@classytic/commerce-ui
v1.6.2
Published
Commerce admin UI — the dashboard feature screens (WMS, inventory, procurement, sales, finance…) organized by Flow kernel bounded contexts. Commerce-owned: imports @classytic/commerce-sdk directly, composes @classytic/fluid + host shadcn, mounts inside @c
Downloads
723
Readme
@classytic/commerce-ui
The commerce admin feature UI — the dashboard screens (WMS, inventory, procurement, sales, finance…) that sit inside the neutral dashboard chrome. It's the domain tier of the front-end stack:
@classytic/fluid UI atoms (DataTable, dialogs, document primitives)
@classytic/erp-shell neutral dashboard chrome (shell, auth, branch, guard) ← peer
@classytic/commerce-ui THIS — commerce feature screens + widgets + manifest
<commerce customer app> thin: route re-exports + theme + brand + configWhat it is (and is NOT)
- Commerce-owned, not vertical-neutral. It imports
@classytic/commerce-sdkdirectly — every commerce customer runs the same SDK, so there's no data injection and no port indirection. (A different vertical — hotel, rental — would build its own UI package; the only genuinely shared pieces areerp-shelland, if it ever materialises, a catalog package with a real second consumer. Flow/WMS is commerce-only, so paying a DI tax for hotel reuse it will never use would be premature.) - The reuse axis is N commerce customers, not N verticals. Fix a screen once, bump the version, it lands for every customer deployment. That's the win.
- Ships no UI atoms. It composes the host's shadcn primitives via the
@/alias (external, never bundled) and@classytic/fluid. The host owns the look.
What ships (real inventory)
~35 bounded-context subpaths, ~60 screens. The list/CRUD standard is Tier-1
config-driven on @classytic/erp-shell/resource (server search, URL
pagination, engine sheets); genuinely bespoke surfaces (structural forms,
monitors, documents) stay custom and say why in their header comment.
| Subpath | Screens (highlights) |
|---|---|
| /accounting | accounts · journal-entries · customer-invoices · vendor-bills (FX settlement) · budgets · payment-terms · recurring-invoices · exchange-rates · fiscal-periods · period-close · bank-reconciliation · partner-statement · aging · oversight · posting · overview · reports · cost-gaps |
| /tax/bd | musok (Mushak 6.3) · VAT/TOT returns · AT reconciliation · VDS · withholding · export-refund |
| /admin | users · audit-logs · approval-policies (Tier-1 + structural sheet) · workflows (bg jobs) · email-templates · license |
| /inventory | stock · low-stock · movements · transfers · requests · purchase-orders (async supplier picker) |
| /warehouse | nodes · locations · audit · lots · packages · trace · procurement · replenishment · returns · scrap · dispatch · cost · standard-costs · landed-cost · classification · slotting · labor · waves · quality · tasks · reports |
| /catalog | products · categories · size-guides |
| /sales | rfqs · rmas · blanket-orders |
| /orders /quotations | order + quotation workbenches |
| /partners | suppliers · customers · parties |
| /crm | leads (Tier-1) |
| /loyalty | dashboard · earning-rules · tiers · programs · referrals |
| /pricelists | price lists (Tier-1) |
| /assets /golive | asset register · go-live console |
| /branch /pos-adjacent | branches · members · invitations |
| /cms /media /marketing /promotions | pages · media library · settings · promos |
| /widgets | StockLevelBadge, LocationPicker, … |
| /manifest | the package-owned IA — see below |
Routes are host config — the package is route-agnostic
The package owns no absolute URLs (same rule as branding — the host owns its
route tree). Screens and fragments are factories the host feeds its own routes
into. Routes are passed as plain strings so a Server-Component route file
can hand them straight to a Client screen (functions aren't serializable across
the RSC boundary — a detail: (id) => … override only works from a client mount;
by default detail derives as ${root}/${id}). typedRoutes verification stays in
the host's route registry — Route values are assignable to string.
Mounting (three seams)
1. Screens — inject the host's routes
// app/dashboard/suppliers/page.tsx (Server Component)
import { SuppliersScreen } from "@classytic/commerce-ui/partners";
const SUPPLIER_ROUTES = { root: "/dashboard/suppliers" }; // serializable → RSC-safe
export default function Page() {
return <SuppliersScreen routes={SUPPLIER_ROUTES} />;
}2. Manifest — compose the package-owned IA
/manifest ships fragment factories for every context (commerce, orders,
inventory, warehouse, loyalty, assets, accounting, crm, hq-admin, settings)
plus standardManifestGates() — the canonical gate wiring (sdk role
selectors + the WMS capability ladder). A host manifest is ~300 lines of
composition instead of ~700 lines of copy-paste; both flagship hosts consume
these fragments, so an IA fix lands once and reaches every client:
import {
standardManifestGates,
createCommerceFragment,
createAccountingFragment,
createWarehouseFragment,
} from "@classytic/commerce-ui/manifest";
const gates = standardManifestGates();
export const coreSidebarCategories = [
hostPortalCategory, // host-owned landing surfaces
createCommerceFragment(gates, { parties: "/dashboard/parties" }), // host extras
/* ... */
];
// feature modules: host owns the launcher tile; sidebar = fragment
{ id: "accounting", enabled: true, launcher: hostTile, sidebar: createAccountingFragment(gates) }Every factory takes Partial routes merged over the canonical /dashboard/…
defaults (also exported — ACCOUNTING_DEFAULTS etc. — so in-screen links like
the accounting overview tiles share the SAME URL source as the nav).
3. Widgets
import { StockLevelBadge } from "@classytic/commerce-ui/widgets";
<StockLevelBadge onHand={40} reserved={12} />; // → "28 avail"Host requirements
- Add
@classytic/commerce-ui(and@classytic/fluid,@classytic/erp-shell) totranspilePackages— it ships pre-built ESM carrying"use client". - Provide the shadcn primitives commerce-ui composes under
@/components/ui/*(badge,button,input,label,skeleton, … — stubbed for type-check insrc/types/host.d.ts; the host provides the real ones). - Wrap the dashboard in a React Query provider and mount
<Toaster/>(sonner).
Local dev (cp-dist)
@classytic/erp-shell and @classytic/commerce-sdk are sibling packages consumed
via the cp-dist loop, not fetched from npm during local iteration: build the
source and copy dist/ + package.json into node_modules/@classytic/<pkg>/.
They are peers here (never bundled).
