dashboard

This commit is contained in:
2026-03-15 00:09:16 -05:00
parent 006b14d93d
commit 4a2be400c5
7 changed files with 152 additions and 31 deletions

View File

@@ -102,6 +102,7 @@ If implementation changes invalidate those docs, update them in the same change
- Keep the denser UI baseline on active screens unless a specific workflow needs more space - Keep the denser UI baseline on active screens unless a specific workflow needs more space
- Inventory items maintain both cost and price; sales entry should default from item price - Inventory items maintain both cost and price; sales entry should default from item price
- Customer-facing and logistics PDFs should continue to use the backend documents module and Puppeteer pipeline - Customer-facing and logistics PDFs should continue to use the backend documents module and Puppeteer pipeline
- The landing experience should remain `Dashboard`, not `Overview`, and should evolve as a modular metric-first operational surface
## Feature expectations ## Feature expectations

View File

@@ -25,6 +25,7 @@ This repository implements the platform foundation milestone:
6. Any non-filter UI that looks up records or items must use a searchable picker/autocomplete, not a long static dropdown. 6. Any non-filter UI that looks up records or items must use a searchable picker/autocomplete, not a long static dropdown.
7. Inventory items must carry both `defaultCost` and `defaultPrice`; sales documents should default line pricing from the selected item `defaultPrice`. 7. Inventory items must carry both `defaultCost` and `defaultPrice`; sales documents should default line pricing from the selected item `defaultPrice`.
8. Maintain the denser UI baseline on active screens; avoid reintroducing oversized `px-4 py-3` style controls, tall action bars, or overly loose card spacing without a specific reason. 8. Maintain the denser UI baseline on active screens; avoid reintroducing oversized `px-4 py-3` style controls, tall action bars, or overly loose card spacing without a specific reason.
9. Treat the landing page as `Dashboard`: a metric-oriented, modular command surface that should accumulate reusable operational panels over time.
## Operational notes ## Operational notes
@@ -36,6 +37,7 @@ This repository implements the platform foundation milestone:
- Back up the whole `/app/data` volume to capture both the database and attachments. - Back up the whole `/app/data` volume to capture both the database and attachments.
- Treat searchable lookup as a standing UX requirement for inventory, BOM, sales, purchasing, manufacturing, customer, vendor, and other operational record-picking flows. Filter-only controls can still use dropdowns. - Treat searchable lookup as a standing UX requirement for inventory, BOM, sales, purchasing, manufacturing, customer, vendor, and other operational record-picking flows. Filter-only controls can still use dropdowns.
- Extend the existing Puppeteer document pipeline when adding customer-facing or logistics PDFs instead of creating a parallel export mechanism. - Extend the existing Puppeteer document pipeline when adding customer-facing or logistics PDFs instead of creating a parallel export mechanism.
- Add future dashboard features as modular metric/action panels instead of one-off hero sections or static marketing-style content.
## Next roadmap candidates ## Next roadmap candidates

View File

@@ -18,6 +18,7 @@ Current foundation scope includes:
Current completed foundation areas: Current completed foundation areas:
- dashboard foundation
- CRM foundation - CRM foundation
- inventory foundation - inventory foundation
- sales foundation - sales foundation
@@ -41,6 +42,13 @@ Revisit / deferred items:
- inventory transfers, reservations, and deeper stock controls - inventory transfers, reservations, and deeper stock controls
- deeper audit-trail coverage - deeper audit-trail coverage
Dashboard direction:
- the landing page is now `Dashboard`, not `Overview`
- it should remain a metric-oriented operational surface rather than a generic welcome page
- new modules should add reusable dashboard cards/panels instead of replacing the whole layout
- future additions should emphasize relevant metrics, next actions, alerts, and workflow shortcuts
## Workspace ## Workspace
- `client`: React, Vite, Tailwind frontend - `client`: React, Vite, Tailwind frontend
@@ -227,8 +235,9 @@ Recent roadmap-driving migrations should always be applied before validating new
## UI Notes ## UI Notes
- Dark mode persistence is handled through the frontend theme provider and should remain stable across page navigation. - Dark mode persistence is handled through the frontend theme provider and should remain stable across page navigation.
- The shell layout is tuned for wider desktop use than the original foundation build, and now exposes CRM, inventory, sales, shipping, settings, and planning modules from the same app shell. - The shell layout is tuned for wider desktop use than the original foundation build, and now exposes Dashboard, CRM, inventory, sales, shipping, settings, and planning modules from the same app shell.
- The active module screens now follow a tighter density baseline for forms, tables, and detail cards. - The active module screens now follow a tighter density baseline for forms, tables, and detail cards.
- The dashboard should continue evolving as a modular metric board for future purchasing, shipping, manufacturing, and audit data.
- The client build still emits a Vite chunk-size warning because the app has not been code-split yet. - The client build still emits a Vite chunk-size warning because the app has not been code-split yet.
## PDF Generation ## PDF Generation

