feat(web): foundation com brand JCS + AntD theme + Rafael painel placeholder
- Design tokens (CSS variables) espelhando brand.md v1.0:
- Paleta JCS Blue #004a99 + estados funcionais
- Plus Jakarta Sans Variable self-host (LGPD + perf)
- Radius 12/20, sombra 0 4px 25px rgba(0,0,0,0.05)
- Layout topbar 80 + sidebar 260 (brand.md canon)
- AntD ConfigProvider com tema JCS (cores, fonts, radius, shadow, motion)
- TanStack Router + Query setup com defaults conservadores
- AppShell desktop (Topbar + Sidebar) com tom canônico
- RafaelPainel placeholder com vocabulário canônico:
meta de maio, clientes esfriando (OPENFRIOS 47 dias), próxima visita,
comissão+FLEX, copy direta apple-inspired
- Logos copiadas para apps/web/public/
- Limpeza: removidos placeholders Nx (app.tsx, nx-welcome.tsx, styles.css)
- pt-BR locale (dayjs + AntD)
- Build OK: 878KB JS (vai code-splitar pós cockpits separados)
Refs: brand.md, design-artifacts/A-Product-Brief/03-visual-direction.md,
design-artifacts/B-Trigger-Map/personas/02-rafael-representante.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
102
apps/web/src/components/layout/Sidebar.tsx
Normal file
102
apps/web/src/components/layout/Sidebar.tsx
Normal file
@@ -0,0 +1,102 @@
|
||||
import { Menu } from 'antd';
|
||||
import { useLocation, useNavigate } from '@tanstack/react-router';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import {
|
||||
faChartLine,
|
||||
faClipboardList,
|
||||
faFunnelDollar,
|
||||
faCalendarDays,
|
||||
faUsers,
|
||||
faBoxesStacked,
|
||||
faGear,
|
||||
faPercent,
|
||||
faFileInvoiceDollar,
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
import type { ItemType } from 'antd/es/menu/interface';
|
||||
|
||||
/**
|
||||
* Sidebar canônica do SAR (260px fixa — brand.md).
|
||||
* Itens mockados para Rafael cockpit. Variantes por cockpit virão depois.
|
||||
*/
|
||||
export function Sidebar() {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
const items: ItemType[] = [
|
||||
{
|
||||
key: '/',
|
||||
icon: <FontAwesomeIcon icon={faChartLine} fixedWidth />,
|
||||
label: 'Painel',
|
||||
},
|
||||
{
|
||||
key: '/agenda',
|
||||
icon: <FontAwesomeIcon icon={faCalendarDays} fixedWidth />,
|
||||
label: 'Agenda e Rotas',
|
||||
},
|
||||
{
|
||||
key: '/clientes',
|
||||
icon: <FontAwesomeIcon icon={faUsers} fixedWidth />,
|
||||
label: 'Clientes',
|
||||
},
|
||||
{
|
||||
key: '/produtos',
|
||||
icon: <FontAwesomeIcon icon={faBoxesStacked} fixedWidth />,
|
||||
label: 'Catálogo',
|
||||
},
|
||||
{
|
||||
key: '/funil',
|
||||
icon: <FontAwesomeIcon icon={faFunnelDollar} fixedWidth />,
|
||||
label: 'Funil de Vendas',
|
||||
},
|
||||
{
|
||||
key: '/pedidos',
|
||||
icon: <FontAwesomeIcon icon={faClipboardList} fixedWidth />,
|
||||
label: 'Pedidos',
|
||||
},
|
||||
{
|
||||
key: '/comissao',
|
||||
icon: <FontAwesomeIcon icon={faPercent} fixedWidth />,
|
||||
label: 'Comissão / FLEX',
|
||||
},
|
||||
{
|
||||
type: 'divider',
|
||||
},
|
||||
{
|
||||
key: '/relatorios',
|
||||
icon: <FontAwesomeIcon icon={faFileInvoiceDollar} fixedWidth />,
|
||||
label: 'Relatórios',
|
||||
},
|
||||
{
|
||||
key: '/configuracoes',
|
||||
icon: <FontAwesomeIcon icon={faGear} fixedWidth />,
|
||||
label: 'Configurações',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<aside
|
||||
style={{
|
||||
width: 'var(--layout-sidebar-width)',
|
||||
flexShrink: 0,
|
||||
height: 'calc(100vh - var(--layout-topbar-height))',
|
||||
background: 'var(--bg-surface)',
|
||||
borderRight: '1px solid var(--border-subtle)',
|
||||
position: 'sticky',
|
||||
top: 'var(--layout-topbar-height)',
|
||||
overflowY: 'auto',
|
||||
padding: 'var(--space-md) var(--space-xs)',
|
||||
}}
|
||||
>
|
||||
<Menu
|
||||
mode="inline"
|
||||
selectedKeys={[location.pathname]}
|
||||
items={items}
|
||||
onClick={({ key }) => navigate({ to: key as string })}
|
||||
style={{
|
||||
border: 'none',
|
||||
background: 'transparent',
|
||||
}}
|
||||
/>
|
||||
</aside>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user