"use client"; import { useState, useEffect } from "react"; import Link from "next/link"; import { Card, CardHeader, CardContent } from "./Card"; import Badge from "./Badge"; import Button from "./Button"; import { formatDate } from "@/lib/utils"; import { format, startOfMonth, endOfMonth, startOfWeek, endOfWeek, addDays, isSameMonth, isSameDay, addMonths, subMonths, parseISO, isAfter, isBefore, startOfDay, addWeeks } from "date-fns"; import { pl } from "date-fns/locale"; const statusColors = { registered: "bg-blue-100 text-blue-800", approved: "bg-green-100 text-green-800", pending: "bg-yellow-100 text-yellow-800", in_progress: "bg-orange-100 text-orange-800", fulfilled: "bg-gray-100 text-gray-800", cancelled: "bg-red-100 text-red-800", }; const statusTranslations = { registered: "Zarejestrowany", approved: "Zatwierdzony", pending: "Oczekujący", in_progress: "W trakcie", fulfilled: "Zakończony", cancelled: "Wycofany", }; export default function ProjectCalendarWidget({ projects = [], compact = false, showUpcoming = true, maxUpcoming = 5 }) { const [currentDate, setCurrentDate] = useState(new Date()); const [viewMode, setViewMode] = useState(compact ? 'upcoming' : 'mini-calendar'); // Filter projects that have finish dates and are not fulfilled const activeProjects = projects.filter(p => p.finish_date && p.project_status !== 'fulfilled' ); const getProjectsForDate = (date) => { return activeProjects.filter(project => { if (!project.finish_date) return false; try { const projectDate = parseISO(project.finish_date); return isSameDay(projectDate, date); } catch (error) { return false; } }); }; const getUpcomingProjects = () => { const today = startOfDay(new Date()); const nextMonth = addWeeks(today, 4); return activeProjects .filter(project => { if (!project.finish_date) return false; try { const projectDate = parseISO(project.finish_date); return isAfter(projectDate, today) && isBefore(projectDate, nextMonth); } catch (error) { return false; } }) .sort((a, b) => { const dateA = parseISO(a.finish_date); const dateB = parseISO(b.finish_date); return dateA - dateB; }) .slice(0, maxUpcoming); }; const getOverdueProjects = () => { const today = startOfDay(new Date()); return activeProjects .filter(project => { if (!project.finish_date) return false; try { const projectDate = parseISO(project.finish_date); return isBefore(projectDate, today); } catch (error) { return false; } }) .sort((a, b) => { const dateA = parseISO(a.finish_date); const dateB = parseISO(b.finish_date); return dateB - dateA; // Most recently overdue first }) .slice(0, maxUpcoming); }; const renderMiniCalendar = () => { const monthStart = startOfMonth(currentDate); const monthEnd = endOfMonth(currentDate); const calendarStart = startOfWeek(monthStart, { weekStartsOn: 1 }); const calendarEnd = endOfWeek(monthEnd, { weekStartsOn: 1 }); const days = []; let day = calendarStart; while (day <= calendarEnd) { days.push(day); day = addDays(day, 1); } const weekdays = ['P', 'W', 'Ś', 'C', 'P', 'S', 'N']; return (