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 };