View File

@@ -45,6 +45,15 @@ MRP Codex is being built as a streamlined, modular manufacturing resource planni
- CRM reporting is now functional, but broader account-role depth and downstream document rollups can still evolve later - CRM reporting is now functional, but broader account-role depth and downstream document rollups can still evolve later
- Purchasing documents are not yet implemented - Purchasing documents are not yet implemented
- The current sales/shipping foundation still does not include approvals, revisions, shipment labels, or broader branded transactional PDF coverage beyond packing slips - The current sales/shipping foundation still does not include approvals, revisions, shipment labels, or broader branded transactional PDF coverage beyond packing slips
- The dashboard is now metric-oriented, but still needs live module-fed KPIs, alerts, and exception reporting as more transactional depth is added
## Dashboard Plan
- Keep `Dashboard` as the primary landing surface for operators
- Expand it by modular panels rather than redesigning it for each new feature phase
- Prefer metric cards, exception queues, action shortcuts, and status summaries over static descriptive content
- Add future widgets for purchasing, shipping exceptions, inventory shortages, manufacturing load, and audit/system health
- Treat dashboard modules as upgradeable blocks that can be reordered or expanded without disturbing the shell
## Planned feature phases ## Planned feature phases
@@ -160,6 +169,7 @@ QOL subfeatures:
- CRM document rollups and broader account-role depth were deferred until more downstream modules exist - CRM document rollups and broader account-role depth were deferred until more downstream modules exist
- Audit-trail depth is still thin outside the current record/update flows - Audit-trail depth is still thin outside the current record/update flows
- Some generated document and workflow screens still need additional polish for dense, keyboard-efficient operational use - Some generated document and workflow screens still need additional polish for dense, keyboard-efficient operational use
- Dashboard cards are still mostly structural and should be revisited once more live operational data exists
## Cross-cutting improvements ## Cross-cutting improvements

View File

@@ -15,6 +15,7 @@
- Keep reusable UI primitives in `src/components`. - Keep reusable UI primitives in `src/components`.
- Theme state and brand tokens belong in `src/theme`. - Theme state and brand tokens belong in `src/theme`.
- PDF screen components must remain separate from API-rendered document templates. - PDF screen components must remain separate from API-rendered document templates.
- Treat `src/modules/dashboard` as a long-lived operational module. New high-level KPI, alert, queue, and shortcut surfaces should compose into it rather than spawning disconnected landing pages.
- Any non-filter lookup UI must be implemented as a searchable picker or autocomplete; do not use long static dropdowns for operational datasets such as items, customers, vendors, or document-linked records. - Any non-filter lookup UI must be implemented as a searchable picker or autocomplete; do not use long static dropdowns for operational datasets such as items, customers, vendors, or document-linked records.
- Inventory items expose both cost and sell price. Downstream sales document entry should default from the item price field rather than requiring duplicate price maintenance. - Inventory items expose both cost and sell price. Downstream sales document entry should default from the item price field rather than requiring duplicate price maintenance.
- Shipping, sales, and future purchasing PDFs should be rendered through the backend documents module and shared Puppeteer pipeline rather than ad hoc frontend-only exports. - Shipping, sales, and future purchasing PDFs should be rendered through the backend documents module and shared Puppeteer pipeline rather than ad hoc frontend-only exports.

View File

