96 lines
2.7 KiB
TypeScript
96 lines
2.7 KiB
TypeScript
import { Button } from "@/components/ui/button";
|
|
import { Card, CardHeader, CardContent } from "@/components/ui/card";
|
|
import { LucideMapPin, Clock, MoreHorizontal } from "lucide-react";
|
|
import {
|
|
DropdownMenu,
|
|
DropdownMenuContent,
|
|
DropdownMenuTrigger,
|
|
DropdownMenuItem,
|
|
} from "@/components/ui/dropdown-menu";
|
|
import { RRuleDisplay } from "@/components/rrule-display";
|
|
import type { CalendarEvent } from "@/lib/types";
|
|
|
|
interface EventCardProps {
|
|
event: CalendarEvent;
|
|
onEdit: (event: CalendarEvent) => void;
|
|
onDelete: (eventId: string) => void;
|
|
}
|
|
|
|
export const EventCard = ({ event, onEdit, onDelete }: EventCardProps) => {
|
|
const formatDateTime = (dateStr: string, allDay: boolean | undefined) => {
|
|
return allDay
|
|
? new Date(dateStr).toLocaleDateString()
|
|
: new Date(dateStr).toLocaleString();
|
|
};
|
|
|
|
const handleEdit = () => {
|
|
onEdit({
|
|
id: event.id,
|
|
title: event.title,
|
|
description: event.description || "",
|
|
location: event.location || "",
|
|
url: event.url || "",
|
|
start: event.start,
|
|
end: event.end || "",
|
|
allDay: event.allDay || false,
|
|
});
|
|
};
|
|
|
|
return (
|
|
<Card className="w-full">
|
|
<CardHeader className="pb-3">
|
|
<div className="flex items-start justify-between">
|
|
<div className="space-y-1 flex-1">
|
|
<h3 className="font-semibold leading-none tracking-tight">
|
|
{event.title}
|
|
</h3>
|
|
{event.recurrenceRule && (
|
|
<div className="mt-1">
|
|
<RRuleDisplay rrule={event.recurrenceRule} />
|
|
</div>
|
|
)}
|
|
{event.description && (
|
|
<p className="text-sm text-muted-foreground mt-2 break-words">
|
|
{event.description}
|
|
</p>
|
|
)}
|
|
</div>
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<Button variant="ghost" className="h-8 w-8 p-0">
|
|
<MoreHorizontal className="h-4 w-4" />
|
|
<span className="sr-only">Open menu</span>
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent align="end">
|
|
<DropdownMenuItem onClick={handleEdit}>Edit</DropdownMenuItem>
|
|
<DropdownMenuItem
|
|
onClick={() => onDelete(event.id)}
|
|
className="text-destructive"
|
|
>
|
|
Delete
|
|
</DropdownMenuItem>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
</div>
|
|
</CardHeader>
|
|
|
|
<CardContent className="pt-0">
|
|
<div className="space-y-2">
|
|
<div className="flex items-center text-sm text-muted-foreground">
|
|
<Clock className="mr-2 h-4 w-4" />
|
|
{formatDateTime(event.start, event.allDay)}
|
|
</div>
|
|
|
|
{event.location && (
|
|
<div className="flex items-center text-sm text-muted-foreground">
|
|
<LucideMapPin className="mr-2 h-4 w-4" />
|
|
{event.location}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
};
|