"use client";
import React, { useState } from 'react';
import {
Calendar, ChevronLeft, ChevronRight, Plus, Settings,
Clock, Users, MapPin, Repeat,
Edit3, Trash2, Copy, Forward, Reply, MoreHorizontal,
Filter, RefreshCw, Share2,
User, AlertCircle,
CheckCircle2, X, Eye, EyeOff, Flag,
PrinterIcon} from 'lucide-react';
import { cn } from "@/lib/utils";
import Footer from '../footer';
// Sample calendar data
const sampleEvents = [
{
id: 1,
title: "Team Standup",
start: "2025-06-28T09:00:00",
end: "2025-06-28T09:30:00",
type: "meeting",
location: "Conference Room A",
attendees: ["john@company.com", "jane@company.com", "mike@company.com"],
description: "Daily team synchronization meeting",
priority: "high",
status: "accepted",
organizer: "sarah@company.com",
category: "work",
recurring: true
},
{
id: 2,
title: "Client Presentation",
start: "2025-06-28T14:00:00",
end: "2025-06-28T15:30:00",
type: "meeting",
location: "Board Room",
attendees: ["client@external.com", "manager@company.com"],
description: "Q2 results presentation to key client",
priority: "high",
status: "tentative",
organizer: "me@company.com",
category: "important",
recurring: false
},
{
id: 3,
title: "Lunch with Marketing Team",
start: "2025-06-28T12:00:00",
end: "2025-06-28T13:00:00",
type: "personal",
location: "Downtown Cafe",
attendees: ["marketing@company.com"],
description: "Monthly team lunch",
priority: "normal",
status: "accepted",
organizer: "marketing@company.com",
category: "social",
recurring: true
},
{
id: 4,
title: "Project Review",
start: "2025-06-29T10:00:00",
end: "2025-06-29T11:00:00",
type: "meeting",
location: "Online",
attendees: ["team@company.com"],
description: "Weekly project status review",
priority: "normal",
status: "accepted",
organizer: "me@company.com",
category: "work",
recurring: true
},
{
id: 5,
title: "Doctor Appointment",
start: "2025-06-30T15:00:00",
end: "2025-06-30T16:00:00",
type: "personal",
location: "Medical Center",
attendees: [],
description: "Annual checkup",
priority: "normal",
status: "accepted",
organizer: "me@company.com",
category: "personal",
recurring: false
}
];
const categoriesData = [
{ name: "Work", color: "blue", visible: true, count: 12 },
{ name: "Personal", color: "green", visible: true, count: 5 },
{ name: "Important", color: "red", visible: true, count: 3 },
{ name: "Social", color: "purple", visible: true, count: 8 },
{ name: "Travel", color: "orange", visible: false, count: 2 },
{ name: "Family", color: "pink", visible: true, count: 4 }
];
// Date utilities
const formatDate = (date) => {
return new Intl.DateTimeFormat('en-US', {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric'
}).format(date);
};
const formatTime = (dateString) => {
return new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: '2-digit',
hour12: true
}).format(new Date(dateString));
};
const formatDateShort = (date) => {
return new Intl.DateTimeFormat('en-US', {
month: 'short',
day: 'numeric'
}).format(date);
};
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
DropdownMenuSeparator,
} from "@/components/ui/dropdown-menu";
import {
ContextMenu,
ContextMenuContent,
ContextMenuItem,
ContextMenuTrigger,
ContextMenuSeparator,
} from "@/components/ui/context-menu";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { ScrollArea } from "@/components/ui/scroll-area";
const CalendarSidebar = ({ isCollapsed, categories, onCategoryToggle, onDateSelect }) => {
const [selectedCategories, setSelectedCategories] = useState(
categories.filter(cat => cat.visible).map(cat => cat.name)
);
const toggleCategory = (categoryName) => {
const newSelected = selectedCategories.includes(categoryName)
? selectedCategories.filter(name => name !== categoryName)
: [...selectedCategories, categoryName];
setSelectedCategories(newSelected);
onCategoryToggle(categoryName);
};
const generateCalendarDays = () => {
const today = new Date();
const currentMonth = today.getMonth();
const currentYear = today.getFullYear();
const firstDay = new Date(currentYear, currentMonth, 1);
const startDate = new Date(firstDay);
startDate.setDate(startDate.getDate() - firstDay.getDay());
const days = [];
for (let i = 0; i < 42; i++) {
const date = new Date(startDate);
date.setDate(startDate.getDate() + i);
days.push(date);
}
return days;
};
const calendarDays = generateCalendarDays();
const today = new Date();
const quickActions = [
{ icon: Plus, label: "New Event", action: "new-event" },
{ icon: Users, label: "New Meeting", action: "new-meeting" },
];
if (isCollapsed) {
return (
{quickActions.map((action, index) => (
{action.label}
))}
);
}
return (
{/* Quick Actions */}
Quick Actions
{quickActions.map((action, index) => (
))}
{/* Mini Calendar */}
{today.toLocaleDateString('en-US', { month: 'long', year: 'numeric' })}
{['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'].map(day => (
{day}
))}
{calendarDays.map((date, index) => {
const isToday = date.toDateString() === today.toDateString();
const isCurrentMonth = date.getMonth() === today.getMonth();
return (
);
})}
{/* Categories */}
My Calendars
{categories.map((category) => (
({category.count})
))}
);
};
const EventCard = ({ event, onAction }) => {
const getCategoryColor = (category) => {
const colors = {
work: "bg-blue-500/20 border-l-blue-500 text-foreground",
personal: "bg-green-500/20 border-l-green-500 text-foreground",
important: "bg-red-500/20 border-l-red-500 text-foreground",
social: "bg-purple-500/20 border-l-purple-500 text-foreground"
};
return colors[category] || "bg-secondary border-l-muted text-foreground";
};
const getPriorityIcon = (priority) => {
if (priority === 'high') return ;
return null;
};
const getStatusIcon = (status) => {
switch (status) {
case 'accepted': return ;
case 'tentative': return ;
case 'declined': return ;
default: return null;
}
};
return (
{getPriorityIcon(event.priority)}
{event.title}
{event.recurring && }
{getStatusIcon(event.status)}
{formatTime(event.start)} - {formatTime(event.end)}
{event.location && (
{event.location}
)}
{event.attendees.length > 0 && (
{event.attendees.length} attendees
)}
onAction('open', event)} className="hover:bg-primary hover:text-primary-foreground">
Open
onAction('edit', event)} className="hover:bg-primary hover:text-primary-foreground">
Edit
onAction('forward', event)} className="hover:bg-primary hover:text-primary-foreground">
Forward
onAction('copy', event)} className="hover:bg-primary hover:text-primary-foreground">
Copy
onAction('delete', event)} className="text-destructive hover:bg-primary hover:text-primary-foreground">
Delete
);
};
const CalendarView = ({ view, events, currentDate, onEventAction }) => {
const filteredEvents = events.filter(event => {
const eventDate = new Date(event.start);
if (view === 'day') {
return eventDate.toDateString() === currentDate.toDateString();
} else if (view === 'week') {
const weekStart = new Date(currentDate);
weekStart.setDate(currentDate.getDate() - currentDate.getDay());
const weekEnd = new Date(weekStart);
weekEnd.setDate(weekStart.getDate() + 6);
return eventDate >= weekStart && eventDate <= weekEnd;
} else if (view === 'month') {
return eventDate.getMonth() === currentDate.getMonth() &&
eventDate.getFullYear() === currentDate.getFullYear();
}
return true;
});
if (view === 'day') {
const dayEvents = filteredEvents.sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime());
return (
{formatDate(currentDate)}
{dayEvents.length > 0 ? (
dayEvents.map(event => (
))
) : (
No events scheduled for this day
)}
);
}
if (view === 'week') {
const weekStart = new Date(currentDate);
weekStart.setDate(currentDate.getDate() - currentDate.getDay());
const weekDays = Array.from({ length: 7 }, (_, i) => {
const day = new Date(weekStart);
day.setDate(weekStart.getDate() + i);
return day;
});
return (
Week of {formatDateShort(weekStart)} - {formatDateShort(weekDays[6])}
{weekDays.map((day, index) => {
const dayEvents = filteredEvents.filter(event =>
new Date(event.start).toDateString() === day.toDateString()
);
const isToday = day.toDateString() === new Date().toDateString();
return (
{day.toLocaleDateString('en-US', { weekday: 'short' })}
{day.getDate()}
{dayEvents.map(event => (
onEventAction('open', event)}
>
{event.title}
{formatTime(event.start)}
))}
);
})}
);
}
// Month view
const monthStart = new Date(currentDate.getFullYear(), currentDate.getMonth(), 1);
const calendarStart = new Date(monthStart);
calendarStart.setDate(calendarStart.getDate() - monthStart.getDay());
const calendarDays = Array.from({ length: 42 }, (_, i) => {
const day = new Date(calendarStart);
day.setDate(calendarStart.getDate() + i);
return day;
});
return (
{currentDate.toLocaleDateString('en-US', { month: 'long', year: 'numeric' })}
{['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'].map(day => (
{day.substring(0, 3)}
))}
{calendarDays.map((day, index) => {
const dayEvents = filteredEvents.filter(event =>
new Date(event.start).toDateString() === day.toDateString()
);
const isToday = day.toDateString() === new Date().toDateString();
const isCurrentMonth = day.getMonth() === currentDate.getMonth();
return (
{day.getDate()}
{dayEvents.slice(0, 3).map(event => (
onEventAction('open', event)}
>
{event.title}
))}
{dayEvents.length > 3 && (
+{dayEvents.length - 3} more
)}
);
})}
);
};
const EventDetails = ({ event }) => {
if (!event) {
return (
No event selected
Select an event to view details
);
}
return (
{/* Header */}
{event.title}
Edit
Forward
Reply
Delete
{event.category}
{/* Content */}
{/* Time */}
{formatTime(event.start)} - {formatTime(event.end)}
{new Date(event.start).toLocaleDateString('en-US', {
weekday: 'long',
month: 'long',
day: 'numeric',
year: 'numeric'
})}
{/* Location */}
{event.location && (
{event.location}
)}
{/* Organizer */}
Organizer
{event.organizer}
{/* Attendees */}
{event.attendees.length > 0 && (
Attendees ({event.attendees.length})
{event.attendees.map((attendee, index) => (
))}
)}
{/* Description */}
{event.description && (
Description
{event.description}
)}
{/* Properties */}
Priority
{event.priority}
Status
{event.status}
Recurring
{event.recurring ? 'Yes' : 'No'}
{/* Footer */}
);
};
const CalendarPage = () => {
const [currentDate, setCurrentDate] = useState(new Date());
const [selectedEvent, setSelectedEvent] = useState(null);
const [categories, setCategories] = useState(categoriesData);
const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
const handleEventAction = (action, event) => {
switch (action) {
case 'open':
setSelectedEvent(event);
break;
case 'edit':
// Handle edit
break;
case 'delete':
// Handle delete
break;
default:
break;
}
};
const handleCategoryToggle = (categoryName) => {
setCategories(categories.map(cat =>
cat.name === categoryName ? { ...cat, visible: !cat.visible } : cat
));
};
const handleDateSelect = (date) => {
setCurrentDate(date);
};
const shortcuts = [
// Calendar actions row (unique qkeys)
[
{ key: 'Q', label: 'New Event', action: () => console.log('New Event') },
{ key: 'W', label: 'New Meeting', action: () => console.log('New Meeting') },
{ key: 'E', label: 'Edit Event', action: () => console.log('Edit Event') },
{ key: 'R', label: 'Refresh', action: () => console.log('Refresh') },
{ key: 'T', label: 'Today', action: () => setCurrentDate(new Date()) },
{ key: 'Y', label: 'Delete Event', action: () => console.log('Delete Event') },
{ key: 'U', label: 'Duplicate', action: () => console.log('Duplicate Event') },
{ key: 'I', label: 'Invite', action: () => console.log('Invite Attendees') },
{ key: 'O', label: 'Open Event', action: () => console.log('Open Event') },
{ key: 'P', label: 'Print', action: () => console.log('Print Calendar') },
],
// Navigation/info row (unique qkeys)
[
{ key: 'A', label: 'Accept', action: () => console.log('Accept Invitation') },
{ key: 'S', label: 'Send', action: () => console.log('Send Invitation') },
{ key: 'D', label: 'Decline', action: () => console.log('Decline Invitation') },
{ key: 'G', label: 'Go to Date', action: () => console.log('Go to Date') },
{ key: 'H', label: 'Help', action: () => console.log('Help') },
{ key: 'J', label: 'Share', action: () => console.log('Share Calendar') },
{ key: 'K', label: 'Show/Hide Weekends', action: () => console.log('Toggle Weekends') },
{ key: 'L', label: 'List View', action: () => console.log('List View') },
{ key: 'Z', label: 'Month View', action: () => console.log('Month View') },
{ key: 'X', label: 'Week View', action: () => console.log('Week View') },
]
];
return (
{/* Sidebar */}
{/* Main Content */}
{/* Toolbar */}
{formatDate(currentDate)}
Refresh
Filters
Print
Share
{/* Calendar Area */}
{/* Three calendar views on the left */}
{/* Event details on the right */}
);
};
export default CalendarPage;