# PM-Pics Routes Reference > **Purpose**: Quick reference for LLM code assistants > **Format**: Structured mappings of routes → components → files --- ## Route-to-Component Mapping ### Top-Level Routes ```yaml /: component: Index file: src/pages/Index.tsx renders: PhotoGrid file: src/components/PhotoGrid.tsx auth: false /auth: component: Auth file: src/pages/Auth.tsx auth: false /profile: component: Profile file: src/pages/Profile.tsx auth: required /post/:id: component: Post file: src/pages/Post.tsx auth: false child_components: - ImageLightbox: src/components/ImageLightbox.tsx - Comments: src/components/Comments.tsx - EditImageModal: src/components/EditImageModal.tsx - MagicWizardButton: src/components/MagicWizardButton.tsx /user/:userId: component: UserProfile file: src/pages/UserProfile.tsx auth: false /user/:userId/collections: component: UserCollections file: src/pages/UserCollections.tsx auth: false /collections/new: component: NewCollection file: src/pages/NewCollection.tsx auth: required /collections/:userId/:slug: component: Collections file: src/pages/Collections.tsx auth: conditional # private collections require ownership renders: PhotoGrid /tags/:tag: component: TagPage file: src/pages/TagPage.tsx auth: false renders: PhotoGrid /search: component: SearchResults file: src/pages/SearchResults.tsx auth: false query_params: [q] renders: PhotoGrid /wizard: component: Wizard file: src/pages/Wizard.tsx renders: ImageWizard file: src/components/ImageWizard.tsx auth: required child_components: - ImageLightbox: src/components/ImageLightbox.tsx - ModelSelector: src/components/ImageWizard/components/ModelSelector.tsx - QuickActionsToolbar: src/components/ImageWizard/components/QuickActionsToolbar.tsx - ImageActionButtons: src/components/ImageWizard/components/ImageActionButtons.tsx /new: component: NewPost file: src/pages/NewPost.tsx auth: required /version-map/:id: component: VersionMap file: src/pages/VersionMap.tsx auth: false /organizations: component: Organizations file: src/pages/Organizations.tsx auth: false ``` ### Organization-Scoped Routes All routes above have org-scoped equivalents: ```yaml /org/:orgSlug/*: pattern: /org/:orgSlug + [any top-level route] examples: - /org/acme-corp - /org/acme-corp/post/:id - /org/acme-corp/wizard context: OrganizationContext file: src/contexts/OrganizationContext.tsx filtering: Content filtered by organization_id ``` --- ## Core Navigation Components ```yaml TopNavigation: file: src/components/TopNavigation.tsx provides_links: - Home: / or /org/:orgSlug - Organizations: /organizations - Wizard: /wizard - Profile: /profile - Auth: /auth uses_contexts: - OrganizationContext - AuthContext PhotoGrid: file: src/components/PhotoGrid.tsx renders: PhotoCard[] sets_context: PostNavigationContext navigation_target: /post/:id PhotoCard: file: src/components/PhotoCard.tsx navigation: onClick -> /post/:id ImageLightbox: file: src/components/ImageLightbox.tsx navigation: prev/next via PostNavigationContext keyboard: [ArrowLeft, ArrowRight, Escape, Space] features: [Wizard mode, Templates, Voice, History] MagicWizardButton: file: src/components/MagicWizardButton.tsx navigation: Current post -> /wizard persistence: sessionStorage[wizardInitialImage, postNavigationContext] ``` --- ## Navigation Contexts ```yaml PostNavigationContext: file: src/contexts/PostNavigationContext.tsx provider: PostNavigationProvider state: posts: Array<{id, title, image_url, user_id}> currentIndex: number source: home | collection | tag | search | user sourceId?: string methods: - setNavigationData(data) - preloadImage(url) persistence: sessionStorage (when navigating to wizard) OrganizationContext: file: src/contexts/OrganizationContext.tsx provider: OrganizationProvider state: orgSlug: string | null isOrgContext: boolean usage: Filters content, prefixes routes with /org/:orgSlug AuthContext: file: src/hooks/useAuth.tsx provider: AuthProvider state: user: User | null guards: Protects /profile, /wizard, /new, /collections/new LogContext: file: src/contexts/LogContext.tsx provider: LogProvider state: logs: LogEntry[] isLoggerVisible: boolean usage: Debug logging in wizard and image generation ``` --- ## Navigation Mechanisms ### 1. React Router Navigation ```typescript // File: src/pages/*.tsx import { useNavigate } from "react-router-dom"; const navigate = useNavigate(); navigate('/post/:id'); // Click navigation navigate(-1); // Back navigation ``` ### 2. PostNavigationContext (Prev/Next) ```typescript // File: src/pages/Post.tsx, src/components/ImageLightbox.tsx const { navigationData, setNavigationData } = usePostNavigation(); // Navigate to next post const newPost = navigationData.posts[navigationData.currentIndex + 1]; navigate(`/post/${newPost.id}`); ``` ### 3. Session Storage Persistence ```typescript // File: src/components/MagicWizardButton.tsx // Store before navigating to wizard sessionStorage.setItem('wizardInitialImage', JSON.stringify(imageData)); sessionStorage.setItem('postNavigationContext', JSON.stringify(navigationData)); // File: src/pages/Post.tsx // Restore on return from wizard const storedData = sessionStorage.getItem('postNavigationContext'); setNavigationData(JSON.parse(storedData)); sessionStorage.removeItem('postNavigationContext'); ``` ### 4. Keyboard Navigation ```typescript // File: src/pages/Post.tsx // Global keyboard listeners ArrowLeft -> handleNavigate('prev') // Previous post ArrowRight -> handleNavigate('next') // Next post Escape -> navigate back // Return to feed // File: src/components/ImageLightbox.tsx // Lightbox keyboard listeners ArrowLeft -> onNavigate('prev') // Previous image ArrowRight -> onNavigate('next') // Next image Space -> toggle prompt field // Show/hide prompt Escape -> onClose() // Close lightbox Ctrl+ArrowUp -> navigate history up // Previous prompt Ctrl+ArrowDown -> navigate history down // Next prompt ``` ### 5. Mouse Wheel Navigation ```typescript // File: src/pages/Post.tsx // Scroll-based navigation at page boundaries wheelDelta > THRESHOLD && isAtBottom -> handleNavigate('next') wheelDelta < THRESHOLD && isAtTop -> handleNavigate('prev') ``` ### 6. Touch Gestures ```typescript // File: src/components/ImageLightbox.tsx // Swipe detection swipe_left -> onNavigate('next') // Next image swipe_right -> onNavigate('prev') // Previous image double_tap -> open lightbox // On Post page ``` --- ## Key Navigation Flows ### 1. Browse → View → Edit ``` Index (PhotoGrid) ↓ click photo Post (/post/:id) ↓ click MagicWizardButton ↓ store context → sessionStorage Wizard (/wizard) ↓ load from sessionStorage ↓ generate variations ↓ back button Post (/post/:id) ↓ restore context ← sessionStorage ↓ resume at exact position ``` **Files involved**: - `src/components/PhotoGrid.tsx` - Sets navigation data - `src/pages/Post.tsx` - Stores/restores context - `src/components/MagicWizardButton.tsx` - Handles storage - `src/pages/Wizard.tsx` - Loads initial image - `src/components/ImageWizard.tsx` - Main wizard logic ### 2. Lightbox Prev/Next Navigation ``` PhotoGrid ↓ setNavigationData(posts[], currentIndex) PostNavigationContext ↓ posts[0...N] Post page opens ↓ opens ImageLightbox ImageLightbox ↓ user presses ← or → ↓ onNavigate('prev' | 'next') Post page ↓ navigate(/post/[newId]) ↓ updates currentIndex ``` **Files involved**: - `src/contexts/PostNavigationContext.tsx` - Context provider - `src/components/PhotoGrid.tsx` - Sets initial data - `src/pages/Post.tsx` - Handles navigation - `src/components/ImageLightbox.tsx` - UI controls ### 3. Organization Context Navigation ``` Any page ↓ URL contains /org/:orgSlug OrganizationProvider ↓ extracts orgSlug from useParams() ↓ provides {orgSlug, isOrgContext} All components ↓ read context ↓ filter content by organization_id ↓ prefix all routes with /org/:orgSlug ``` **Files involved**: - `src/contexts/OrganizationContext.tsx` - Context provider - `src/components/TopNavigation.tsx` - Adjusts links - `src/components/PhotoGrid.tsx` - Filters content - `src/pages/Post.tsx` - Scoped navigation --- ## Router Configuration ```typescript // File: src/App.tsx {/* Top-level routes */} } /> } /> } /> {/* ... all other routes */} {/* Organization-scoped routes */} } /> } /> } /> {/* ... all other org routes */} } /> ``` **Provider Nesting Order** (outer to inner): 1. `QueryClientProvider` - React Query 2. `AuthProvider` - Authentication state 3. `LogProvider` - Debug logging 4. `PostNavigationProvider` - Post navigation 5. `BrowserRouter` - Routing 6. `OrganizationProvider` - Organization context --- ## Image-Related Files (Wizard Features) ```yaml Image Generation/Editing: router: src/lib/image-router.ts apis: - OpenAI: src/lib/openai.ts - Replicate: src/lib/replicate.ts - AIMLAPI: src/lib/aimlapi.ts - Bria: src/lib/bria.ts entry: src/image-api.ts Wizard Handlers: base: src/components/ImageWizard/handlers/ files: - imageHandlers.ts: Upload, selection, download - generationHandlers.ts: Image generation, optimization - publishHandlers.ts: Publishing to gallery - dataHandlers.ts: Loading versions, images - settingsHandlers.ts: Templates, presets, history - voiceHandlers.ts: Voice recording, transcription - agentHandlers.ts: AI agent generation Wizard Components: base: src/components/ImageWizard/components/ files: - ModelSelector.tsx: Model selection UI - QuickActionsToolbar.tsx: Quick action buttons - ImageActionButtons.tsx: Per-image actions ``` --- ## Authentication Guards ```typescript // Pattern used in protected routes // Files: src/pages/Profile.tsx, src/pages/Wizard.tsx, src/pages/NewPost.tsx import { Navigate } from "react-router-dom"; import { useAuth } from "@/hooks/useAuth"; if (!user) { return ; } ``` **Protected Routes**: - `/profile` → `/auth` - `/wizard` → `/auth` - `/new` → `/auth` - `/collections/new` → `/auth` --- ## Common Patterns ### Navigate to Post from Grid ```typescript // File: src/components/PhotoGrid.tsx const handleImageClick = (pictureId: string) => { navigate(`/post/${pictureId}`); }; ``` ### Navigate with Org Context ```typescript // File: src/components/TopNavigation.tsx const { orgSlug, isOrgContext } = useOrganization(); const basePath = isOrgContext ? `/org/${orgSlug}` : ''; navigate(`${basePath}/wizard`); ``` ### Preserve Navigation on Wizard Visit ```typescript // File: src/components/MagicWizardButton.tsx // Before navigate sessionStorage.setItem('postNavigationContext', JSON.stringify(navigationData)); // File: src/pages/Post.tsx // On mount const stored = sessionStorage.getItem('postNavigationContext'); if (stored) { setNavigationData(JSON.parse(stored)); sessionStorage.removeItem('postNavigationContext'); } ``` ### Lightbox Navigation Handler ```typescript // File: src/pages/Post.tsx const handleNavigate = (direction: 'prev' | 'next') => { if (!navigationData) return; const newIndex = direction === 'next' ? navigationData.currentIndex + 1 : navigationData.currentIndex - 1; if (newIndex >= 0 && newIndex < navigationData.posts.length) { const newPost = navigationData.posts[newIndex]; setNavigationData({ ...navigationData, currentIndex: newIndex }); navigate(`/post/${newPost.id}`); } }; ``` --- ## Quick Reference ### Find Route Handler - Route definition: `src/App.tsx` - Page component: `src/pages/[PageName].tsx` - Navigation setup: `src/components/TopNavigation.tsx` ### Find Context Usage - Auth: `useAuth()` from `src/hooks/useAuth.tsx` - Navigation: `usePostNavigation()` from `src/contexts/PostNavigationContext.tsx` - Organization: `useOrganization()` from `src/contexts/OrganizationContext.tsx` ### Find Navigation Logic - Click navigation: `src/components/PhotoGrid.tsx`, `src/components/TopNavigation.tsx` - Keyboard navigation: `src/pages/Post.tsx` (global), `src/components/ImageLightbox.tsx` (lightbox) - Context persistence: `src/components/MagicWizardButton.tsx`, `src/pages/Post.tsx` --- **Version**: 2.0 **Last Updated**: 2025-10-03 **Format**: LLM-optimized reference