feat: use friendly event date labels
This commit is contained in:
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user