import React from 'react'; import { View, Text, StyleSheet, Pressable } from 'react-native'; import { Clock, MapPin, Users } from 'lucide-react-native'; import { format } from 'date-fns'; import type { Calendar, CalendarEvent } from '../../api/types'; import { radius, spacing, typography, type ThemePalette } from '../../theme/tokens'; import { useColors } from '../../theme/colors'; import { eventTimeRange, getEventColor } from '../../lib/calendar-utils'; interface EventCardProps { event: CalendarEvent; calendars: Calendar[]; onPress?: (event: CalendarEvent) => void; onLongPress?: (event: CalendarEvent) => void; } function participantCount(event: CalendarEvent): number { return event.participants ? Object.keys(event.participants).length : 0; } function formatTimeRange(event: CalendarEvent): string { const { start, end, allDay } = eventTimeRange(event); if (allDay) return 'All day'; return `${format(start, 'HH:mm')} – ${format(end, 'HH:mm')}`; } export function EventCard({ event, calendars, onPress, onLongPress }: EventCardProps) { const c = useColors(); const styles = React.useMemo(() => makeStyles(c), [c]); const color = getEventColor(event, calendars); const time = formatTimeRange(event); const count = participantCount(event); return ( [styles.card, pressed && styles.cardPressed]} onPress={() => onPress?.(event)} onLongPress={() => onLongPress?.(event)} > {event.title || 'Untitled'} {event.showWithoutTime && ( All day )} {!event.showWithoutTime && ( {time} )} {event.description ? ( {event.description} ) : null} {count > 0 && ( {count} participants )} ); } function makeStyles(c: ThemePalette) { return StyleSheet.create({ card: { flexDirection: 'row', backgroundColor: c.card, borderTopRightRadius: radius.lg, borderBottomRightRadius: radius.lg, marginBottom: spacing.sm, overflow: 'hidden', borderWidth: 1, borderColor: c.border, }, cardPressed: { backgroundColor: c.surfaceHover }, colorBar: { width: 3 }, body: { flex: 1, padding: spacing.md, gap: 4 }, headerRow: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', gap: spacing.sm, }, title: { ...typography.bodyMedium, color: c.text, flex: 1 }, allDayBadge: { backgroundColor: c.primaryBg, paddingHorizontal: 8, paddingVertical: 2, borderRadius: radius.full, }, allDayText: { ...typography.small, color: c.primary }, detailRow: { flexDirection: 'row', alignItems: 'center', gap: 6 }, detailText: { ...typography.caption, color: c.textMuted, flexShrink: 1 }, }); }