Spaces:
Sleeping
Sleeping
Download src/components/Shell.tsx from brestok/supplier-segmentation: direct link, hf CLI and curl.
- Browser
- Download file 3.34 kB
-
https://huggingface.co/spaces/brestok/supplier-segmentation/resolve/main/src/components/Shell.tsx
- Command line
-
hf download hf://spaces/brestok/supplier-segmentation/src/components/Shell.tsx
-
curl -L -o Shell.tsx https://huggingface.co/spaces/brestok/supplier-segmentation/resolve/main/src/components/Shell.tsx
3.34 kB
| import React, { useState } from 'react'; | |
| import { ReferenceDataStatus } from '../api/types'; | |
| import { formatDate, formatNumber } from '../lib/format'; | |
| import { CodeCheckDialog } from './CodeCheckDialog'; | |
| /** | |
| * The chapters in scope (06–08, 22, 61–62, 84–85) hold about 5 800 TARIC | |
| * positions. Anything far below that is the demo seed, and a pack checked | |
| * against it comes back red for reasons that have nothing to do with the pack. | |
| */ | |
| const REAL_NOMENCLATURE_FLOOR = 1000; | |
| export function Header({ status }: { status: ReferenceDataStatus | null }) { | |
| const [checkOpen, setCheckOpen] = useState(false); | |
| return ( | |
| <header className="flex h-20 items-center justify-between gap-4 border-b border-line-header bg-white px-[6%] max-[560px]:h-16"> | |
| <div className="text-2xl font-[750] tracking-[-1px]"> | |
| Cargo<span className="text-brand-accent">Flow</span> | |
| </div> | |
| <div className="flex items-center gap-3"> | |
| <button | |
| type="button" | |
| onClick={() => setCheckOpen(true)} | |
| className="rounded-[20px] border border-line-header px-[11px] py-[5px] text-xs text-slate-chipText hover:bg-slate-50" | |
| > | |
| Check code | |
| </button> | |
| <ReferenceChip status={status} /> | |
| </div> | |
| <CodeCheckDialog open={checkOpen} onClose={() => setCheckOpen(false)} /> | |
| </header> | |
| ); | |
| } | |
| function ReferenceChip({ status }: { status: ReferenceDataStatus | null }) { | |
| if (status === null) { | |
| return ( | |
| <span className="rounded-[20px] bg-slate-chip px-[11px] py-[5px] text-xs text-slate-chipText"> | |
| Checking reference data… | |
| </span> | |
| ); | |
| } | |
| const nomenclature = status.counts.nomenclature ?? 0; | |
| const measures = status.counts.measures ?? 0; | |
| const detail = Object.entries(status.counts) | |
| .map(([name, count]) => `${name}: ${formatNumber(count, 0)}`) | |
| .join(' · '); | |
| if (nomenclature === 0) { | |
| return ( | |
| <Chip tone="red" title={detail}> | |
| No reference data loaded | |
| </Chip> | |
| ); | |
| } | |
| if (nomenclature < REAL_NOMENCLATURE_FLOOR) { | |
| return ( | |
| <Chip tone="amber" title={detail}> | |
| Demo data only — {formatNumber(nomenclature, 0)} codes, {formatNumber(measures, 0)}{' '} | |
| measures | |
| </Chip> | |
| ); | |
| } | |
| return ( | |
| <Chip tone="plain" title={detail}> | |
| TARIC as of {formatDate(status.referenceAsOf)} · {formatNumber(nomenclature, 0)} codes | |
| </Chip> | |
| ); | |
| } | |
| function Chip({ | |
| tone, | |
| title, | |
| children, | |
| }: { | |
| tone: 'plain' | 'amber' | 'red'; | |
| title: string; | |
| children: React.ReactNode; | |
| }) { | |
| const classes = { | |
| plain: 'bg-slate-chip text-slate-chipText', | |
| amber: 'border border-confidence-amberLine bg-confidence-amberBg text-confidence-amber', | |
| red: 'border border-confidence-redLine bg-confidence-redBg text-confidence-red', | |
| }[tone]; | |
| return ( | |
| <span | |
| title={title} | |
| className={`shrink-0 rounded-[20px] px-[11px] py-[5px] text-xs ${classes}`} | |
| > | |
| {children} | |
| </span> | |
| ); | |
| } | |
| export function Footer() { | |
| return ( | |
| <footer className="my-6 text-center text-[11px] text-slate-foot"> | |
| The declarant stays in control · Deterministic check against reference data, not | |
| customs advice. | |
| </footer> | |
| ); | |
| } | |
| export function Card({ children }: { children: React.ReactNode }) { | |
| return <div className="cf-card">{children}</div>; | |
| } | |