'use client' import { useState, useRef, useEffect } from 'react' import { Deadline } from '@/types' import { Button } from '@/components/ui/button' import { cn } from '@/lib/utils' import { isDeadlineOverdue, DEADLINE_TYPE_LABELS, parseDate, startOfDay, } from '@/lib/calendar/utils' import { Check, Pencil } from 'lucide-react' interface DeadlineCardProps { deadline: Deadline onToggle: (deadline: Deadline) => void onEdit?: (deadline: Deadline) => void onDelete?: (deadline: Deadline) => void compact?: boolean } function getRelativeDate(dateStr: string): { text: string; urgent: boolean } | null { const today = startOfDay(new Date()) const target = parseDate(dateStr) const diffMs = target.getTime() - today.getTime() const diffDays = Math.round(diffMs / (1000 * 60 * 60 * 24)) if (diffDays === 0) return { text: 'Idag', urgent: true } if (diffDays === 1) return { text: 'Imorgon', urgent: false } if (diffDays === -1) return { text: '1 dag sedan', urgent: true } if (diffDays < -1) return { text: `${Math.abs(diffDays)} dagar sedan`, urgent: true } if (diffDays <= 7) return { text: `Om ${diffDays} dagar`, urgent: false } if (diffDays <= 14) return { text: `Om ${diffDays} dagar`, urgent: false } return null } const SWEDISH_MONTHS_SHORT = [ 'jan', 'feb', 'mar', 'apr', 'maj', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec', ] export function DeadlineCard({ deadline, onToggle, onEdit, onDelete, compact = false, }: DeadlineCardProps) { const [confirming, setConfirming] = useState(false) const confirmRef = useRef(null) const overdue = isDeadlineOverdue(deadline) const completed = deadline.is_completed const relative = getRelativeDate(deadline.due_date) const dueDate = parseDate(deadline.due_date) const dayNum = dueDate.getDate() const monthStr = SWEDISH_MONTHS_SHORT[dueDate.getMonth()] // Dismiss confirmation when clicking outside useEffect(() => { if (!confirming) return function handleClickOutside(e: MouseEvent) { if (confirmRef.current && !confirmRef.current.contains(e.target as Node)) { setConfirming(false) } } document.addEventListener('mousedown', handleClickOutside) return () => document.removeEventListener('mousedown', handleClickOutside) }, [confirming]) function handleToggleClick(e: React.MouseEvent) { e.stopPropagation() if (completed) { // Uncompleting doesn't need confirmation onToggle(deadline) return } setConfirming(true) } function handleConfirm(e: React.MouseEvent) { e.stopPropagation() setConfirming(false) onToggle(deadline) } function handleCancel(e: React.MouseEvent) { e.stopPropagation() setConfirming(false) } function handleCardClick() { if (confirming) return if (onEdit) onEdit(deadline) } // -- Compact variant (used in dashboard widgets) -- if (compact) { return (
{dayNum} {monthStr}

{deadline.title}

{!completed && relative && ( {relative.text} )} {completed && ( )}
) } // -- Full card -- return (
{/* Main row */}
{/* Date block */}
{dayNum} {monthStr}
{/* Divider */}
{/* Content */}

{deadline.title}

{deadline.deadline_type !== 'other' && ( {DEADLINE_TYPE_LABELS[deadline.deadline_type]} )}
{deadline.due_time && ( kl {deadline.due_time.slice(0, 5)} )} {deadline.due_time && deadline.customer && ( · )} {deadline.customer && ( {deadline.customer.name} )}
{/* Right: relative date + action */}
{!completed && relative && ( )} {completed ? ( Klar ) : ( )} {/* Edit hint */} {onEdit && !confirming && ( )}
{/* Inline confirmation bar */}

Markera {deadline.title} som klar?

) }