Files
trackgo-fe/apps/showcase/src/layouts/ShowcaseLayout.tsx
T
shancheas 67ae5b6c11 refactor: improve code formatting and consistency across multiple files
- Standardized import statements and removed unnecessary line breaks for better readability in various components.
- Enhanced error handling and logging in the useElectronPrinter hook.
- Updated sample data formatting in AgGridShowcase for improved clarity.
- Refactored JSX elements for consistent indentation and structure in LandingSample, AuthPage, and EventsPage components.
- Consolidated and simplified conditional rendering logic in several components.

These changes aim to enhance code maintainability and readability throughout the project.
2026-08-25 17:50:48 +07:00

154 lines
5.2 KiB
TypeScript

import { AppShell, NavLink, Group, Title, Box, Select, Text, Paper } from '@repo/ui/components';
import { Outlet, useLocation, useNavigate } from 'react-router-dom';
import { useTranslation } from '@repo/core-i18n';
import { Layout, FileText, Database, ShieldCheck, Lock, Activity, Printer, Globe, Layers, Table2 } from 'lucide-react';
import { DensityType } from '@repo/ui/provider';
import { useThemeStore } from '../core/stores/theme.store';
import { ColorSchemeType } from '@repo/ui/provider';
interface ShowcaseLayoutProps {
density: DensityType;
setDensity: (val: DensityType) => void;
}
export default function ShowcaseLayout({ density, setDensity }: ShowcaseLayoutProps) {
const navigate = useNavigate();
const location = useLocation();
const { i18n } = useTranslation();
const { colorScheme, setColorScheme } = useThemeStore();
const navItems = [
{ label: 'UI Components', path: '/ui-components', icon: Layout },
{ label: 'Layout Engine', path: '/shell-demo', icon: Layout },
{ label: 'Form Engine', path: '/forms', icon: FileText },
{ label: 'Offline Storage', path: '/storage', icon: Database },
{ label: 'RBAC Engine', path: '/rbac', icon: ShieldCheck },
{ label: 'Auth & Security', path: '/auth', icon: Lock },
{ label: 'Events', path: '/events', icon: Activity },
{ label: 'Hardware', path: '/hardware', icon: Printer },
{ label: 'Action Tools', path: '/action-tools', icon: Layers },
{ label: 'AG Grid', path: '/ag-grid', icon: Table2 },
];
const getSubtitle = () => {
const currentPath = location.pathname.replace('/', '');
switch (currentPath) {
case 'rbac':
return 'Role-Based Access Control and Permissions';
case 'storage':
return 'Offline-First PouchDB Synchronization';
case 'auth':
return 'Authentication & Security Layers';
case 'ui-components':
return 'Theme, Typography, Forms & Data Grids';
case 'forms':
return 'Enterprise Form Engine & Zod Validation';
case 'events':
return 'Global Event Bus Synchronization';
case 'hardware':
return 'Hardware Integration & Printers';
case 'layout-engine':
return 'Core Layout Engine & Variants';
case 'action-tools':
return 'Showcase for PageActions and RowActions components';
case 'ag-grid':
return 'Enterprise Data Grid with Mantine Theme Integration';
default:
return 'Architecture Showcase';
}
};
return (
<AppShell
navbar={{
width: 260,
breakpoint: 'sm',
}}
padding="0"
>
<AppShell.Navbar p="md">
<Box mb="xl">
<Title order={3} c="brand.7">
Eigen ERP
</Title>
<Text size="xs" c="dimmed">
Architecture Showcase
</Text>
</Box>
<Box style={{ flex: 1 }}>
{navItems.map((item) => (
<NavLink
key={item.path}
active={location.pathname === item.path}
label={item.label}
leftSection={<item.icon size={18} />}
onClick={() => navigate(item.path)}
variant="filled"
style={{ borderRadius: 'var(--mantine-radius-md)', marginBottom: 4 }}
/>
))}
</Box>
<Box mt="auto" pt="md" style={{ borderTop: '1px solid var(--mantine-color-default-border)' }}>
<Select
label="Color Scheme"
size="xs"
mb="xs"
value={colorScheme}
onChange={(val) => setColorScheme((val as ColorSchemeType) || 'light')}
data={[
{ value: 'light', label: 'Light' },
{ value: 'dark', label: 'Dark' },
]}
/>
<Select
label="Density"
size="xs"
value={density}
onChange={(val) => setDensity((val as DensityType) || 'standard')}
data={[
{ value: 'compact', label: 'Compact' },
{ value: 'standard', label: 'Standard' },
]}
/>
</Box>
</AppShell.Navbar>
<AppShell.Main style={{ display: 'flex', flexDirection: 'column', height: '100vh', overflow: 'hidden' }}>
<Paper
p="md"
radius={0}
withBorder
style={{ borderTop: 0, borderLeft: 0, borderRight: 0, zIndex: 10, flexShrink: 0 }}
>
<Group justify="space-between">
<Box>
<Title order={3}>Architecture Showcase</Title>
<Text size="sm" c="dimmed">
{getSubtitle()}
</Text>
</Box>
<Select
w={180}
size="sm"
variant="filled"
leftSection={<Globe size={16} />}
data={[
{ value: 'en', label: 'English' },
{ value: 'id', label: 'Bahasa Indonesia' },
]}
value={i18n.resolvedLanguage || i18n.language}
onChange={(val) => val && i18n.changeLanguage(val)}
/>
</Group>
</Paper>
<Box className="flex-1 overflow-y-auto p-6" style={{ height: 'calc(100vh - 80px)' }}>
<Outlet />
</Box>
</AppShell.Main>
</AppShell>
);
}