import { Event, CalendarDay } from './types'; /** * Get the month name for display */ export const getMonthName = (date: Date, short: boolean = false): string => { const monthNames = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]; if (short) { return monthNames[date.getMonth()].slice(0, 3); } return monthNames[date.getMonth()]; }; /** * Get day names for calendar header */ export const getDayNames = (short: boolean = false): string[] => { if (short) { return ['S', 'M', 'T', 'W', 'T', 'F', 'S']; } return ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; }; /** * Check if two dates are on the same day */ export const isSameDay = (date1: Date, date2: Date): boolean => { return date1.toDateString() === date2.toDateString(); }; /** * Check if a date is today */ export const isToday = (date: Date): boolean => { return isSameDay(date, new Date()); }; /** * Generate calendar days grid for a given month */ export const generateCalendarDays = (currentDate: Date, events: Event[]): CalendarDay[] => { const year = currentDate.getFullYear(); const month = currentDate.getMonth(); // Get first day of month and number of days const firstDay = new Date(year, month, 1); const lastDay = new Date(year, month + 1, 0); const daysInMonth = lastDay.getDate(); const startingDayOfWeek = firstDay.getDay(); // Calculate previous month days to show const prevMonth = new Date(year, month - 1, 0); const daysInPrevMonth = prevMonth.getDate(); const calendarDays: CalendarDay[] = []; // Calculate total cells needed const totalCells = Math.ceil((daysInMonth + startingDayOfWeek) / 7) * 7; for (let i = 0; i < totalCells; i++) { let dayNumber: number; let isCurrentMonth: boolean; let currentDayDate: Date; if (i < startingDayOfWeek) { // Previous month days dayNumber = daysInPrevMonth - (startingDayOfWeek - i - 1); isCurrentMonth = false; currentDayDate = new Date(year, month - 1, dayNumber); } else if (i >= startingDayOfWeek + daysInMonth) { // Next month days dayNumber = i - startingDayOfWeek - daysInMonth + 1; isCurrentMonth = false; currentDayDate = new Date(year, month + 1, dayNumber); } else { // Current month days dayNumber = i - startingDayOfWeek + 1; isCurrentMonth = true; currentDayDate = new Date(year, month, dayNumber); } // Get events for this day const dayEvents = events.filter(event => { const eventDate = new Date(event.start_time); return isSameDay(eventDate, currentDayDate); }); calendarDays.push({ day: dayNumber, isCurrentMonth, isToday: isToday(currentDayDate), date: currentDayDate, events: dayEvents }); } return calendarDays; }; /** * Get events for a specific day */ export const getEventsForDay = (events: Event[], date: Date): Event[] => { return events.filter(event => { const eventDate = new Date(event.start_time); return isSameDay(eventDate, date); }); }; /** * Format date for display */ export const formatDate = (date: Date, options?: Intl.DateTimeFormatOptions): string => { const defaultOptions: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'long', day: 'numeric' }; return new Intl.DateTimeFormat('en-US', { ...defaultOptions, ...options }).format(date); }; /** * Format time for display */ export const formatTime = (date: Date): string => { return new Intl.DateTimeFormat('en-US', { hour: 'numeric', minute: '2-digit', hour12: true }).format(date); }; /** * Format date and time for display */ export const formatDateTime = (dateString: string) => { const date = new Date(dateString); return { date: formatDate(date), time: formatTime(date), dayOfWeek: date.toLocaleDateString('en-US', { weekday: 'long' }) }; }; /** * Get category color classes */ export const getCategoryColor = (category?: string): string => { const colors = { music: 'from-purple-500 to-pink-500', arts: 'from-blue-500 to-cyan-500', community: 'from-green-500 to-emerald-500', business: 'from-gray-500 to-slate-500', food: 'from-orange-500 to-red-500', sports: 'from-indigo-500 to-purple-500', default: 'from-gray-400 to-gray-500' }; return colors[category as keyof typeof colors] || colors.default; }; /** * Get category icon */ export const getCategoryIcon = (category?: string): string => { const icons = { music: '🎵', arts: '🎨', community: '🤝', business: '💼', food: '🍷', sports: '⚽', default: '📅' }; return icons[category as keyof typeof icons] || icons.default; }; /** * Group events by date */ export const groupEventsByDate = (events: Event[]): Record => { const grouped: Record = {}; events.forEach(event => { const dateKey = new Date(event.start_time).toDateString(); if (!grouped[dateKey]) { grouped[dateKey] = []; } grouped[dateKey].push(event); }); return grouped; }; /** * Sort events by start time */ export const sortEventsByDate = (events: Event[]): Event[] => { return events.sort((a, b) => new Date(a.start_time).getTime() - new Date(b.start_time).getTime() ); }; /** * Filter future events */ export const getFutureEvents = (events: Event[]): Event[] => { const today = new Date(); return events.filter(event => new Date(event.start_time) >= today); }; /** * Get relative date text (Today, Tomorrow, etc.) */ export const getRelativeDateText = (date: Date): string => { const today = new Date(); const tomorrow = new Date(today); tomorrow.setDate(tomorrow.getDate() + 1); if (isSameDay(date, today)) { return 'Today'; } else if (isSameDay(date, tomorrow)) { return 'Tomorrow'; } else { return formatDate(date, { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }); } }; /** * Truncate text with ellipsis */ export const truncateText = (text: string, maxLength: number): string => { if (text.length <= maxLength) return text; return text.substring(0, maxLength) + '...'; }; /** * Get CSS variable value */ export const getCSSVariable = (variableName: string): string => { if (typeof window === 'undefined') return ''; return getComputedStyle(document.documentElement).getPropertyValue(variableName).trim(); };