Download app/frontend/src/App.tsx from ml-intern-explorers/primarydraft: direct link, hf CLI and curl.
- Browser
- Download file 4.71 kB
-
https://huggingface.co/spaces/ml-intern-explorers/primarydraft/resolve/main/app/frontend/src/App.tsx
- Command line
-
hf download hf://spaces/ml-intern-explorers/primarydraft/app/frontend/src/App.tsx
-
curl -L -o App.tsx https://huggingface.co/spaces/ml-intern-explorers/primarydraft/resolve/main/app/frontend/src/App.tsx
4.71 kB
| import { useEffect, useState } from "react"; | |
| import { | |
| Buildings, Stack, FileText, ShieldCheck, SealCheck, Check, | |
| } from "@phosphor-icons/react"; | |
| import { api, type RunSummary } from "./lib/api"; | |
| import { Intake } from "./components/Intake"; | |
| import { CinIntake } from "./components/CinIntake"; | |
| import { Ledger } from "./components/Ledger"; | |
| import { Draft } from "./components/Draft"; | |
| import { Board } from "./components/Board"; | |
| import { Handoff } from "./components/Handoff"; | |
| const STEPS = [ | |
| { id: "intake", label: "Issuer", icon: Buildings }, | |
| { id: "ledger", label: "Disclosure ledger", icon: Stack }, | |
| { id: "draft", label: "Draft", icon: FileText }, | |
| { id: "board", label: "Consistency check", icon: ShieldCheck }, | |
| { id: "handoff", label: "Handoff", icon: SealCheck }, | |
| ] as const; | |
| type StepId = (typeof STEPS)[number]["id"]; | |
| function IntakeTabs({ onStarted }: { onStarted: (r: RunSummary) => void }) { | |
| const [mode, setMode] = useState<"listed" | "cin">("listed"); | |
| return ( | |
| <> | |
| <div className="page-head"> | |
| <h1 className="page">Select an issuer</h1> | |
| <p className="lede"> | |
| A listed company can be found by search and read from its own filing. A company that | |
| has not listed yet has no exchange history at all, so it is identified by its | |
| Corporate Identity Number and its records are the ones it supplies. | |
| </p> | |
| <div className="filters" style={{ marginTop: 12 }}> | |
| <button className="filter" aria-pressed={mode === "listed"} | |
| onClick={() => setMode("listed")}>listed on BSE</button> | |
| <button className="filter" aria-pressed={mode === "cin"} | |
| onClick={() => setMode("cin")}>pre-IPO, by CIN</button> | |
| </div> | |
| </div> | |
| {mode === "listed" ? <Intake onStarted={onStarted} embedded /> | |
| : <CinIntake onStarted={onStarted} />} | |
| </> | |
| ); | |
| } | |
| export function App() { | |
| const [step, setStep] = useState<StepId>("intake"); | |
| const [run, setRun] = useState<RunSummary | null>(null); | |
| const [health, setHealth] = useState<any>(null); | |
| useEffect(() => { api.health().then(setHealth).catch(() => setHealth(null)); }, []); | |
| const reached = (id: StepId) => { | |
| if (!run) return id === "intake"; | |
| return STEPS.findIndex((s) => s.id === id) <= STEPS.findIndex((s) => s.id === step); | |
| }; | |
| return ( | |
| <div className="app"> | |
| <header className="topbar"> | |
| <span className="brand">Primary<b>Draft</b></span> | |
| <span className="brand-sub">the IPO offer document that checks itself</span> | |
| <div className="topbar-right"> | |
| {health && ( | |
| <> | |
| <span className="badge badge-accent">{health.rule_count} deterministic checks</span> | |
| <span className="badge badge-quiet">{health.companies} real BSE SME issuers</span> | |
| <span className="badge badge-quiet"> | |
| narrative AI {health.llm?.enabled ? "on" : "off"} | |
| </span> | |
| </> | |
| )} | |
| </div> | |
| </header> | |
| <nav className="steps" aria-label="Workflow"> | |
| {STEPS.map((s, i) => { | |
| const Icon = s.icon; | |
| const isCurrent = s.id === step; | |
| const done = run !== null && STEPS.findIndex((x) => x.id === step) > i; | |
| return ( | |
| <button | |
| key={s.id} | |
| className={`step${done ? " step-done" : ""}`} | |
| aria-current={isCurrent ? "step" : undefined} | |
| disabled={!reached(s.id)} | |
| onClick={() => reached(s.id) && setStep(s.id)} | |
| > | |
| <span className="step-i">{done ? <Check size={15} weight="bold" /> : <Icon size={15} />}</span> | |
| {s.label} | |
| </button> | |
| ); | |
| })} | |
| {run && ( | |
| <span style={{ | |
| marginLeft: "auto", alignSelf: "center", paddingRight: 8, | |
| fontSize: 12, color: "var(--text-2)", | |
| }}> | |
| {run.company_name} <span className="mono" style={{ fontSize: 11 }}>{run.cin}</span> | |
| </span> | |
| )} | |
| </nav> | |
| <main className="main"> | |
| {step === "intake" && ( | |
| <IntakeTabs onStarted={(r) => { setRun(r); setStep("ledger"); }} /> | |
| )} | |
| {step === "ledger" && run && ( | |
| <Ledger run={run} onNext={() => setStep("draft")} /> | |
| )} | |
| {step === "draft" && run && ( | |
| <Draft run={run} onRunUpdate={setRun} onNext={() => setStep("board")} /> | |
| )} | |
| {step === "board" && run && ( | |
| <Board run={run} onRunUpdate={setRun} onNext={() => setStep("handoff")} /> | |
| )} | |
| {step === "handoff" && run && <Handoff runId={run.id} />} | |
| </main> | |
| </div> | |
| ); | |
| } | |