'use client' import {APIError} from 'common/api/utils' import {debug} from 'common/logger' import {useState} from 'react' import toast from 'react-hot-toast' import {Button} from 'web/components/buttons/button' import {CreateEventModal} from 'web/components/events/create-event-modal' import {EventsList} from 'web/components/events/events-list' import {Col} from 'web/components/layout/col' import {EnglishOnlyWarning} from 'web/components/news/english-only-warning' import {PageBase} from 'web/components/page-base' import {SEO} from 'web/components/SEO' import {CompassLoadingIndicator} from 'web/components/widgets/loading-indicator' import {Event, useEvents} from 'web/hooks/use-events' import {usePersistentInMemoryState} from 'web/hooks/use-persistent-in-memory-state' import {useUser} from 'web/hooks/use-user' import {api} from 'web/lib/api' import {useT} from 'web/lib/locale' export default function EventsPage() { const user = useUser() const {events, loading, error, refetch} = useEvents() const [showCreateModal, setShowCreateModal] = useState(false) const [editingEvent, setEditingEvent] = useState(null) const [_rsvpLoading, setRsvpLoading] = usePersistentInMemoryState>( {}, 'rsvp-loading', ) const t = useT() const handleRsvp = async (eventId: string, status: 'going' | 'maybe' | 'not_going') => { if (!user) return setRsvpLoading((prev) => ({...prev, [eventId]: true})) try { await api('rsvp-event', {eventId, status}) refetch() debug('RSVPed to event', eventId) } catch (err) { if (err instanceof APIError) { toast.error(err.message) } else { toast.error(t('events.failed_rsvp', 'Failed to RSVP. Please try again.')) } } finally { setRsvpLoading((prev) => ({...prev, [eventId]: false})) } } const handleCancelRsvp = async (eventId: string) => { if (!user) return setRsvpLoading((prev) => ({...prev, [eventId]: true})) try { await api('cancel-rsvp', {eventId}) refetch() debug('Cancelled RSVP to event', eventId) } catch (err) { if (err instanceof APIError) { toast.error(err.message) } else { toast.error(t('events.failed_cancel_rsvp', 'Failed to cancel RSVP. Please try again.')) } } finally { setRsvpLoading((prev) => ({...prev, [eventId]: false})) } } const handleCancelEvent = async (eventId: string) => { if (!user) return setRsvpLoading((prev) => ({...prev, [eventId]: true})) try { await api('cancel-event', {eventId}) refetch() toast.success(t('events.event_cancelled', 'Event cancelled successfully!')) debug('Cancelled event', eventId) } catch (err) { if (err instanceof APIError) { toast.error(err.message) } else { toast.error(t('events.failed_cancel_event', 'Failed to cancel event. Please try again.')) } } finally { setRsvpLoading((prev) => ({...prev, [eventId]: false})) } } const handleEdit = (event: Event) => { setEditingEvent(event) setShowCreateModal(true) } return ( {/* Header */}

{t('events.title', 'Events')}

{t( 'events.subtitle', 'Discover and join community events — or create your own to bring people together', )}

{/* Event Ideas Section */}

{t('events.why_organize', 'Why organize events?')}

{t( 'events.why_description', 'Events are the heart of meaningful connection. Whether online or in-person, they create space for deeper conversations, shared experiences, and lasting relationships.', )}

📚 {t('events.book_clubs', 'Book clubs')} 🎮 {t('events.game_nights', 'Game nights')} 🚶 {t('events.walking_groups', 'Walking groups')} ☕ {t('events.coffee_chats', 'Coffee chats')} 🎨 {t('events.creative_workshops', 'Creative workshops')} 🤔 {t('events.philosophy_discussions', 'Philosophy discussions')} 🌱 {t('events.sustainability_meetups', 'Sustainability meetups')} 🎯 {t('events.hobby_exchanges', 'Hobby exchanges')}
{user && ( )}
{/* Loading State */} {loading && } {/* Error State */} {error && !loading && (

{t('events.failed_to_load', 'Failed to load events. Please try again later.')}

)} {/* Events Content */} {!loading && !error && events && (
{/* Upcoming Events */} {/* Past Events */} {events.past.length > 0 && ( )}
)} {/* {t('events.create_event', 'Create Event')} Modal */} { setShowCreateModal(false) setEditingEvent(null) }} onSuccess={() => { refetch() toast.success( editingEvent ? t('events.event_updated', 'Event updated successfully!') : t('events.event_created', 'Event created successfully!'), ) setShowCreateModal(false) setEditingEvent(null) }} />
) }