/** * Lock Management Utilities * * Helper functions for managing submission locks and lock state. */ /** * Check if a submission can be claimed by the current user */ export function canClaimSubmission( submission: { assigned_to: string | null; locked_until: string | null }, currentUserId: string ): boolean { // Can claim if unassigned if (!submission.assigned_to) return true; // Can claim if no lock time set if (!submission.locked_until) return true; // Can claim if lock expired if (new Date(submission.locked_until) < new Date()) return true; // Already claimed by current user - cannot claim again if (submission.assigned_to === currentUserId) return false; return false; } /** * Check if a submission has an active lock */ export function isActiveLock( assignedTo: string | null, lockedUntil: string | null ): boolean { if (!assignedTo || !lockedUntil) return false; return new Date(lockedUntil) > new Date(); } /** * Get lock status indicator for a submission */ export type LockStatus = 'locked_by_me' | 'locked_by_other' | 'unlocked' | 'expired'; export function getLockStatus( submission: { assigned_to: string | null; locked_until: string | null }, currentUserId: string ): LockStatus { if (!submission.assigned_to || !submission.locked_until) { return 'unlocked'; } const lockExpired = new Date(submission.locked_until) < new Date(); if (lockExpired) { return 'expired'; } if (submission.assigned_to === currentUserId) { return 'locked_by_me'; } return 'locked_by_other'; } /** * Format lock expiry time as MM:SS */ export function formatLockExpiry(lockedUntil: string): string { const expiresAt = new Date(lockedUntil); const now = new Date(); const msLeft = expiresAt.getTime() - now.getTime(); if (msLeft <= 0) return 'Expired'; const minutes = Math.floor(msLeft / 60000); const seconds = Math.floor((msLeft % 60000) / 1000); return `${minutes}:${seconds.toString().padStart(2, '0')}`; } /** * Calculate lock urgency level based on time remaining */ export type LockUrgency = 'critical' | 'warning' | 'normal'; export function getLockUrgency(timeLeftMs: number): LockUrgency { if (timeLeftMs < 2 * 60 * 1000) return 'critical'; // < 2 min if (timeLeftMs < 5 * 60 * 1000) return 'warning'; // < 5 min return 'normal'; }