import React, { useState, useEffect } from 'react'; import { useNavigate, useLocation, useParams } from 'react-router-dom'; import { Box, Drawer, AppBar, Toolbar, IconButton, Typography, List, ListItem, ListItemButton, ListItemIcon, ListItemText, Paper, Grid, Card, CardContent, CardActionArea, useTheme, useMediaQuery } from '@mui/material'; import MenuIcon from '@mui/icons-material/Menu'; import PersonIcon from '@mui/icons-material/Person'; import CloseIcon from '@mui/icons-material/Close'; import ArrowBackIcon from '@mui/icons-material/ArrowBack'; import DescriptionIcon from '@mui/icons-material/Description'; import CodeIcon from '@mui/icons-material/Code'; import LayersIcon from '@mui/icons-material/Layers'; import DashboardIcon from '@mui/icons-material/Dashboard'; import PaletteIcon from '@mui/icons-material/Palette'; import AnalyticsIcon from '@mui/icons-material/Analytics'; import ViewQuiltIcon from '@mui/icons-material/ViewQuilt'; import { Document } from '../components/Document'; import { BackstoryPageProps } from '../components/BackstoryTab'; import { BackstoryUIOverviewPage } from 'documents/BackstoryUIOverviewPage'; import { BackstoryAppAnalysisPage } from 'documents/BackstoryAppAnalysisPage'; import { BackstoryThemeVisualizerPage } from 'documents/BackstoryThemeVisualizerPage'; import { UserManagement } from 'documents/UserManagement'; import { MockupPage } from 'documents/MockupPage'; // Sidebar navigation component using MUI components const Sidebar: React.FC<{ currentPage: string; onDocumentSelect: (docName: string, open: boolean) => void; onClose?: () => void; isMobile: boolean; }> = ({ currentPage, onDocumentSelect, onClose, isMobile }) => { const navigate = useNavigate(); // Document definitions const handleItemClick = (route: string) => { onDocumentSelect(route, true); if (isMobile && onClose) { onClose(); } }; return ( Documentation {isMobile && onClose && ( )} {documents.map((doc, index) => ( doc.route ? handleItemClick(doc.route) : navigate('/')} selected={currentPage === doc.route} sx={{ borderRadius: 1, mb: 0.5 }} > {getDocumentIcon(doc.title)} ))} ); }; const getDocumentIcon = (title: string): React.ReactNode => { const item = documents.find(d => d.title.toLocaleLowerCase() === title.toLocaleLowerCase()); if (!item) { throw Error(`${title} does not exist in documents`); } return item.icon || ; } type DocType = { title: string; route: string | null; description: string; icon?: React.ReactNode; }; const documents : DocType[] = [ { title: "Backstory", route: null, description: "Backstory", icon: }, { title: "About", route: "about", description: "General information about the application and its purpose", icon: }, { title: "BETA", route: "beta", description: "Details about the current beta version and upcoming features", icon: }, { title: "Resume Generation Architecture", route: "resume-generation", description: "Technical overview of how resumes are processed and generated", icon: }, { title: "Application Architecture", route: "about-app", description: "System design and technical stack information", icon: }, { title: "Authentication Architecture", route: "authentication.md", description: "Complete authentication architecture", icon: }, { title: "UI Overview", route: "ui-overview", description: "Guide to the user interface components and interactions", icon: }, { title: "UI Mockup", route: "ui-mockup", description: "Visual previews of interfaces and layout concepts", icon: }, { title: "Chat Mockup", route: "mockup-chat-system", description: "Mockup of chat system", icon: }, { title: "Theme Visualizer", route: "theme-visualizer", description: "Explore and customize application themes and visual styles", icon: }, { title: "App Analysis", route: "app-analysis", description: "Statistics and performance metrics of the application", icon: }, { title: 'Text Mockups', route: "backstory-ui-mockups", description: "Early text mockups of many of the interaction points." }, { title: 'User Management', route: "user-management", description: "User management.", icon: }, { title: 'Type Safety', route: "type-safety", description: "Overview of front/back-end type synchronization.", icon: }, ]; const documentFromRoute = (route: string) : DocType | null => { const index = documents.findIndex(v => v.route === route); if (index === -1) { return null } return documents[index]; }; // Helper function to get document title from route const documentTitleFromRoute = (route: string): string => { const doc = documentFromRoute(route); if (doc === null) { return 'Documentation' } return doc.title; } const DocsPage = (props: BackstoryPageProps) => { const { submitQuery, setSnack } = props; const navigate = useNavigate(); const location = useLocation(); const { paramPage = '' } = useParams(); const [page, setPage] = useState(paramPage); const [drawerOpen, setDrawerOpen] = useState(false); const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down('md')); // Track location changes useEffect(() => { const parts = location.pathname.split('/'); if (parts.length > 2) { setPage(parts[2]); } else { setPage(''); } }, [location]); // Close drawer when changing to desktop view useEffect(() => { if (!isMobile) { setDrawerOpen(false); } }, [isMobile]); // Handle document navigation const onDocumentExpand = (docName: string, open: boolean) => { console.log("Document expanded:", { docName, open, location }); if (open) { const parts = location.pathname.split('/'); if (docName === "backstory") { navigate('/'); return; } if (parts.length > 2) { const basePath = parts.slice(0, -1).join('/'); navigate(`${basePath}/${docName}`); } else { navigate(docName); } } else { const basePath = location.pathname.split('/').slice(0, -1).join('/'); navigate(`${basePath}`); } }; // Toggle mobile drawer const toggleDrawer = () => { setDrawerOpen(!drawerOpen); }; // Close the drawer const closeDrawer = () => { setDrawerOpen(false); }; interface DocViewProps { page: string }; const DocView = (props: DocViewProps) => { const { page = 'about' } = props; const title = documentTitleFromRoute(page); const icon = getDocumentIcon(title); return ( {icon} {title} {page && } ); }; // Render the appropriate content based on current page function renderContent() { switch (page) { case 'ui-overview': return (); case 'theme-visualizer': return (); case 'app-analysis': return (); case 'ui-mockup': return (); case 'user-management': return (); default: if (documentFromRoute(page)) { return } // Document grid for landing page return ( Documentation Select a document from the sidebar to view detailed technical information about the application. {documents.map((doc, index) => { if (doc.route === null) return (<>); return ( doc.route ? onDocumentExpand(doc.route, true) : navigate('/')}> {getDocumentIcon(doc.title)} {doc.title} {doc.description} ) })} ); } } // Calculate drawer width const drawerWidth = 240; return ( {/* Mobile App Bar */} {isMobile && ( {page ? documentTitleFromRoute(page) : "Documentation"} )} {/* Navigation drawer */} {/* Mobile drawer (temporary) */} {isMobile ? ( ) : ( // Desktop drawer (permanent) )} {/* Main content */} {renderContent()} ); }; export { DocsPage };