diff --git a/src/modules/event/screens/EventDetailScreen.tsx b/src/modules/event/screens/EventDetailScreen.tsx index 1c48374..7dd1793 100644 --- a/src/modules/event/screens/EventDetailScreen.tsx +++ b/src/modules/event/screens/EventDetailScreen.tsx @@ -1,3 +1,4 @@ +import { useLayoutEffect } from 'react'; import { ArrowLeft } from 'lucide-react'; import { Button, Avatar, EventCover, EventMeetingPoints, showToast, Text, type MeetingPointData } from '../../../shared/components/sketchy'; import { useFestipodData } from '../../../shared/context/FestipodDataContext'; @@ -15,8 +16,19 @@ export function EventDetailScreen() { getEventParticipants, getEventMeetingPoints, getEventOwnership, + openEvent, + getEventReadState, } = useFestipodData(); + // ANOTHER USER'S EVENT IS NOT IN THE OWN LIST. Découvrir links to events from + // every pod; the data layer reads one it does not hold only when asked. Asked + // in a LAYOUT effect so the request lands before the first paint — the + // "not found" state must never flash for an event that is about to load. + useLayoutEffect(() => { + if (eventId) openEvent(eventId); + }, [eventId, openEvent]); + const readState = eventId ? getEventReadState(eventId) : 'unavailable'; + const event = eventId ? getEvent(eventId) : undefined; const participants = eventId ? getEventParticipants(eventId) : []; const meetingPointsRaw = eventId ? getEventMeetingPoints(eventId) : []; @@ -27,6 +39,8 @@ export function EventDetailScreen() { when: mp.time, duration: '~60 min', lieu: mp.location, + // Derived by the data layer (absent where it cannot be counted per point). + participantCount: mp.participantCount, })); // SIGNING UP IS PER MEETING POINT — the product model (on s'inscrit à un @@ -85,7 +99,7 @@ export function EventDetailScreen() { Événement
- Événement non trouvé + {readState === 'loading' ? "Chargement de l'événement…" : 'Événement non trouvé'}
); diff --git a/src/modules/event/screens/EventsScreen.tsx b/src/modules/event/screens/EventsScreen.tsx index d32cc18..2f7dd0e 100644 --- a/src/modules/event/screens/EventsScreen.tsx +++ b/src/modules/event/screens/EventsScreen.tsx @@ -16,13 +16,16 @@ const EVENT_COLORS = ['#E8590C', '#2B6CB0', '#9C4DC7', '#38A169', '#D69E2E']; function EventCard({ event, + participantCount, onClick, }: { - event: { id: string; title: string; date: string; location: string; distance?: number; participantCount: number }; + event: { id: string; title: string; date: string; location: string; distance?: number }; + /** `undefined` when nobody counted it (a catalog entry) — then no count is shown, never a made-up 0. */ + participantCount: number | undefined; onClick: () => void; }) { const color = EVENT_COLORS[Number(event.id.replace(/\D/g, '') || 0) % EVENT_COLORS.length] ?? '#E8590C'; - const people = PEOPLE.slice(0, Math.min(5, Math.max(1, event.participantCount))); + const people = PEOPLE.slice(0, Math.min(5, Math.max(1, participantCount ?? 0))); return (
{event.date} · {event.location}{event.distance != null && ` · ${event.distance} km`}
-
-
- - {event.participantCount} inscrits + {participantCount !== undefined && ( +
+
+ + {participantCount} inscrits +
-
+ )}
); @@ -51,7 +56,7 @@ function EventCard({ export function EventsScreen() { const navigate = useNavigate(); - const { events: ownEvents } = useFestipodData(); + const { events: ownEvents, getEvent } = useFestipodData(); const events = useDiscoverEvents(ownEvents); return ( @@ -78,9 +83,20 @@ export function EventsScreen() { Aucun événement à afficher )} - {events.map(event => ( - navigate(eventPath(event.id))} /> - ))} + {events.map(event => { + // An event the data layer READ (own, or another user's opened by URI) + // carries a derived count; a catalog entry nobody opened carries none — + // its card shows no count rather than a misleading "0 inscrits". + const held = getEvent(event.id); + return ( + navigate(eventPath(event.id))} + /> + ); + })} diff --git a/src/shared/components/sketchy/EventMeetingPoints.tsx b/src/shared/components/sketchy/EventMeetingPoints.tsx index ae5420e..4fee460 100644 --- a/src/shared/components/sketchy/EventMeetingPoints.tsx +++ b/src/shared/components/sketchy/EventMeetingPoints.tsx @@ -7,6 +7,8 @@ export interface MeetingPointData { when: string; duration: string; lieu: string; + /** How many signed up to this point — shown when the caller knows it, omitted otherwise. */ + participantCount?: number; } interface Props { @@ -56,6 +58,12 @@ export function EventMeetingPoints({ points, joinedIds, onToggle, expanded = fal 🕒 {p.when} · {p.duration}
📍 {p.lieu} + {p.participantCount !== undefined && ( + <> +
+ 👥 {p.participantCount} inscrit{p.participantCount > 1 ? 's' : ''} + + )}