@@ -4,7 +4,7 @@ import { useAuth } from "../auth/AuthProvider";
import { ThemeToggle } from "./ThemeToggle"; import { ThemeToggle } from "./ThemeToggle";
const links = [ const links = [
{ to: "/", label: "Overview" }, { to: "/", label: "Dashboard" },
{ to: "/settings/company", label: "Company Settings" }, { to: "/settings/company", label: "Company Settings" },
{ to: "/crm/customers", label: "Customers" }, { to: "/crm/customers", label: "Customers" },
{ to: "/crm/vendors", label: "Vendors" }, { to: "/crm/vendors", label: "Vendors" },

View File

@@ -1,39 +1,137 @@
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
export function DashboardPage() { export function DashboardPage() {
const metricCards = [
{ label: "CRM Scope", value: "Complete", detail: "Customers, vendors, hierarchy, contacts, attachments", tone: "border-emerald-400/30 bg-emerald-500/12 text-emerald-700 dark:text-emerald-300" },
{ label: "Inventory", value: "Live", detail: "Items, BOMs, warehouses, stock, transactions", tone: "border-sky-400/30 bg-sky-500/12 text-sky-700 dark:text-sky-300" },
{ label: "Sales", value: "Active", detail: "Quotes, orders, totals, reseller pricing defaults", tone: "border-amber-400/30 bg-amber-500/12 text-amber-700 dark:text-amber-300" },
{ label: "Shipping", value: "Online", detail: "Shipments, status flow, packing-slip PDFs", tone: "border-brand/30 bg-brand/10 text-brand" },
];
const modulePanels = [
{
title: "Commercial",
eyebrow: "Revenue Flow",
summary: "Quotes and sales orders now support item pricing, discount, tax, freight, and conversion workflows.",
metrics: [
{ label: "Quote -> SO", value: "Enabled" },
{ label: "Totals Logic", value: "Live" },
{ label: "Customer Lookup", value: "Searchable" },
],
links: [
{ label: "Open quotes", to: "/sales/quotes" },
{ label: "Open sales orders", to: "/sales/orders" },
],
},
{
title: "Operations",
eyebrow: "Stock + Ship",
summary: "Inventory and shipping now share a usable operational path from item master through shipment paperwork.",
metrics: [
{ label: "On-Hand", value: "Tracked" },
{ label: "Shipments", value: "Linked" },
{ label: "Packing Slips", value: "Ready" },
],
links: [
{ label: "Open inventory", to: "/inventory/items" },
{ label: "Open shipments", to: "/shipping/shipments" },
],
},
{
title: "Planning",
eyebrow: "Next Layer",
summary: "The dashboard is now intended as a modular command surface for future purchasing, manufacturing, and execution metrics.",
metrics: [
{ label: "PO Module", value: "Next" },
{ label: "Gantt", value: "Preview" },
{ label: "Audit", value: "Pending" },
],
links: [
{ label: "Open gantt", to: "/planning/gantt" },
{ label: "Company settings", to: "/settings/company" },
],
},
];
const futureModules = [
"Purchasing queue and supplier receipts",
"Shipment labels and bills of lading",
"Manufacturing schedule and bottleneck metrics",
"Audit and system-health diagnostics",
];
return ( return (
<div className="grid gap-4 xl:grid-cols-[1.15fr_0.85fr]"> <div className="space-y-4">
<section className="rounded-[28px] border border-line/70 bg-surface/90 p-4 shadow-panel backdrop-blur"> <section className="overflow-hidden rounded-[30px] border border-line/70 bg-surface/90 shadow-panel backdrop-blur">
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Foundation Status</p> <div className="grid gap-0 xl:grid-cols-[1.35fr_0.65fr]">
<h3 className="mt-2 text-xl font-bold text-text">Platform primitives are online.</h3> <div className="relative overflow-hidden p-5 2xl:p-6">
<p className="mt-3 max-w-2xl text-sm leading-6 text-muted"> <div className="absolute inset-0 bg-[radial-gradient(circle_at_top_left,_rgba(24,90,219,0.16),_transparent_44%),linear-gradient(135deg,rgba(255,255,255,0.06),transparent)]" />
Authentication, RBAC, runtime branding, attachment storage, Docker deployment, and a planning visualization wrapper are now structured for future domain expansion. <div className="relative">
</p> <p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Dashboard</p>
<div className="mt-8 flex flex-wrap gap-3"> <h3 className="mt-2 max-w-3xl text-2xl font-extrabold text-text">Operational command surface for metrics, movement, and next actions.</h3>
<Link className="rounded-2xl bg-brand px-3 py-2 text-sm font-semibold text-white" to="/settings/company"> <p className="mt-3 max-w-3xl text-sm leading-6 text-muted">
Manage company profile This dashboard is now the primary landing surface for the platform. It is intended to stay modular as purchasing, manufacturing, shipping, and audit metrics are added in future slices.
</Link> </p>
<Link className="rounded-2xl border border-line/70 px-3 py-2 text-sm font-semibold text-text" to="/inventory/items"> <div className="mt-6 flex flex-wrap gap-3">
Open inventory <Link className="rounded-2xl bg-brand px-3 py-2 text-sm font-semibold text-white" to="/sales/orders">
</Link> Open sales orders
<Link className="rounded-2xl border border-line/70 px-3 py-2 text-sm font-semibold text-text" to="/planning/gantt"> </Link>
Open gantt preview <Link className="rounded-2xl border border-line/70 px-3 py-2 text-sm font-semibold text-text" to="/shipping/shipments">
</Link> Open shipments
</Link>
<Link className="rounded-2xl border border-line/70 px-3 py-2 text-sm font-semibold text-text" to="/inventory/items">
Open inventory
</Link>
</div>
</div>
</div>
<div className="border-l border-line/70 bg-page/40 p-5 2xl:p-6">
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Upgrade Path</p>
<div className="mt-4 space-y-3">
{futureModules.map((item) => (
<div key={item} className="rounded-2xl border border-line/70 bg-surface/80 px-2 py-2 text-sm text-text">
{item}
</div>
))}
</div>
</div>
</div> </div>
</section> </section>
<section className="rounded-[28px] border border-line/70 bg-surface/90 p-4 shadow-panel backdrop-blur"> <section className="grid gap-3 xl:grid-cols-4">
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">Roadmap</p> {metricCards.map((card) => (
<div className="mt-5 space-y-4"> <article key={card.label} className="rounded-[24px] border border-line/70 bg-surface/90 px-3 py-3 shadow-panel">
{[ <p className="text-xs font-semibold uppercase tracking-[0.18em] text-muted">{card.label}</p>
"CRM reference entities are seeded and available via protected APIs.", <div className="mt-2 flex items-center justify-between gap-3">
"Company Settings drives runtime brand tokens and PDF identity.", <div className="text-xl font-extrabold text-text">{card.value}</div>
"Inventory item master and BOM records now have a dedicated protected module.", <span className={`rounded-full px-2 py-1 text-xs font-semibold ${card.tone}`}>Live</span>
].map((item) => (
<div key={item} className="rounded-2xl border border-line/70 bg-page/70 px-2 py-2 text-sm text-text">
{item}
</div> </div>
))} <p className="mt-2 text-sm text-muted">{card.detail}</p>
</div> </article>
))}
</section>
<section className="grid gap-3 xl:grid-cols-3">
{modulePanels.map((panel) => (
<article key={panel.title} className="rounded-[28px] border border-line/70 bg-surface/90 p-4 shadow-panel 2xl:p-5">
<p className="text-xs font-semibold uppercase tracking-[0.24em] text-muted">{panel.eyebrow}</p>
<h4 className="mt-2 text-lg font-bold text-text">{panel.title}</h4>
<p className="mt-3 text-sm leading-6 text-muted">{panel.summary}</p>
<div className="mt-5 grid gap-2">
{panel.metrics.map((metric) => (
<div key={metric.label} className="flex items-center justify-between rounded-2xl border border-line/70 bg-page/60 px-2 py-2 text-sm">
<span className="text-muted">{metric.label}</span>
<span className="font-semibold text-text">{metric.value}</span>
</div>
))}
</div>
<div className="mt-5 flex flex-wrap gap-2">
{panel.links.map((link) => (
<Link key={link.to} to={link.to} className="rounded-2xl border border-line/70 px-2 py-2 text-sm font-semibold text-text">
{link.label}
</Link>
))}
</div>
</article>
))}
</section> </section>
</div> </div>
); );