From a8bd5790435195be99c866d7057a9dff963cf448 Mon Sep 17 00:00:00 2001 From: dtoro Date: Sun, 15 Mar 2026 20:19:00 +0100 Subject: [PATCH] feat: flip card transition --- .../app/recollections/FlippingCardView.tsx | 35 ++++++++++++++++++ .../app/recollections/RecollectionLayout.tsx | 7 ++-- .../app/recollections/RecollectionMenubar.tsx | 7 +++- frontend/src/main.tsx | 6 +-- frontend/src/styles.css | 37 +++++++++++++++++++ 5 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 frontend/src/app/recollections/FlippingCardView.tsx diff --git a/frontend/src/app/recollections/FlippingCardView.tsx b/frontend/src/app/recollections/FlippingCardView.tsx new file mode 100644 index 0000000..3c93932 --- /dev/null +++ b/frontend/src/app/recollections/FlippingCardView.tsx @@ -0,0 +1,35 @@ +/** + * Flipping card container: Logos on the front, Flux on the back. + * Uses CSS 3D transform for a performant flip animation when switching via the menubar. + */ + +import React from 'react' +import { useLocation, useParams } from 'react-router-dom' +import { LogosPage } from './logos/LogosPage' +import { FluxRoute } from './flux/FluxRoute' + +export function FlippingCardView() { + const { pathname } = useLocation() + const { recollectionId } = useParams<{ recollectionId: string }>() + const isFlux = pathname.endsWith('/flux') + + return ( +
+
+
+ +
+
+ {recollectionId && } +
+
+
+ ) +} diff --git a/frontend/src/app/recollections/RecollectionLayout.tsx b/frontend/src/app/recollections/RecollectionLayout.tsx index dce0eba..34f9ef8 100644 --- a/frontend/src/app/recollections/RecollectionLayout.tsx +++ b/frontend/src/app/recollections/RecollectionLayout.tsx @@ -1,12 +1,13 @@ /** - * Layout for a single recollection: shared menubar (with optional custom content from active page) and outlet. + * Layout for a single recollection: shared menubar and flipping card (Logos front / Flux back). */ import React, { useEffect } from 'react' -import { Link, Outlet, useParams } from 'react-router-dom' +import { Link, useParams } from 'react-router-dom' import { usePlatform } from '@/app/kosmos/KosmosContext' import { RecollectionMenubarProvider } from './RecollectionMenubarContext' import { RecollectionMenubar } from './RecollectionMenubar' +import { FlippingCardView } from './FlippingCardView' export function RecollectionLayout() { const { recollectionId } = useParams<{ recollectionId: string }>() @@ -35,7 +36,7 @@ export function RecollectionLayout() {
- +
diff --git a/frontend/src/app/recollections/RecollectionMenubar.tsx b/frontend/src/app/recollections/RecollectionMenubar.tsx index 319bf22..6629545 100644 --- a/frontend/src/app/recollections/RecollectionMenubar.tsx +++ b/frontend/src/app/recollections/RecollectionMenubar.tsx @@ -3,7 +3,7 @@ */ import React from 'react' -import { Link, NavLink, useParams } from 'react-router-dom' +import { Link, NavLink, useParams, useLocation } from 'react-router-dom' import { usePlatform } from '@/app/kosmos/KosmosContext' import { ArrowLeft } from 'lucide-react' import { FluxIcon, LogosIcon } from '@/lib/icons' @@ -11,14 +11,17 @@ import { useRecollectionMenubar } from './RecollectionMenubarContext' export function RecollectionMenubar() { const { recollectionId } = useParams<{ recollectionId: string }>() + const { pathname } = useLocation() const { recollections } = usePlatform() const { customContent } = useRecollectionMenubar() + const isFlux = pathname.endsWith('/flux') const recollection = recollectionId ? recollections.find((p) => p.id === recollectionId) : null const base = recollectionId ? `/recollections/${recollectionId}` : '' const defaultMiddle = recollection ? ( {recollection.name} ) : null + const middleContent = isFlux ? (customContent ?? defaultMiddle) : defaultMiddle return (
@@ -30,7 +33,7 @@ export function RecollectionMenubar() {
- {customContent ?? defaultMiddle} + {middleContent}
{base && (