import React, { useState, useEffect } from "react"; import { ContentCalendar, CalendarEntry, ReviewPriority, } from "../types/review"; interface ContentCalendarProps { siteId: string; className?: string; } interface CalendarView { month: number; year: number; selectedDate: Date | null; } export const ContentCalendarComponent: React.FC = ({ siteId, className = "", }) => { const [calendar, setCalendar] = useState(null); const [view, setView] = useState({ month: new Date().getMonth(), year: new Date().getFullYear(), selectedDate: null, }); const [isLoading, setIsLoading] = useState(true); const [showEventModal, setShowEventModal] = useState(false); const mockCalendar: ContentCalendar = { id: "calendar-main", name: "Main Content Calendar", description: "Primary calendar for content review scheduling", siteId, entries: [ { id: "entry-1", title: "Hero Section Review", description: "Quarterly review of hero section content", type: "review", startDate: new Date(2024, 2, 15), allDay: true, recurring: false, assignedTo: ["content-manager", "marketing-lead"], createdBy: "admin", status: "scheduled", priority: "medium", tags: ["hero", "quarterly"], estimatedHours: 2, createdAt: new Date(), updatedAt: new Date(), }, { id: "entry-2", title: "Pricing Update Publication", description: "Publish approved pricing changes", type: "publication", startDate: new Date(2024, 2, 20), allDay: false, recurring: false, assignedTo: ["content-manager"], createdBy: "admin", status: "scheduled", priority: "high", tags: ["pricing", "publication"], estimatedHours: 1, createdAt: new Date(), updatedAt: new Date(), }, { id: "entry-3", title: "Content Audit", description: "Monthly content audit and cleanup", type: "audit", startDate: new Date(2024, 2, 25), allDay: true, recurring: true, recurrenceRule: "FREQ=MONTHLY;BYMONTHDAY=25", assignedTo: ["content-manager", "seo-specialist"], createdBy: "admin", status: "scheduled", priority: "medium", tags: ["audit", "monthly"], estimatedHours: 4, createdAt: new Date(), updatedAt: new Date(), }, ], timezone: "UTC", workingDays: [1, 2, 3, 4, 5], // Monday to Friday workingHours: { start: "09:00", end: "17:00", }, createdBy: "admin", createdAt: new Date(), updatedAt: new Date(), }; useEffect(() => { const loadCalendar = async () => { setIsLoading(true); // Simulate API call await new Promise((resolve) => setTimeout(resolve, 1000)); setCalendar(mockCalendar); setIsLoading(false); }; loadCalendar(); }, [siteId]); const getDaysInMonth = (month: number, year: number) => { return new Date(year, month + 1, 0).getDate(); }; const getFirstDayOfMonth = (month: number, year: number) => { return new Date(year, month, 1).getDay(); }; const getEventsForDate = (date: Date): CalendarEntry[] => { if (!calendar) return []; return calendar.entries.filter((entry) => { const entryDate = new Date(entry.startDate); return ( entryDate.getDate() === date.getDate() && entryDate.getMonth() === date.getMonth() && entryDate.getFullYear() === date.getFullYear() ); }); }; const getPriorityColor = (priority: ReviewPriority) => { switch (priority) { case "urgent": return "bg-red-500"; case "high": return "bg-orange-500"; case "medium": return "bg-yellow-500"; case "low": return "bg-green-500"; default: return "bg-gray-500"; } }; const getTypeIcon = (type: string) => { switch (type) { case "review": return "📝"; case "publication": return "🚀"; case "expiration": return "⏰"; case "audit": return "🔍"; case "campaign": return "📢"; default: return "📅"; } }; const navigateMonth = (direction: "prev" | "next") => { setView((prev) => { const newMonth = direction === "prev" ? prev.month - 1 : prev.month + 1; const newYear = newMonth < 0 ? prev.year - 1 : newMonth > 11 ? prev.year + 1 : prev.year; const adjustedMonth = newMonth < 0 ? 11 : newMonth > 11 ? 0 : newMonth; return { ...prev, month: adjustedMonth, year: newYear, }; }); }; const renderCalendarGrid = () => { const daysInMonth = getDaysInMonth(view.month, view.year); const firstDay = getFirstDayOfMonth(view.month, view.year); const days = []; const monthNames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ]; // Add empty cells for days before the first day of the month for (let i = 0; i < firstDay; i++) { days.push(
); } // Add cells for each day of the month for (let day = 1; day <= daysInMonth; day++) { const date = new Date(view.year, view.month, day); const events = getEventsForDate(date); const isToday = new Date().toDateString() === date.toDateString(); const isSelected = view.selectedDate?.toDateString() === date.toDateString(); days.push(
setView((prev) => ({ ...prev, selectedDate: date }))} >
{day} {events.length > 0 && ( {events.length} )}
{events.slice(0, 2).map((event) => (
{getTypeIcon(event.type)} {event.title}
))} {events.length > 2 && (
+{events.length - 2} more
)}
); } return (

{monthNames[view.month]} {view.year}

{["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"].map((day) => (
{day}
))} {days}
); }; const renderSelectedDateEvents = () => { if (!view.selectedDate) return null; const events = getEventsForDate(view.selectedDate); const dateStr = view.selectedDate.toLocaleDateString(); return (

Events for {dateStr}

{events.length === 0 ? (

No events scheduled for this date

) : (
{events.map((event) => (
{getTypeIcon(event.type)}

{event.title}

{event.description}

Type: {event.type} Priority: {event.priority} Estimated: {event.estimatedHours}h Assigned: {event.assignedTo.length} people
{event.tags.length > 0 && (
{event.tags.map((tag) => ( {tag} ))}
)}
))}
)}
); }; if (isLoading) { return (
Loading calendar...
); } return (
{/* Calendar Header */}

Content Calendar

Schedule and track content review activities

{/* Calendar Stats */}
📝

Reviews

{calendar?.entries.filter((e) => e.type === "review") .length || 0}

🚀

Publications

{calendar?.entries.filter((e) => e.type === "publication") .length || 0}

🔍

Audits

{calendar?.entries.filter((e) => e.type === "audit").length || 0}

📢

Campaigns

{calendar?.entries.filter((e) => e.type === "campaign") .length || 0}

{/* Calendar Grid */}
{renderCalendarGrid()}
{/* Event Details Sidebar */}
{renderSelectedDateEvents()} {/* Upcoming Events */}

Upcoming Events

{calendar?.entries .filter((entry) => new Date(entry.startDate) > new Date()) .sort( (a, b) => new Date(a.startDate).getTime() - new Date(b.startDate).getTime() ) .slice(0, 5) .map((event) => (
{getTypeIcon(event.type)}

{event.title}

{new Date(event.startDate).toLocaleDateString()}

))}
{/* Event Modal Placeholder */} {showEventModal && (

Add New Event

Event creation form will be implemented in future iterations.

)}
); }; export default ContentCalendarComponent;