feat(showcase): add PouchDB sample component and storage page
- Implemented PouchSample component for managing POS configurations and item inventories using PouchDB. - Created StoragePage to encapsulate the PouchSample component. - Added UI components page with various UI elements including buttons, forms, and data grids. - Defined Electron type declarations for printing and auto-update functionalities. - Extended event registry with custom application events for printing and stock updates. - Configured Vite for the showcase application with React and Tailwind CSS support. - Updated package.json and pnpm-lock.yaml to include necessary dependencies for the showcase app.
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user