From d801adccbc041f828a9cba2c779e4b4f7e0e8a5f Mon Sep 17 00:00:00 2001 From: jzgom067 Date: Tue, 21 Jul 2026 21:08:48 -0400 Subject: [PATCH 01/17] Remove event loading pages --- .../src/app/(event)/[event-code]/loading.tsx | 25 ---------------- .../(event)/[event-code]/painting/loading.tsx | 29 ------------------- 2 files changed, 54 deletions(-) delete mode 100644 frontend/src/app/(event)/[event-code]/loading.tsx delete mode 100644 frontend/src/app/(event)/[event-code]/painting/loading.tsx diff --git a/frontend/src/app/(event)/[event-code]/loading.tsx b/frontend/src/app/(event)/[event-code]/loading.tsx deleted file mode 100644 index 835d0486..00000000 --- a/frontend/src/app/(event)/[event-code]/loading.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import HeaderSpacer from "@/features/header/components/header-spacer"; - -export default function Loading() { - return ( -
- - -
-
- -
-
- -
-
- -
-
- -
-
-
-
- ); -} diff --git a/frontend/src/app/(event)/[event-code]/painting/loading.tsx b/frontend/src/app/(event)/[event-code]/painting/loading.tsx deleted file mode 100644 index 948551c5..00000000 --- a/frontend/src/app/(event)/[event-code]/painting/loading.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import HeaderSpacer from "@/features/header/components/header-spacer"; - -export default function Loading() { - return ( -
- - -
-
- -
-
- -
-
-
-
-
-
-
-
- -
- -
-
-
- ); -} From cb929e9aacdc865ccc090bc8ff446159cb690a91 Mon Sep 17 00:00:00 2001 From: jzgom067 Date: Tue, 21 Jul 2026 21:10:22 -0400 Subject: [PATCH 02/17] Create useViewTransition hook --- frontend/src/lib/hooks/use-view-transition.ts | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 frontend/src/lib/hooks/use-view-transition.ts diff --git a/frontend/src/lib/hooks/use-view-transition.ts b/frontend/src/lib/hooks/use-view-transition.ts new file mode 100644 index 00000000..a213773c --- /dev/null +++ b/frontend/src/lib/hooks/use-view-transition.ts @@ -0,0 +1,37 @@ +"use client"; + +import { useRouter } from "next/navigation"; + +export function useViewTransition() { + const router = useRouter(); + + const doViewTransition = (href: string, timeout: number = 2000) => { + if (!document.startViewTransition) { + router.push(href); + return; + } + + document.startViewTransition(() => { + return new Promise((resolve) => { + const observer = new MutationObserver(() => { + observer.disconnect(); + resolve(); + }); + + observer.observe(document.body, { + childList: true, + subtree: true, + }); + + router.push(href); + + setTimeout(() => { + observer.disconnect(); + resolve(); + }, timeout); + }); + }); + }; + + return doViewTransition; +} From 23006061e6642763429d801999c1ba7fd9150917 Mon Sep 17 00:00:00 2001 From: jzgom067 Date: Tue, 21 Jul 2026 21:10:32 -0400 Subject: [PATCH 03/17] Add grid view transition --- .../src/app/(event)/[event-code]/page-client.tsx | 11 +++++++++-- .../(event)/[event-code]/painting/page-client.tsx | 12 ++++++------ frontend/src/features/event/grid/grid.tsx | 5 ++++- .../event/results/attendees/mobile-drawer.tsx | 12 +++++++++--- 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/frontend/src/app/(event)/[event-code]/page-client.tsx b/frontend/src/app/(event)/[event-code]/page-client.tsx index a9bbf136..696f4644 100644 --- a/frontend/src/app/(event)/[event-code]/page-client.tsx +++ b/frontend/src/app/(event)/[event-code]/page-client.tsx @@ -6,6 +6,7 @@ import { PencilIcon, ShareIcon, SquarePenIcon } from "lucide-react"; import KebabMenu from "@/components/kebab-menu"; import { EventInformation } from "@/core/event/types"; +import ActionButton from "@/features/button/components/action"; import EmptyButton from "@/features/button/components/empty"; import LinkButton from "@/features/button/components/link"; import ScheduleGrid from "@/features/event/grid/grid"; @@ -20,6 +21,7 @@ import { import { ResultsInformation } from "@/features/event/results/lib/types"; import HeaderSpacer from "@/features/header/components/header-spacer"; import ShareMenu from "@/features/share-menu/menu"; +import { useViewTransition } from "@/lib/hooks/use-view-transition"; import { cn } from "@/lib/utils/classname"; export default function ClientPage({ @@ -86,13 +88,18 @@ function EventResults({ eventData }: { eventData: EventInformation }) { currentUser !== null, ); + const doViewTransition = useViewTransition(); + /* BUTTONS */ const paintingButton = ( - } label={(currentUser ? "Edit" : "Add") + " Availability"} - href={`/${eventCode}/painting`} + onClick={() => { + doViewTransition(`/${eventCode}/painting`); + }} + loadOnSuccess /> ); diff --git a/frontend/src/app/(event)/[event-code]/painting/page-client.tsx b/frontend/src/app/(event)/[event-code]/painting/page-client.tsx index 8fb4afac..0d7cc264 100644 --- a/frontend/src/app/(event)/[event-code]/painting/page-client.tsx +++ b/frontend/src/app/(event)/[event-code]/painting/page-client.tsx @@ -3,7 +3,6 @@ import { useEffect, useRef, useState } from "react"; import { parseISO } from "date-fns"; -import { useRouter } from "next/navigation"; import { useDebouncedCallback } from "use-debounce"; import Checkbox from "@/components/checkbox"; @@ -12,7 +11,6 @@ import TextInputField from "@/components/text-input-field"; import { useAvailability } from "@/core/availability/use-availability"; import { EventRange } from "@/core/event/types"; import ActionButton from "@/features/button/components/action"; -import LinkButton from "@/features/button/components/link"; import { MAX_DISPLAY_NAME_LENGTH } from "@/features/event/availability/constants"; import { validateAvailabilityData } from "@/features/event/availability/validate-data"; import TimeZoneSelector from "@/features/event/components/selectors/timezone"; @@ -23,6 +21,7 @@ import { RateLimitBanner, useToast, } from "@/features/system-feedback"; +import { useViewTransition } from "@/lib/hooks/use-view-transition"; import { MESSAGES } from "@/lib/messages"; import { clientPost } from "@/lib/utils/api/client-fetch"; import { ROUTES } from "@/lib/utils/api/endpoints"; @@ -46,7 +45,7 @@ export default function ClientPage({ timeslots: Date[]; initialData: SelfAvailability | null; }) { - const router = useRouter(); + const doViewTransition = useViewTransition(); // AVAILABILITY STATE const { state, setDisplayName, setTimeZone, toggleSlot } = useAvailability( @@ -212,7 +211,7 @@ export default function ClientPage({ try { await clientPost(ROUTES.availability.add, payload); - router.push(`/${eventCode}`); + doViewTransition(`/${eventCode}`); return true; } catch (e) { const error = e as ApiErrorResponse; @@ -230,10 +229,11 @@ export default function ClientPage({ // BUTTONS const cancelButton = ( - doViewTransition(`/${eventCode}`)} + loadOnSuccess /> ); const submitButton = ( diff --git a/frontend/src/features/event/grid/grid.tsx b/frontend/src/features/event/grid/grid.tsx index 207dd9f0..b86904f0 100644 --- a/frontend/src/features/event/grid/grid.tsx +++ b/frontend/src/features/event/grid/grid.tsx @@ -129,7 +129,10 @@ export default function ScheduleGrid({ if (error) return ; return ( -
+
} label={(currentUser ? "Edit" : "Add") + " Availability"} - href={`/${eventCode}/painting`} + onClick={() => { + doViewTransition(`/${eventCode}/painting`); + }} + loadOnSuccess /> ); From a1987d75d5cd9510c069616ffdcdb6072be983c4 Mon Sep 17 00:00:00 2001 From: jzgom067 Date: Tue, 21 Jul 2026 21:23:55 -0400 Subject: [PATCH 04/17] Increase base view transition timeout --- frontend/src/lib/hooks/use-view-transition.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/lib/hooks/use-view-transition.ts b/frontend/src/lib/hooks/use-view-transition.ts index a213773c..f116108d 100644 --- a/frontend/src/lib/hooks/use-view-transition.ts +++ b/frontend/src/lib/hooks/use-view-transition.ts @@ -5,7 +5,7 @@ import { useRouter } from "next/navigation"; export function useViewTransition() { const router = useRouter(); - const doViewTransition = (href: string, timeout: number = 2000) => { + const doViewTransition = (href: string, timeout: number = 3000) => { if (!document.startViewTransition) { router.push(href); return; From 1979b8f68ac512e7352e1154f6f8b86559e4380d Mon Sep 17 00:00:00 2001 From: jzgom067 Date: Tue, 21 Jul 2026 21:29:31 -0400 Subject: [PATCH 05/17] Adjust grid view transition timing and duration --- frontend/src/styles/globals.css | 1 + frontend/src/styles/view-transition.css | 4 ++++ 2 files changed, 5 insertions(+) create mode 100644 frontend/src/styles/view-transition.css diff --git a/frontend/src/styles/globals.css b/frontend/src/styles/globals.css index a6754d77..a2f3d8e4 100644 --- a/frontend/src/styles/globals.css +++ b/frontend/src/styles/globals.css @@ -9,6 +9,7 @@ @import "./radix.css"; @import "./scrollbar.css"; @import "./header.css"; +@import "./view-transition.css"; /* GLOBAL STYLES */ diff --git a/frontend/src/styles/view-transition.css b/frontend/src/styles/view-transition.css new file mode 100644 index 00000000..ff4a9486 --- /dev/null +++ b/frontend/src/styles/view-transition.css @@ -0,0 +1,4 @@ +::view-transition-group(grid) { + animation-duration: 0.35s; + animation-timing-function: ease-in-out; +} From 3972b13569aad1a8953b39dd23c6fb3b87b63e21 Mon Sep 17 00:00:00 2001 From: jzgom067 Date: Tue, 21 Jul 2026 21:29:39 -0400 Subject: [PATCH 06/17] Add background color to grid --- frontend/src/features/event/grid/grid.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/src/features/event/grid/grid.tsx b/frontend/src/features/event/grid/grid.tsx index b86904f0..729f1895 100644 --- a/frontend/src/features/event/grid/grid.tsx +++ b/frontend/src/features/event/grid/grid.tsx @@ -130,7 +130,10 @@ export default function ScheduleGrid({ return (
Date: Wed, 22 Jul 2026 12:50:42 -0400 Subject: [PATCH 07/17] Add viewTransitionName to drawer and island --- frontend/src/components/mobile-footer-island.tsx | 7 +++++++ frontend/src/features/drawer/components/base.tsx | 8 +++++++- frontend/src/features/drawer/props.ts | 4 ++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/mobile-footer-island.tsx b/frontend/src/components/mobile-footer-island.tsx index d7971c06..84872c61 100644 --- a/frontend/src/components/mobile-footer-island.tsx +++ b/frontend/src/components/mobile-footer-island.tsx @@ -7,10 +7,12 @@ export default function MobileFooterIsland({ children, leftButtons, rightButtons, + viewTransitionName, }: { children?: React.ReactNode; leftButtons?: ButtonArray; rightButtons?: ButtonArray; + viewTransitionName?: string; }) { const [islandHeight, setIslandHeight] = useState(0); const islandRef = useRef(null); @@ -40,6 +42,11 @@ export default function MobileFooterIsland({ "border-foreground/10 border", "flex flex-col gap-3", )} + style={{ + viewTransitionName: viewTransitionName + ? viewTransitionName + : undefined, + }} > {children}
diff --git a/frontend/src/features/drawer/components/base.tsx b/frontend/src/features/drawer/components/base.tsx index c4bdeb54..517bbb61 100644 --- a/frontend/src/features/drawer/components/base.tsx +++ b/frontend/src/features/drawer/components/base.tsx @@ -28,6 +28,7 @@ export default function BaseDrawer({ showOverlay = !frostedGlass && modal, nested = false, hideCloseButton = false, + viewTransitionName, ...rest }: DrawerProps) { useDrawerResize(); @@ -155,7 +156,12 @@ export default function BaseDrawer({ _type !== "floating" && "h-[100dvh]", contentClassName, )} - style={{ zIndex: contentZIndex }} + style={{ + zIndex: contentZIndex, + viewTransitionName: viewTransitionName + ? viewTransitionName + : undefined, + }} >
Date: Wed, 22 Jul 2026 14:32:25 -0400 Subject: [PATCH 08/17] Add drawer and island view transitions with ghosts --- frontend/src/app/(event)/[event-code]/page-client.tsx | 7 +++++++ .../src/app/(event)/[event-code]/painting/page-client.tsx | 8 ++++++++ .../features/event/results/attendees/mobile-drawer.tsx | 1 + 3 files changed, 16 insertions(+) diff --git a/frontend/src/app/(event)/[event-code]/page-client.tsx b/frontend/src/app/(event)/[event-code]/page-client.tsx index 696f4644..cd8db361 100644 --- a/frontend/src/app/(event)/[event-code]/page-client.tsx +++ b/frontend/src/app/(event)/[event-code]/page-client.tsx @@ -179,6 +179,13 @@ function EventResults({ eventData }: { eventData: EventInformation }) { eventTitle={eventTitle} eventCode={eventCode} /> + {/* Desktop Sidebar */} diff --git a/frontend/src/app/(event)/[event-code]/painting/page-client.tsx b/frontend/src/app/(event)/[event-code]/painting/page-client.tsx index 0d7cc264..ad23ee88 100644 --- a/frontend/src/app/(event)/[event-code]/painting/page-client.tsx +++ b/frontend/src/app/(event)/[event-code]/painting/page-client.tsx @@ -321,6 +321,7 @@ export default function ClientPage({
+ } + viewTransitionName="results-drawer" > Date: Wed, 22 Jul 2026 14:32:35 -0400 Subject: [PATCH 09/17] Adjust drawer and island animation and z-index --- frontend/src/styles/view-transition.css | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/frontend/src/styles/view-transition.css b/frontend/src/styles/view-transition.css index ff4a9486..59fa9b04 100644 --- a/frontend/src/styles/view-transition.css +++ b/frontend/src/styles/view-transition.css @@ -1,4 +1,12 @@ ::view-transition-group(grid) { animation-duration: 0.35s; animation-timing-function: ease-in-out; + z-index: 1; +} + +::view-transition-group(results-drawer), +::view-transition-group(painting-island) { + animation-duration: 0.35s; + animation-timing-function: ease-in-out; + z-index: 100; } From 25908790437b8b8a396ea8a1a1bbb76b2d630b3f Mon Sep 17 00:00:00 2001 From: jzgom067 Date: Wed, 22 Jul 2026 17:17:22 -0400 Subject: [PATCH 10/17] Switch transition to vertical --- frontend/src/app/(event)/[event-code]/page-client.tsx | 2 +- frontend/src/app/(event)/[event-code]/painting/page-client.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/(event)/[event-code]/page-client.tsx b/frontend/src/app/(event)/[event-code]/page-client.tsx index cd8db361..a3db4b71 100644 --- a/frontend/src/app/(event)/[event-code]/page-client.tsx +++ b/frontend/src/app/(event)/[event-code]/page-client.tsx @@ -181,7 +181,7 @@ function EventResults({ eventData }: { eventData: EventInformation }) { />