Files
2026-06-28 21:34:58 -04:00

5.6 KiB
Raw Permalink Blame History

Handoff Report: Menu Exploration & Investigation

1. Observation

  • Types Definitions:

    • packages/types/index.ts lines 195–208:
      export interface MenuItem {
        id: number
        label: string
        url: string
        order: number
        translations?: any[]
      }
      
      export interface Menu {
        id: number
        name: string
        items: MenuItem[]
        payload?: any
      }
      
    • apps/spa/src/store/menuStore.ts lines 4–21:
      export interface MenuLink {
        label: Record<string, string>;
        url?: string;
        links?: MenuLink[];
      }
      
      export interface MenuColumn {
        title: Record<string, string>;
        links: MenuLink[];
      }
      
      export interface MegaMenuPayload {
        id?: string;
        nodeId?: string;
        label: Record<string, string>;
        url?: string;
        columns?: MenuColumn[];
      }
      
    • apps/website/src/components/navigation/menuTypes.ts lines 1–18:
      export interface MenuLink {
        label: Record<string, string> | string
        url?: string
        links?: MenuLink[]
      }
      
      export interface MenuColumn {
        title: Record<string, string> | string
        links: MenuLink[]
      }
      
      export interface MegaMenuPayload {
        id?: string
        nodeId?: string
        label: Record<string, string> | string
        url?: string
        columns?: MenuColumn[]
      }
      
  • Elysia Backend Routes:

    • apps/backend/src/routes/menus.ts line 5 defines route prefix /menus.
    • PUT /:name (lines 60–147) receives items and payload, upserts the menu model, and executes tx.menuItem operations in a Prisma transaction (prisma.$transaction).
    • Validation schema (lines 132–147) defines payload: t.Optional(t.Any()).
    • Database schema: apps/backend/prisma/schema.prisma lines 638–670 specifies:
      model Menu {
        id        Int        @id @default(autoincrement())
        name      String     @unique
        payload   Json?
        isActive  Boolean    @default(true)
        items     MenuItem[]
        ...
      }
      
  • Storefront & Admin UI Rendering:

    • apps/spa/src/components/DesktopMegaMenu.tsx lines 86–130 renders three hardcoded mockup images from picsum.photos for:
      • Left side root menu mockup: picsum.photos/seed/root-...
      • Column thumbnail: picsum.photos/seed/col-...
      • Right side hover link preview: picsum.photos/seed/link-...
    • apps/website/src/components/navigation/DesktopMegaMenu.tsx lines 73–94 maps columns and links but currently lacks any image placements (root, column, or hover).
    • apps/admin/src/pages/MenuManagerPage.tsx lines 311–327 maps currentMenu.payload recursive tree configuration via TreeNodeEditor but has no inputs for image URLs.

2. Logic Chain

  1. Prisma Schema Constraints: Currently, the Menu and MenuItem database models do not have columns for rootImage, columnImage, or hoverImage (apps/backend/prisma/schema.prisma). Because these are missing in the schema, the backend cannot yet store flat values directly related to menus/menu-items.
  2. Payload Structure: The PUT /:name route accepts an unvalidated JSON tree in payload and stores it directly as a Json database column. Thus, the client applications can structure the payload freely.
  3. TypeScript Contracts: The client applications (apps/spa and apps/website) define different structures for recursive MegaMenuPayload, but both map to the database JSON field.
  4. Current SPA Rendering Logic: The SPA megamenu dropdown implements the three visual image compartments but relies entirely on static mockup links from picsum.photos.
  5. Next.js storefront (apps/website): Does not render any images inside its desktop megamenu layout.
  6. Admin Interface (apps/admin): The MenuManagerPage's recursive TreeNodeEditor component permits editing names and URLs, but has no provisions for specifying the image links.

3. Caveats

  • We assumed that all menus are stored using the Elysia menu routes and no direct raw SQL queries bypass them.
  • We did not check the exact media uploader functionality since we only focused on how URLs are represented in menu definitions.
  • The isActive flag toggle behavior on the website storefront was not fully traced since it does not affect structural data definitions.

4. Conclusion

  • Backend / Database Changes Needed:
    • Prisma schema needs updates: rootImage on Menu, and columnImage / hoverImage on MenuItem.
    • Type validation schemas inside Elysia and typescript interfaces must be expanded to include these optional image fields.
  • Frontend Changes Needed:
    • apps/admin/src/pages/MenuManagerPage.tsx: Expand TreeNodeEditor to support text/upload inputs for the 3 image types depending on the node type (root, column, link).
    • apps/spa/src/components/DesktopMegaMenu.tsx: Replace hardcoded Picsum placeholders with dynamic data retrieved from the payload.
    • apps/website/src/components/navigation/DesktopMegaMenu.tsx: Implement the 3-image layout using next/image to match the SPA design.

5. Verification Method

  • Check project compilation using:
    npm run build --workspaces --if-present
    
  • Inspect file paths to verify the location of changes:
    • Prisma schema: apps/backend/prisma/schema.prisma
    • Types: packages/types/index.ts, apps/spa/src/store/menuStore.ts, apps/website/src/components/navigation/menuTypes.ts
    • Routes: apps/backend/src/routes/menus.ts
    • Components: apps/admin/src/pages/MenuManagerPage.tsx, apps/spa/src/components/DesktopMegaMenu.tsx, apps/website/src/components/navigation/DesktopMegaMenu.tsx