mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-21 23:11:12 -05:00
Refactor code structure and remove redundant changes
This commit is contained in:
164
src-old/components/moderation/EnhancedLockStatusDisplay.tsx
Normal file
164
src-old/components/moderation/EnhancedLockStatusDisplay.tsx
Normal file
@@ -0,0 +1,164 @@
|
||||
import { useState, useEffect, useMemo } from 'react';
|
||||
import { Clock, AlertTriangle } from 'lucide-react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Progress } from '@/components/ui/progress';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
interface LockState {
|
||||
submissionId: string;
|
||||
expiresAt: Date;
|
||||
}
|
||||
|
||||
interface QueueStats {
|
||||
pendingCount: number;
|
||||
assignedToMe: number;
|
||||
avgWaitHours: number;
|
||||
}
|
||||
|
||||
interface EnhancedLockStatusDisplayProps {
|
||||
currentLock: LockState | null;
|
||||
queueStats: QueueStats | null;
|
||||
loading: boolean;
|
||||
onExtendLock: () => void;
|
||||
onReleaseLock: () => void;
|
||||
getCurrentTime: () => Date;
|
||||
}
|
||||
|
||||
const LOCK_DURATION_MS = 15 * 60 * 1000; // 15 minutes
|
||||
const WARNING_THRESHOLD_MS = 5 * 60 * 1000; // 5 minutes
|
||||
const CRITICAL_THRESHOLD_MS = 2 * 60 * 1000; // 2 minutes
|
||||
|
||||
export const EnhancedLockStatusDisplay = ({
|
||||
currentLock,
|
||||
queueStats,
|
||||
loading,
|
||||
onExtendLock,
|
||||
onReleaseLock,
|
||||
getCurrentTime,
|
||||
}: EnhancedLockStatusDisplayProps) => {
|
||||
const [timeLeft, setTimeLeft] = useState<number>(0);
|
||||
|
||||
useEffect(() => {
|
||||
if (!currentLock) return;
|
||||
|
||||
const updateTimer = () => {
|
||||
const now = getCurrentTime();
|
||||
const remaining = currentLock.expiresAt.getTime() - now.getTime();
|
||||
setTimeLeft(Math.max(0, remaining));
|
||||
};
|
||||
|
||||
updateTimer();
|
||||
const interval = setInterval(updateTimer, 1000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [currentLock, getCurrentTime]);
|
||||
|
||||
const { urgency, progressPercent } = useMemo(() => {
|
||||
if (timeLeft <= 0) return { urgency: 'expired', progressPercent: 0 };
|
||||
if (timeLeft <= CRITICAL_THRESHOLD_MS) return { urgency: 'critical', progressPercent: (timeLeft / LOCK_DURATION_MS) * 100 };
|
||||
if (timeLeft <= WARNING_THRESHOLD_MS) return { urgency: 'warning', progressPercent: (timeLeft / LOCK_DURATION_MS) * 100 };
|
||||
return { urgency: 'safe', progressPercent: (timeLeft / LOCK_DURATION_MS) * 100 };
|
||||
}, [timeLeft]);
|
||||
|
||||
const formatTime = (ms: number): string => {
|
||||
const totalSeconds = Math.floor(ms / 1000);
|
||||
const minutes = Math.floor(totalSeconds / 60);
|
||||
const seconds = totalSeconds % 60;
|
||||
return `${minutes}:${seconds.toString().padStart(2, '0')}`;
|
||||
};
|
||||
|
||||
const showExtendButton = timeLeft > 0 && timeLeft <= WARNING_THRESHOLD_MS;
|
||||
|
||||
if (!currentLock) {
|
||||
return (
|
||||
<div className="flex items-center justify-between p-4 bg-muted/30 rounded-lg">
|
||||
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||
<Clock className="w-4 h-4" />
|
||||
<span>No submission claimed</span>
|
||||
</div>
|
||||
{queueStats && (
|
||||
<div className="text-sm text-muted-foreground">
|
||||
{queueStats.pendingCount} pending
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'p-4 rounded-lg border transition-colors',
|
||||
urgency === 'critical' && 'bg-destructive/10 border-destructive animate-pulse',
|
||||
urgency === 'warning' && 'bg-yellow-500/10 border-yellow-500',
|
||||
urgency === 'safe' && 'bg-primary/10 border-primary'
|
||||
)}
|
||||
data-testid="lock-status-display"
|
||||
>
|
||||
<div className="flex items-center justify-between mb-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<Clock className={cn(
|
||||
'w-4 h-4',
|
||||
urgency === 'critical' && 'text-destructive',
|
||||
urgency === 'warning' && 'text-yellow-600',
|
||||
urgency === 'safe' && 'text-primary'
|
||||
)} />
|
||||
<span className="text-sm font-medium">Lock expires in</span>
|
||||
</div>
|
||||
<Badge
|
||||
variant={urgency === 'critical' ? 'destructive' : urgency === 'warning' ? 'default' : 'secondary'}
|
||||
className={cn(
|
||||
'font-mono text-base',
|
||||
urgency === 'critical' && 'animate-pulse'
|
||||
)}
|
||||
>
|
||||
{formatTime(timeLeft)}
|
||||
</Badge>
|
||||
</div>
|
||||
|
||||
<Progress
|
||||
value={progressPercent}
|
||||
className={cn(
|
||||
'h-2 mb-3',
|
||||
urgency === 'critical' && '[&>div]:bg-destructive',
|
||||
urgency === 'warning' && '[&>div]:bg-yellow-500',
|
||||
urgency === 'safe' && '[&>div]:bg-primary'
|
||||
)}
|
||||
/>
|
||||
|
||||
{urgency === 'critical' && (
|
||||
<div className="flex items-start gap-2 mb-3 text-sm text-destructive">
|
||||
<AlertTriangle className="w-4 h-4 mt-0.5 flex-shrink-0" />
|
||||
<span className="font-medium">Lock expiring soon! Extend or release.</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="flex gap-2">
|
||||
{showExtendButton && (
|
||||
<Button
|
||||
onClick={onExtendLock}
|
||||
disabled={loading}
|
||||
size="sm"
|
||||
variant={urgency === 'critical' ? 'default' : 'outline'}
|
||||
className="flex-1"
|
||||
>
|
||||
<Clock className="w-4 h-4 mr-2" />
|
||||
Extend Lock (+15min)
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
onClick={onReleaseLock}
|
||||
disabled={loading}
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className={!showExtendButton ? 'flex-1' : ''}
|
||||
>
|
||||
Release Lock
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
EnhancedLockStatusDisplay.displayName = 'EnhancedLockStatusDisplay';
|
||||
Reference in New Issue
Block a user