Move working documents to it's own area

This commit is contained in:
2026-04-28 16:33:30 +12:00
parent c9580ac2eb
commit 7e9663fa06
2 changed files with 189 additions and 27 deletions
+184 -22
View File
@@ -13,26 +13,34 @@
keywords: string;
};
const navigation = [
{ href: '/', label: 'Overview', shortLabel: 'OV' },
type NavItem = {
href: string;
label: string;
shortLabel: string;
icon?: 'home';
};
const dashboardItem: NavItem = { href: '/', label: 'Dashboard', shortLabel: 'DB', icon: 'home' };
const workingDocumentItems: NavItem[] = [
{ href: '/raw-materials', label: 'Raw Materials', shortLabel: 'RM' },
{ href: '/mixes', label: 'Mix Master', shortLabel: 'MM' },
{ href: '/products', label: 'Products', shortLabel: 'PR' },
{ href: '/scenarios', label: 'Scenarios', shortLabel: 'SC' }
];
const navigation = [dashboardItem, ...workingDocumentItems];
const footerLinks = [
{ href: '/products', label: 'Delivered Pricing', shortLabel: 'DP' },
{ href: '/scenarios', label: 'Planning View', shortLabel: 'PV' }
];
const primaryBottomNavigation = navigation.slice(0, 4);
const primaryBottomNavigation = [dashboardItem, ...workingDocumentItems.slice(0, 3)];
const searchItems: SearchItem[] = [
{
href: '/',
label: 'Open Hunter Overview',
label: 'Open Dashboard',
description: 'Jump to the Hunter Premium Produce workspace summary.',
keywords: 'hunter premium produce overview dashboard workspace'
keywords: 'hunter premium produce overview dashboard workspace home'
},
{
href: '/raw-materials',
@@ -92,7 +100,7 @@
}
function pageTitle(pathname: string) {
return navigation.find((item) => matchesRoute(item.href, pathname))?.label ?? 'Overview';
return navigation.find((item) => matchesRoute(item.href, pathname))?.label ?? 'Dashboard';
}
function pageDescription(pathname: string) {
@@ -248,14 +256,48 @@
</button>
<nav class="nav-list" aria-label="Client navigation">
{#each navigation as item}
<a class:active={matchesRoute(item.href, page.url.pathname)} href={item.href}>
<span class="nav-icon">{item.shortLabel}</span>
<span>{item.label}</span>
</a>
{/each}
<a class:active={matchesRoute(dashboardItem.href, page.url.pathname)} href={dashboardItem.href}>
<span class="nav-icon">
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M3.75 10.5 12 3.75l8.25 6.75"
stroke="currentColor"
stroke-width="1.85"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M5.25 9.75v9h13.5v-9"
stroke="currentColor"
stroke-width="1.85"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M10.125 18.75v-5.25h3.75v5.25"
stroke="currentColor"
stroke-width="1.85"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</span>
<span>{dashboardItem.label}</span>
</a>
</nav>
<div class="nav-group" aria-label="Working documents">
<p class="nav-group-label">Working Documents</p>
<nav class="nav-sublist" aria-label="Working document pages">
{#each workingDocumentItems as item}
<a class:active={matchesRoute(item.href, page.url.pathname)} href={item.href}>
<span class="nav-icon">{item.shortLabel}</span>
<span>{item.label}</span>
</a>
{/each}
</nav>
</div>
<div class="sidebar-footer">
{#each footerLinks as item}
<a href={item.href}>
@@ -346,7 +388,7 @@
{$sessionHydrated
? $clientSession
? $clientSession.email
: 'Return to the overview page to sign in.'
: 'Return to the dashboard page to sign in.'
: 'Waiting for the browser session check to complete.'}
</span>
</div>
@@ -389,7 +431,35 @@
<nav class="bottom-nav" aria-label="Tablet navigation">
{#each primaryBottomNavigation as item}
<a class:active={matchesRoute(item.href, page.url.pathname)} href={item.href}>
<span class="bottom-nav-icon">{item.shortLabel}</span>
<span class="bottom-nav-icon">
{#if item.icon === 'home'}
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M3.75 10.5 12 3.75l8.25 6.75"
stroke="currentColor"
stroke-width="1.85"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M5.25 9.75v9h13.5v-9"
stroke="currentColor"
stroke-width="1.85"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M10.125 18.75v-5.25h3.75v5.25"
stroke="currentColor"
stroke-width="1.85"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
{:else}
{item.shortLabel}
{/if}
</span>
<span>{item.label}</span>
</a>
{/each}
@@ -428,12 +498,44 @@
<div class="drawer-grid">
<nav class="drawer-section" aria-label="All workspace pages">
{#each navigation as item}
<a class:active={matchesRoute(item.href, page.url.pathname)} href={item.href} onclick={() => (navOpen = false)}>
<span class="nav-icon">{item.shortLabel}</span>
<span>{item.label}</span>
</a>
{/each}
<a class:active={matchesRoute(dashboardItem.href, page.url.pathname)} href={dashboardItem.href} onclick={() => (navOpen = false)}>
<span class="nav-icon">
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path
d="M3.75 10.5 12 3.75l8.25 6.75"
stroke="currentColor"
stroke-width="1.85"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M5.25 9.75v9h13.5v-9"
stroke="currentColor"
stroke-width="1.85"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M10.125 18.75v-5.25h3.75v5.25"
stroke="currentColor"
stroke-width="1.85"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</span>
<span>{dashboardItem.label}</span>
</a>
<div class="drawer-group">
<p class="drawer-group-label">Working Documents</p>
{#each workingDocumentItems as item}
<a class:active={matchesRoute(item.href, page.url.pathname)} href={item.href} onclick={() => (navOpen = false)}>
<span class="nav-icon">{item.shortLabel}</span>
<span>{item.label}</span>
</a>
{/each}
</div>
</nav>
<div class="drawer-section drawer-actions">
@@ -725,12 +827,14 @@
}
.nav-list,
.nav-sublist,
.sidebar-footer {
display: grid;
gap: 0.3rem;
}
.nav-list a,
.nav-sublist a,
.sidebar-footer a {
display: flex;
align-items: center;
@@ -742,22 +846,70 @@
}
.nav-list a:hover,
.nav-sublist a:hover,
.sidebar-footer a:hover,
.nav-list a.active {
.nav-list a.active,
.nav-sublist a.active {
background: var(--green-soft);
}
.nav-list a.active {
.nav-list a.active,
.nav-sublist a.active {
color: var(--green-deep);
font-weight: 600;
}
.nav-group {
display: grid;
gap: 0.55rem;
padding-top: 0.15rem;
}
.nav-group-label,
.drawer-group-label {
margin: 0;
color: var(--muted);
font-size: 0.72rem;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.nav-group-label {
padding: 0 0.68rem;
}
.nav-sublist {
position: relative;
padding-left: 1rem;
}
.nav-sublist::before {
content: '';
position: absolute;
top: 0.4rem;
bottom: 0.4rem;
left: 0.7rem;
width: 1px;
background: var(--line);
}
.nav-sublist a {
position: relative;
}
.nav-icon {
width: 1.56rem;
height: 1.56rem;
border-radius: 0.56rem;
}
.nav-icon svg,
.bottom-nav-icon svg {
width: 0.9rem;
height: 0.9rem;
}
.nav-icon.muted {
background: linear-gradient(135deg, #95a39b 0%, #6e7c73 100%);
}
@@ -1271,6 +1423,16 @@
background: var(--green-soft);
}
.drawer-group {
display: grid;
gap: 0.4rem;
padding-top: 0.35rem;
}
.drawer-group-label {
padding: 0 0.2rem;
}
.drawer-footer {
display: grid;
gap: 0.5rem;
+5 -5
View File
@@ -270,17 +270,17 @@
{:else if !$clientSession}
<section class="dashboard-intro">
<div>
<p class="eyebrow">Client Workspace</p>
<h2>Hunter Premium Produce costing overview.</h2>
<p>Sign in to load live input pricing, mixes, delivered products, and planning scenarios.</p>
<!-- <p class="eyebrow">Client Workspace</p>-->
<h2>Welcome to the Hunter Premium Produce App</h2>
<p>Sign in to load input pricing, Mix Master products, and Scenario Builder.</p>
</div>
</section>
<section class="workspace-banner login-banner">
<div>
<p class="eyebrow">Client Sign-In</p>
<h3>Authenticate before the frontend can return any Hunter Premium Produce data.</h3>
<p>`operator@example.com` is the client account. Lean 101 administration is isolated under `/admin`.</p>
<h3>Login to Hunter Premium Produce</h3>
<p>Enter your username & password to begin</p>
</div>
<form class="signin-form" onsubmit={handleLogin}>