From b6a84d0d8bfb1b9e5207f416f3a9f25c077be8a1 Mon Sep 17 00:00:00 2001 From: Milan Date: Wed, 29 Jul 2026 22:08:34 +0530 Subject: [PATCH 1/5] feat(events): add desktop split-screen master-detail layout --- src/App.tsx | 37 ++++++++++------ src/components/EventCard.tsx | 6 ++- src/pages/Events/EmptyState.tsx | 16 +++++++ .../Events/EventDetail.tsx} | 10 ++--- src/pages/Events/EventsLayout.tsx | 43 +++++++++++++++++++ .../Events/EventsList.tsx} | 11 +++-- 6 files changed, 99 insertions(+), 24 deletions(-) create mode 100644 src/pages/Events/EmptyState.tsx rename src/{routes/events.$eventId.tsx => pages/Events/EventDetail.tsx} (99%) create mode 100644 src/pages/Events/EventsLayout.tsx rename src/{routes/events.tsx => pages/Events/EventsList.tsx} (99%) diff --git a/src/App.tsx b/src/App.tsx index c45a54872..a30a15647 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -120,8 +120,10 @@ const Leaderboard = lazy(() => import("./components/Leaderboard").then((m) => ({ default: m.Leaderboard })), ); -const LazyEventsIndex = lazy(() => import("./routes/events")); -const LazyEventDetails = lazy(() => import("./routes/events.$eventId")); +const EventsLayout = lazy(() => import("./pages/Events/EventsLayout")); +const LazyEventsIndex = lazy(() => import("./pages/Events/EventsList")); +const LazyEventDetails = lazy(() => import("./pages/Events/EventDetail")); +const EmptyState = lazy(() => import("./pages/Events/EmptyState")); function PageFallback() { return ( @@ -174,20 +176,27 @@ const router = createBrowserRouter( path="/events" element={ }> - + } - /> - }> - - - } - /> - } /> - } /> + > + }> + + + } + /> + }> + + + } + /> + } /> {/* Events Map View with clustering */} } /> diff --git a/src/components/EventCard.tsx b/src/components/EventCard.tsx index ee1fe8029..48fb7927d 100644 --- a/src/components/EventCard.tsx +++ b/src/components/EventCard.tsx @@ -45,6 +45,7 @@ interface EventCardProps { isRsvpPending: boolean; onBookmarkToggle: (eventId: string, isSaved: boolean) => void; isBookmarkPending: boolean; + active?: boolean; } // Assumed lead time (in days) used when an event has no `created_at` available @@ -163,6 +164,7 @@ export function EventCard({ isRsvpPending, onBookmarkToggle, isBookmarkPending, + active, }: EventCardProps) { const club = Array.isArray(event.clubs) ? event.clubs[0] : event.clubs; const rsvps = Array.isArray(event.event_rsvps) ? event.event_rsvps : []; @@ -254,7 +256,9 @@ export function EventCard({ id={`event-${event.id}`} onMouseEnter={preloadEvent.onMouseEnter} onMouseLeave={preloadEvent.onMouseLeave} - className={`neu-border p-5 relative ${colors[index % colors.length]} transition-transform duration-300 ease-out group-hover:scale-[1.02]`} + className={`neu-border p-5 relative ${ + active ? "bg-blue-100 border-4 border-blue-600 ring-2 ring-blue-600" : colors[index % colors.length] + } transition-all duration-300 ease-out group-hover:scale-[1.02]`} > {" "}
diff --git a/src/pages/Events/EmptyState.tsx b/src/pages/Events/EmptyState.tsx new file mode 100644 index 000000000..00ab2080f --- /dev/null +++ b/src/pages/Events/EmptyState.tsx @@ -0,0 +1,16 @@ +import React from "react"; +import { Calendar } from "lucide-react"; + +export default function EmptyState() { + return ( +
+
+ +

Select an event

+

+ Click on any event from the list on the left to view its details, RSVP, or see who is attending. +

+
+
+ ); +} diff --git a/src/routes/events.$eventId.tsx b/src/pages/Events/EventDetail.tsx similarity index 99% rename from src/routes/events.$eventId.tsx rename to src/pages/Events/EventDetail.tsx index 2492418c9..eb413f68c 100644 --- a/src/routes/events.$eventId.tsx +++ b/src/pages/Events/EventDetail.tsx @@ -6,7 +6,7 @@ import { TableOfContents } from "@/components/events/TableOfContents"; import NotFound from "./NotFound"; import { User } from "@supabase/supabase-js"; import { useEmailVerification } from "@/hooks/useEmailVerification"; -import { SiteShell } from "@/components/site/SiteShell"; +// Removed SiteShell import import { SkeletonEventDetails } from "@/components/events/SkeletonEventDetails"; import { MapSkeleton } from "@/components/ui/MapSkeleton"; @@ -896,7 +896,7 @@ export default function EventDetailsPage() { if (!event) { return ( - + <>

Event Not Found

@@ -912,7 +912,7 @@ export default function EventDetailsPage() {
-
+ ); } @@ -1007,7 +1007,7 @@ export default function EventDetailsPage() { attendeeCount >= maxAttendees; return ( - + <> {/* Breadcrumb nav */}