You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
60 lines
2.0 KiB
TypeScript
60 lines
2.0 KiB
TypeScript
import { useEffect, useRef } from 'react'
|
|
import { NavLink, Outlet } from 'react-router-dom'
|
|
import { Badge, ThemeSwitcher } from '@sims/ui'
|
|
import { NAV, isLocked } from './nav'
|
|
|
|
export function Layout(props: { userName: string; onLogout: () => void }) {
|
|
const searchRef = useRef<HTMLInputElement>(null)
|
|
|
|
useEffect(() => {
|
|
const onKey = (e: KeyboardEvent) => {
|
|
if (e.ctrlKey && e.key.toLowerCase() === 'k') {
|
|
e.preventDefault()
|
|
searchRef.current?.focus()
|
|
}
|
|
}
|
|
window.addEventListener('keydown', onKey)
|
|
return () => window.removeEventListener('keydown', onKey)
|
|
}, [])
|
|
|
|
return (
|
|
<div className="bo-shell">
|
|
<nav className="bo-side">
|
|
<div className="bo-brand">
|
|
SiMS Next
|
|
<small>Back Office · wireframe</small>
|
|
</div>
|
|
{NAV.map((mod) => (
|
|
<div key={mod.key}>
|
|
<div className="bo-module">{mod.icon} {mod.label}</div>
|
|
{mod.pages.map((p) => (
|
|
<NavLink key={p.path} to={p.path} className={({ isActive }) => (isActive ? 'active' : '')} end={p.path === '/'}>
|
|
{p.label}
|
|
{isLocked(p) && <span className="lock">🔒 {p.edition}</span>}
|
|
</NavLink>
|
|
))}
|
|
</div>
|
|
))}
|
|
</nav>
|
|
<div className="bo-main">
|
|
<header className="bo-top">
|
|
<input ref={searchRef} className="wf" placeholder="Search everything… (Ctrl+K)" />
|
|
<span style={{ flex: 1 }} />
|
|
<select className="wf" style={{ width: 170 }} defaultValue="ST1">
|
|
<option value="ST1">ST1 · T.Nagar</option>
|
|
<option value="ST2">ST2 · Velachery</option>
|
|
<option value="all">All stores</option>
|
|
</select>
|
|
<ThemeSwitcher />
|
|
<Badge tone="accent">Pro</Badge>
|
|
<Badge>{props.userName}</Badge>
|
|
<button type="button" className="wf" onClick={props.onLogout}>Logout</button>
|
|
</header>
|
|
<div className="bo-content">
|
|
<Outlet />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|