14 KiB
14 KiB
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
/:
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:
/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
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
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
// 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)
// 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
// 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
// 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
// File: src/pages/Post.tsx
// Scroll-based navigation at page boundaries
wheelDelta > THRESHOLD && isAtBottom -> handleNavigate('next')
wheelDelta < THRESHOLD && isAtTop -> handleNavigate('prev')
6. Touch Gestures
// 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 datasrc/pages/Post.tsx- Stores/restores contextsrc/components/MagicWizardButton.tsx- Handles storagesrc/pages/Wizard.tsx- Loads initial imagesrc/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 providersrc/components/PhotoGrid.tsx- Sets initial datasrc/pages/Post.tsx- Handles navigationsrc/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 providersrc/components/TopNavigation.tsx- Adjusts linkssrc/components/PhotoGrid.tsx- Filters contentsrc/pages/Post.tsx- Scoped navigation
Router Configuration
// File: src/App.tsx
<BrowserRouter>
<AuthProvider>
<LogProvider>
<PostNavigationProvider>
<OrganizationProvider>
<Routes>
{/* Top-level routes */}
<Route path="/" element={<Index />} />
<Route path="/post/:id" element={<Post />} />
<Route path="/wizard" element={<Wizard />} />
{/* ... all other routes */}
{/* Organization-scoped routes */}
<Route path="/org/:orgSlug" element={<Index />} />
<Route path="/org/:orgSlug/post/:id" element={<Post />} />
<Route path="/org/:orgSlug/wizard" element={<Wizard />} />
{/* ... all other org routes */}
<Route path="*" element={<NotFound />} />
</Routes>
</OrganizationProvider>
</PostNavigationProvider>
</LogProvider>
</AuthProvider>
</BrowserRouter>
Provider Nesting Order (outer to inner):
QueryClientProvider- React QueryAuthProvider- Authentication stateLogProvider- Debug loggingPostNavigationProvider- Post navigationBrowserRouter- RoutingOrganizationProvider- Organization context
Image-Related Files (Wizard Features)
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
// 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 <Navigate to="/auth" replace />;
}
Protected Routes:
/profile→/auth/wizard→/auth/new→/auth/collections/new→/auth
Common Patterns
Navigate to Post from Grid
// File: src/components/PhotoGrid.tsx
const handleImageClick = (pictureId: string) => {
navigate(`/post/${pictureId}`);
};
Navigate with Org Context
// File: src/components/TopNavigation.tsx
const { orgSlug, isOrgContext } = useOrganization();
const basePath = isOrgContext ? `/org/${orgSlug}` : '';
navigate(`${basePath}/wizard`);
Preserve Navigation on Wizard Visit
// 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
// 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()fromsrc/hooks/useAuth.tsx - Navigation:
usePostNavigation()fromsrc/contexts/PostNavigationContext.tsx - Organization:
useOrganization()fromsrc/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