feat: log staff sign-in and sign-out and force logout at a set time

This commit is contained in:
2026-10-19 13:34:55 +03:30
parent 3863c5e7d1
commit 8590579605
25 changed files with 588 additions and 15 deletions
@@ -0,0 +1,44 @@
const TEHRAN = 'Asia/Tehran';
export type AttendanceKind = 'login' | 'logout' | 'forced_logout';
export function tehranDateKey(date: Date): string {
const parts = new Intl.DateTimeFormat('en-CA', {
timeZone: TEHRAN,
year: 'numeric',
month: '2-digit',
day: '2-digit',
}).format(date);
return parts;
}
/** ساعت HH:mm امروز به وقت تهران، به صورت لحظهٔ مطلق */
export function tehranCutoff(now: Date, hhmm: string): Date | null {
const match = /^([01]\d|2[0-3]):([0-5]\d)$/.exec(hhmm.trim());
if (!match) return null;
const day = tehranDateKey(now);
return new Date(`${day}T${match[1]}:${match[2]}:00+03:30`);
}
export function isPastLogoutTime(now: Date, hhmm: string | null | undefined): boolean {
if (!hhmm) return false;
const cutoff = tehranCutoff(now, hhmm);
if (!cutoff) return false;
return now.getTime() >= cutoff.getTime();
}
export function loggedInAfterCutoff(at: Date, hhmm: string | null | undefined): boolean {
if (!hhmm) return false;
const cutoff = tehranCutoff(at, hhmm);
if (!cutoff) return false;
return at.getTime() >= cutoff.getTime();
}
export function tehranClock(date: Date): string {
return new Intl.DateTimeFormat('fa-IR', {
timeZone: TEHRAN,
hour: '2-digit',
minute: '2-digit',
hourCycle: 'h23',
}).format(date);
}