Files
sleepy/lib/sleep.ts

59 lines
1.7 KiB
TypeScript

export type AlarmType = 'alarm' | 'natural' | 'awakened';
export interface SleepEntry {
date: string;
napped: boolean;
napStart: string | null;
napDurationMinutes: number | null;
bedtime: string;
sleepLatencyMinutes: number;
awakenings: number;
wasoMinutes: number;
riseTime: string;
alarmType: AlarmType;
rating: number;
notes: string;
createdAt?: string;
updatedAt?: string;
}
export interface SleepMetrics {
timeInBedMinutes: number;
totalSleepMinutes: number;
efficiency: number;
}
export function calculateMetrics(entry: Pick<SleepEntry, 'bedtime' | 'riseTime' | 'sleepLatencyMinutes' | 'wasoMinutes'>): SleepMetrics {
const [bedHours, bedMinutes] = entry.bedtime.split(':').map(Number);
const [riseHours, riseMinutes] = entry.riseTime.split(':').map(Number);
let timeInBedMinutes = riseHours * 60 + riseMinutes - (bedHours * 60 + bedMinutes);
if (timeInBedMinutes <= 0) timeInBedMinutes += 24 * 60;
const totalSleepMinutes = Math.max(0, timeInBedMinutes - entry.sleepLatencyMinutes - entry.wasoMinutes);
const efficiency = timeInBedMinutes === 0 ? 0 : Math.round((totalSleepMinutes / timeInBedMinutes) * 100);
return { timeInBedMinutes, totalSleepMinutes, efficiency };
}
export function formatDuration(minutes: number): string {
const hours = Math.floor(minutes / 60);
const remainder = minutes % 60;
return hours > 0 ? `${hours} ч ${remainder.toString().padStart(2, '0')} мин` : `${remainder} мин`;
}
export const defaultEntry = (date: string): SleepEntry => ({
date,
napped: false,
napStart: null,
napDurationMinutes: null,
bedtime: '23:30',
sleepLatencyMinutes: 20,
awakenings: 0,
wasoMinutes: 0,
riseTime: '07:00',
alarmType: 'natural',
rating: 3,
notes: '',
});