11/**
2- * Packs detail aside: source-safe overview, measurements, states, accounting,
3- * governance, and proof roots for the selected PackActivity row.
2+ * Packs detail aside shell: overview, measurements, then section units
3+ * (states, accounting, governance, proof roots) for the selected row.
44 */
55"use client" ;
66
77import React from "react" ;
88import { ShieldCheck } from "lucide-react" ;
9- import {
10- ProductRouteProofDetail ,
11- ProductRouteStatePanel ,
12- } from "@/components/bitcode/routes/ProductRouteShell/ProductRouteShell" ;
9+ import { ProductRouteStatePanel } from "@/components/bitcode/routes/ProductRouteShell/ProductRouteShell" ;
1310import type { PackActivityDetailProjection } from "@/components/bitcode/activity/PackActivityModel/pack-activity-model" ;
1411import {
15- formatSats ,
1612 formatTimestamp ,
1713 formatType ,
18- statusPill ,
1914} from "@/components/packs/models/packs-format" ;
20- import { PacksDetailSection as DetailSection } from "@/components/packs/PacksDetailSection/PacksDetailSection" ;
15+ import { PacksDetailSection } from "@/components/packs/PacksDetailSection/PacksDetailSection" ;
16+ import { PacksActivityDetailStates } from "@/components/packs/PacksActivityDetailStates/PacksActivityDetailStates" ;
17+ import { PacksActivityDetailAccounting } from "@/components/packs/PacksActivityDetailAccounting/PacksActivityDetailAccounting" ;
18+ import { PacksActivityDetailGovernance } from "@/components/packs/PacksActivityDetailGovernance/PacksActivityDetailGovernance" ;
19+ import { PacksActivityDetailProofRoots } from "@/components/packs/PacksActivityDetailProofRoots/PacksActivityDetailProofRoots" ;
2120
2221export type PacksActivityDetailProps = {
2322 detail : PackActivityDetailProjection | null ;
@@ -54,7 +53,7 @@ export function PacksActivityDetail({ detail }: PacksActivityDetailProps) {
5453 </ p >
5554 </ div >
5655
57- < DetailSection title = "Overview" >
56+ < PacksDetailSection title = "Overview" >
5857 < dl className = "grid gap-3 text-sm tablet:grid-cols-2" >
5958 < div >
6059 < dt className = "text-neutral-500" > Type</ dt >
@@ -81,9 +80,9 @@ export function PacksActivityDetail({ detail }: PacksActivityDetailProps) {
8180 </ dd >
8281 </ div >
8382 </ dl >
84- </ DetailSection >
83+ </ PacksDetailSection >
8584
86- < DetailSection title = "Measurements" >
85+ < PacksDetailSection title = "Measurements" >
8786 < div className = "grid gap-2" >
8887 { detail . measurements . length ? (
8988 detail . measurements . map ( ( measurement ) => (
@@ -103,184 +102,19 @@ export function PacksActivityDetail({ detail }: PacksActivityDetailProps) {
103102 </ p >
104103 ) }
105104 </ div >
106- </ DetailSection >
105+ </ PacksDetailSection >
107106
108- < DetailSection title = "State readback" >
109- < div className = "grid gap-2 text-sm" >
110- < div className = "flex items-center justify-between gap-3" >
111- { statusPill ( detail . states . settlement , "settlement not recorded" ) }
112- </ div >
113- < div className = "flex items-center justify-between gap-3" >
114- { statusPill ( detail . states . rights , "BTD rights not recorded" ) }
115- </ div >
116- < div className = "flex items-center justify-between gap-3" >
117- { statusPill (
118- detail . states . compensation ,
119- "compensation not recorded" ,
120- ) }
121- </ div >
122- < div className = "flex items-center justify-between gap-3" >
123- { statusPill ( detail . states . delivery , "delivery not recorded" ) }
124- </ div >
125- < div className = "flex items-center justify-between gap-3" >
126- { statusPill ( detail . states . repair , "repair not recorded" ) }
127- </ div >
128- </ div >
129- </ DetailSection >
107+ < PacksActivityDetailStates detail = { detail } />
130108
131- { detail . commodityState ?. repairRequired ||
132- detail . commodityState ?. blockers ?. length ? (
133- < DetailSection title = "Repair surface" >
134- < div className = "grid gap-2 text-sm" >
135- < div className = "flex items-center justify-between gap-3" >
136- { statusPill (
137- detail . states . repair || "repair-required" ,
138- "repair posture pending" ,
139- ) }
140- </ div >
141- < ul className = "grid gap-1 text-xs text-neutral-400" >
142- { ( detail . commodityState ?. blockers || [ ] ) . map ( ( blocker ) => (
143- < li key = { blocker } className = "break-words" >
144- { blocker }
145- </ li >
146- ) ) }
147- </ ul >
148- < p className = "text-xs text-neutral-500" >
149- State advances only through proof-backed readback; repair fails
150- closed until the missing or contradictory evidence above is
151- reconciled.
152- </ p >
153- </ div >
154- </ DetailSection >
109+ { detail . accounting ? (
110+ < PacksActivityDetailAccounting accounting = { detail . accounting } />
155111 ) : null }
156112
157- { detail . accounting && (
158- < DetailSection title = "Accounting" >
159- < dl className = "grid gap-3 text-sm tablet:grid-cols-2" >
160- < div >
161- < dt className = "text-neutral-500" > BTD/BTC state</ dt >
162- < dd className = "mt-1 text-neutral-100" >
163- { detail . accounting . state || "not recorded" }
164- </ dd >
165- </ div >
166- < div >
167- < dt className = "text-neutral-500" > BTD range</ dt >
168- < dd className = "mt-1 text-neutral-100" >
169- { detail . accounting . btdRangeState || "not recorded" }
170- </ dd >
171- </ div >
172- < div >
173- < dt className = "text-neutral-500" > BTC settlement</ dt >
174- < dd className = "mt-1 text-neutral-100" >
175- { detail . accounting . btcSettlementState || "not recorded" }
176- </ dd >
177- </ div >
178- < div >
179- < dt className = "text-neutral-500" > Treasury route</ dt >
180- < dd className = "mt-1 text-neutral-100" >
181- { detail . accounting . treasuryRouteState || "not recorded" }
182- </ dd >
183- </ div >
184- < div >
185- < dt className = "text-neutral-500" > Contributors</ dt >
186- < dd className = "mt-1 font-mono text-neutral-100" >
187- { detail . accounting . contributorCount }
188- </ dd >
189- </ div >
190- < div >
191- < dt className = "text-neutral-500" > Allocated</ dt >
192- < dd className = "mt-1 font-mono text-neutral-100" >
193- { formatSats ( detail . accounting . allocatedContributorSats ) }
194- </ dd >
195- </ div >
196- { detail . accounting . statementRoot && (
197- < div className = "tablet:col-span-2" >
198- < dt className = "text-neutral-500" > Accounting root</ dt >
199- < dd className = "mt-1 break-all font-mono text-xs text-emerald-100" >
200- { detail . accounting . statementRoot }
201- </ dd >
202- </ div >
203- ) }
204- </ dl >
205- </ DetailSection >
206- ) }
207-
208- { detail . governance && (
209- < DetailSection title = "Governance" >
210- < dl className = "grid gap-3 text-sm tablet:grid-cols-2" >
211- < div >
212- < dt className = "text-neutral-500" > Authority</ dt >
213- < dd className = "mt-1 text-neutral-100" >
214- { detail . governance . state || "not recorded" }
215- </ dd >
216- </ div >
217- < div >
218- < dt className = "text-neutral-500" > Route</ dt >
219- < dd className = "mt-1 text-neutral-100" >
220- { detail . governance . route || "not recorded" }
221- </ dd >
222- </ div >
223- < div >
224- < dt className = "text-neutral-500" > Wallet</ dt >
225- < dd className = "mt-1 text-neutral-100" >
226- { detail . governance . walletState || "not recorded" }
227- </ dd >
228- </ div >
229- < div >
230- < dt className = "text-neutral-500" > Spend</ dt >
231- < dd className = "mt-1 text-neutral-100" >
232- { detail . governance . spendState || "not recorded" }
233- </ dd >
234- </ div >
235- < div >
236- < dt className = "text-neutral-500" > Deposit</ dt >
237- < dd className = "mt-1 text-neutral-100" >
238- { detail . governance . depositState || "not recorded" }
239- </ dd >
240- </ div >
241- < div >
242- < dt className = "text-neutral-500" > Required denials</ dt >
243- < dd className = "mt-1 font-mono text-neutral-100" >
244- { detail . governance . requiredDeniedActionCount }
245- </ dd >
246- </ div >
247- { detail . governance . authorityRoot && (
248- < div className = "tablet:col-span-2" >
249- < dt className = "text-neutral-500" > Authority root</ dt >
250- < dd className = "mt-1 break-all font-mono text-xs text-emerald-100" >
251- { detail . governance . authorityRoot }
252- </ dd >
253- </ div >
254- ) }
255- </ dl >
256- </ DetailSection >
257- ) }
113+ { detail . governance ? (
114+ < PacksActivityDetailGovernance governance = { detail . governance } />
115+ ) : null }
258116
259- < DetailSection title = "Proof roots" >
260- < ProductRouteProofDetail
261- testId = "packs-expandable-proof-detail"
262- title = "Expandable proof detail"
263- tone = "emerald"
264- defaultOpen
265- roots = { [
266- ...detail . proofRoots . map ( ( proofRoot ) => ( {
267- id : proofRoot . id ,
268- label : proofRoot . label ,
269- root : proofRoot . root ,
270- } ) ) ,
271- {
272- id : "accounting-root" ,
273- label : "Accounting root" ,
274- root : detail . accounting ?. statementRoot ,
275- } ,
276- {
277- id : "authority-root" ,
278- label : "Authority root" ,
279- root : detail . governance ?. authorityRoot ,
280- } ,
281- ] }
282- />
283- </ DetailSection >
117+ < PacksActivityDetailProofRoots detail = { detail } />
284118 </ div >
285119 </ aside >
286120 ) ;
0 commit comments