'use client' import { useState } from 'react' import Link from 'next/link' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Badge } from '@/components/ui/badge' import { Button } from '@/components/ui/button' import { useToast } from '@/components/ui/use-toast' import { Deadline, DeadlineStatus, TAX_DEADLINE_TYPE_LABELS, DEADLINE_STATUS_LABELS } from '@/types' import { getReportUrl } from '@/lib/tax/deadline-config' import { STATUS_COLORS } from '@/lib/calendar/utils' // Use the labels from types const STATUS_LABELS = DEADLINE_STATUS_LABELS import { FileText, ChevronRight, AlertTriangle, Clock, Send, Check, Loader2, ExternalLink, } from 'lucide-react' interface TaxTodoWidgetProps { deadlines: Deadline[] onStatusChange?: (deadlineId: string, newStatus: DeadlineStatus) => void } export function TaxTodoWidget({ deadlines, onStatusChange }: TaxTodoWidgetProps) { const { toast } = useToast() const [updatingId, setUpdatingId] = useState(null) // Filter to only tax deadlines needing attention const taxDeadlines = deadlines.filter( (d) => d.deadline_type === 'tax' && !d.is_completed && ['action_needed', 'overdue', 'in_progress'].includes(d.status) ) // Sort by urgency: overdue first, then by date const sortedDeadlines = taxDeadlines.sort((a, b) => { if (a.status === 'overdue' && b.status !== 'overdue') return -1 if (b.status === 'overdue' && a.status !== 'overdue') return 1 return a.due_date.localeCompare(b.due_date) }) const overdueCount = taxDeadlines.filter((d) => d.status === 'overdue').length const actionNeededCount = taxDeadlines.filter((d) => d.status === 'action_needed').length if (sortedDeadlines.length === 0) { return null } const formatDate = (dateStr: string) => { const date = new Date(dateStr) const today = new Date() today.setHours(0, 0, 0, 0) const diffDays = Math.ceil( (date.getTime() - today.getTime()) / (1000 * 60 * 60 * 24) ) if (diffDays === 0) return 'Idag' if (diffDays === 1) return 'Imorgon' if (diffDays < 0) return `${Math.abs(diffDays)} dagar sedan` if (diffDays <= 7) return `Om ${diffDays} dagar` return date.toLocaleDateString('sv-SE', { day: 'numeric', month: 'short' }) } const handleStatusChange = async (deadlineId: string, newStatus: DeadlineStatus) => { setUpdatingId(deadlineId) try { const response = await fetch(`/api/deadlines/${deadlineId}/status`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ status: newStatus }), }) if (!response.ok) { const data = await response.json() throw new Error(data.error || 'Failed to update status') } toast({ title: 'Status uppdaterad', description: `Markerad som ${STATUS_LABELS[newStatus].toLowerCase()}`, }) onStatusChange?.(deadlineId, newStatus) } catch (error) { toast({ title: 'Fel', description: error instanceof Error ? error.message : 'Kunde inte uppdatera status', variant: 'destructive', }) } finally { setUpdatingId(null) } } const getReportLink = (deadline: Deadline): string | null => { if (!deadline.linked_report_type || !deadline.linked_report_period) { return null } return getReportUrl(deadline.linked_report_type, deadline.linked_report_period) } return (
Att göra - Skatt
{overdueCount > 0 && ( {overdueCount} försenad )} {actionNeededCount > 0 && ( {actionNeededCount} snart )}
{sortedDeadlines.slice(0, 5).map((deadline) => { const isUpdating = updatingId === deadline.id const reportLink = getReportLink(deadline) const isOverdue = deadline.status === 'overdue' const isActionNeeded = deadline.status === 'action_needed' return (
{isOverdue ? ( ) : ( )}

{deadline.title}

{formatDate(deadline.due_date)} {deadline.tax_deadline_type && ( {TAX_DEADLINE_TYPE_LABELS[deadline.tax_deadline_type]} )}
{/* Link to report if available */} {reportLink && ( )} {/* Mark as in progress */} {['action_needed', 'overdue'].includes(deadline.status) && ( )} {/* Mark as submitted */} {deadline.status === 'in_progress' && ( )}
) })} {sortedDeadlines.length > 5 && (

+{sortedDeadlines.length - 5} fler uppgifter

)}
) }