75 lines
1.8 KiB
TypeScript
75 lines
1.8 KiB
TypeScript
import { ClassValue, clsx } from "clsx";
|
|
import { twMerge } from "tailwind-merge";
|
|
import { SetLog } from "@prisma/client";
|
|
|
|
/**
|
|
* Merge classnames using clsx and tailwind-merge
|
|
*/
|
|
export function cn(...inputs: ClassValue[]): string {
|
|
return twMerge(clsx(inputs));
|
|
}
|
|
|
|
/**
|
|
* Format a date to a readable string (e.g., "Feb 16, 2026")
|
|
*/
|
|
export function formatDate(date: Date | string): string {
|
|
const dateObj = typeof date === "string" ? new Date(date) : date;
|
|
return dateObj.toLocaleDateString("en-US", {
|
|
year: "numeric",
|
|
month: "short",
|
|
day: "numeric",
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Format weight with unit (e.g., "150 lbs")
|
|
*/
|
|
export function formatWeight(weight: number, unit: string): string {
|
|
return `${weight} ${unit}`;
|
|
}
|
|
|
|
/**
|
|
* Calculate total volume (sets * reps * weight)
|
|
*/
|
|
export function calculateVolume(sets: SetLog[]): number {
|
|
return sets.reduce((total, set) => {
|
|
const reps = set.reps || 0;
|
|
const weight = set.weight || 0;
|
|
return total + reps * weight;
|
|
}, 0);
|
|
}
|
|
|
|
/**
|
|
* Calculate estimated 1-rep max using Epley formula
|
|
* 1RM = weight * (1 + reps / 30)
|
|
*/
|
|
export function calculateE1RM(weight: number, reps: number): number {
|
|
if (reps === 1) return weight;
|
|
return Math.round(weight * (1 + reps / 30) * 100) / 100;
|
|
}
|
|
|
|
/**
|
|
* Get the start and end of a week for a given date
|
|
*/
|
|
export function getWeekRange(date: Date): { start: Date; end: Date } {
|
|
const d = new Date(date);
|
|
const day = d.getDay();
|
|
const diff = d.getDate() - day + (day === 0 ? -6 : 1); // Adjust to Monday
|
|
|
|
const start = new Date(d.setDate(diff));
|
|
start.setHours(0, 0, 0, 0);
|
|
|
|
const end = new Date(start);
|
|
end.setDate(end.getDate() + 6);
|
|
end.setHours(23, 59, 59, 999);
|
|
|
|
return { start, end };
|
|
}
|
|
|
|
/**
|
|
* Generate a random UUID
|
|
*/
|
|
export function generateId(): string {
|
|
return crypto.randomUUID();
|
|
}
|