feat: use friendly event date labels

This commit is contained in:
2026-04-09 17:41:37 -04:00
parent 12f2fd95dc
commit e01a7ed1ad
4 changed files with 94 additions and 31 deletions

View File

@@ -18,6 +18,7 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { formatEventRangeLabel } from "@/lib/event-date-format";
import type { CalendarEvent } from "@/lib/types";
interface EventCardProps {
@@ -27,21 +28,6 @@ interface EventCardProps {
}
export const EventCard = ({ event, onEdit, onDelete }: EventCardProps) => {
const formatDateTime = (dateStr: string, allDay: boolean | undefined) => {
return allDay
? new Date(dateStr).toLocaleDateString(undefined, {
month: "short",
day: "numeric",
year: "numeric",
})
: new Date(dateStr).toLocaleString(undefined, {
month: "short",
day: "numeric",
hour: "numeric",
minute: "2-digit",
});
};
const handleEdit = () => {
onEdit({
id: event.id,
@@ -52,12 +38,10 @@ export const EventCard = ({ event, onEdit, onDelete }: EventCardProps) => {
start: event.start,
end: event.end || "",
allDay: event.allDay || false,
recurrenceRule: event.recurrenceRule,
});
};
const endDate =
event.end && !event.allDay ? formatDateTime(event.end, event.allDay) : null;
return (
<motion.div
layout
@@ -66,15 +50,13 @@ export const EventCard = ({ event, onEdit, onDelete }: EventCardProps) => {
exit={{ opacity: 0, y: -8, transition: { duration: 0.15 } }}
transition={{ duration: 0.2 }}
>
<div className="glass-card p-4 group cursor-pointer hover:bg-accent/50 transition-colors duration-150">
<div className="glass-card group cursor-pointer p-4 transition-colors duration-150 hover:bg-accent/50">
<div className="flex items-start gap-3">
<div className="flex-1 min-w-0 space-y-1.5">
<h3 className="font-medium text-sm leading-snug truncate">
{event.title}
</h3>
<div className="min-w-0 flex-1 space-y-1.5">
<h3 className="truncate text-sm font-medium leading-snug">{event.title}</h3>
{event.description && (
<p className="text-xs text-muted-foreground line-clamp-2 leading-relaxed">
<p className="line-clamp-2 text-xs leading-relaxed text-muted-foreground">
{event.description}
</p>
)}
@@ -82,9 +64,7 @@ export const EventCard = ({ event, onEdit, onDelete }: EventCardProps) => {
<div className="flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground">
<span className="inline-flex items-center gap-1">
<Clock className="h-3 w-3 shrink-0" />
{formatDateTime(event.start, event.allDay)}
{endDate && <span className="text-muted-foreground/50">-</span>}
{endDate}
{formatEventRangeLabel(event)}
</span>
{event.location && (
@@ -98,24 +78,24 @@ export const EventCard = ({ event, onEdit, onDelete }: EventCardProps) => {
<Button
variant="link"
size="sm"
className="gap-1 h-auto p-0 text-xs text-primary/70 hover:text-primary"
className="h-auto gap-1 p-0 text-xs text-primary/70 hover:text-primary"
asChild
>
<a
href={event.url}
target="_blank"
rel="noopener noreferrer"
onClick={(e) => e.stopPropagation()}
onClick={(currentEvent) => currentEvent.stopPropagation()}
>
<ExternalLink className="h-3 w-3" />
<span className="truncate max-w-[120px]">Link</span>
<span className="max-w-[120px] truncate">Link</span>
</a>
</Button>
)}
</div>
{event.recurrenceRule && (
<RRuleDisplay rrule={event.recurrenceRule} />
<RRuleDisplay rrule={event.recurrenceRule} start={event.start} />
)}
</div>