- Add Sora + DM Sans Google Fonts with heading/body font system - New CSS variables for elevated surfaces, transitions, custom scrollbars - Tailwind config: fade-in/slide-up animations, card-elevated color, font families - Card component: hover glow, accent border on hover, smooth transitions - New WeekTimeline component: 7-day horizontal strip with event dot indicators - Dashboard: contextual time-of-day greeting, week timeline, redesigned 5-col layout - Stats widget: accent-tinted gradients, icon glow backgrounds, uppercase labels - Upcoming widget: colored left-border type indicators, unified timeline feed - Calendar/Todo widgets: refined spacing, hover states, colored accent bars - Sidebar: accent bar active state (border-l-2), backdrop-blur mobile overlay Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
65 lines
2.2 KiB
TypeScript
65 lines
2.2 KiB
TypeScript
import { format } from 'date-fns';
|
||
import { Calendar, Clock } from 'lucide-react';
|
||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||
|
||
interface DashboardEvent {
|
||
id: number;
|
||
title: string;
|
||
start_datetime: string;
|
||
end_datetime: string;
|
||
all_day: boolean;
|
||
color?: string;
|
||
}
|
||
|
||
interface CalendarWidgetProps {
|
||
events: DashboardEvent[];
|
||
}
|
||
|
||
export default function CalendarWidget({ events }: CalendarWidgetProps) {
|
||
return (
|
||
<Card>
|
||
<CardHeader>
|
||
<CardTitle className="flex items-center gap-2">
|
||
<div className="p-1.5 rounded-md bg-purple-500/10">
|
||
<Calendar className="h-4 w-4 text-purple-400" />
|
||
</div>
|
||
Today's Events
|
||
</CardTitle>
|
||
</CardHeader>
|
||
<CardContent>
|
||
{events.length === 0 ? (
|
||
<p className="text-sm text-muted-foreground text-center py-6">
|
||
No events today
|
||
</p>
|
||
) : (
|
||
<div className="space-y-2">
|
||
{events.map((event) => (
|
||
<div
|
||
key={event.id}
|
||
className="flex items-start gap-3 p-3 rounded-lg border border-transparent hover:border-border/50 hover:bg-card-elevated transition-all duration-200"
|
||
>
|
||
<div
|
||
className="w-1 h-full min-h-[2rem] rounded-full shrink-0"
|
||
style={{ backgroundColor: event.color || 'hsl(var(--primary))' }}
|
||
/>
|
||
<div className="flex-1 min-w-0">
|
||
<p className="font-medium text-sm">{event.title}</p>
|
||
{!event.all_day ? (
|
||
<div className="flex items-center gap-1 text-xs text-muted-foreground mt-1">
|
||
<Clock className="h-3 w-3" />
|
||
{format(new Date(event.start_datetime), 'h:mm a')}
|
||
{event.end_datetime && ` – ${format(new Date(event.end_datetime), 'h:mm a')}`}
|
||
</div>
|
||
) : (
|
||
<p className="text-xs text-muted-foreground mt-1">All day</p>
|
||
)}
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
)}
|
||
</CardContent>
|
||
</Card>
|
||
);
|
||
}
|