repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
The Living OS cockpit
stars
latest
clone command
git clone gitlawb://did:key:z6Mku78K...XywC/living-os-cockp...git clone gitlawb://did:key:z6Mku78K.../living-os-cockp...59751530feat: surface worker supervisor health in live work8h ago| #1 | 'use client'; |
| #2 | |
| #3 | import Link from 'next/link'; |
| #4 | import type { CSSProperties } from 'react'; |
| #5 | import type { ReactNode } from 'react'; |
| #6 | import { useEffect, useMemo, useState } from 'react'; |
| #7 | import { sameOriginFetch } from '@/lib/client-api'; |
| #8 | import { Download, FileText, PenLine, ShieldCheck, Upload } from 'lucide-react'; |
| #9 | import DocumentSealEmboss from '@/components/DocumentSealEmboss'; |
| #10 | |
| #11 | type ProfileResponse = { |
| #12 | displayName?: string; |
| #13 | trust?: { |
| #14 | name?: string; |
| #15 | id?: string | null; |
| #16 | role?: string | null; |
| #17 | uccFiling?: string | null; |
| #18 | filingState?: string | null; |
| #19 | governingLaw?: string | null; |
| #20 | primaryColor?: string; |
| #21 | secondaryColor?: string; |
| #22 | sealUrl?: string | null; |
| #23 | }; |
| #24 | }; |
| #25 | |
| #26 | type UploadState = { |
| #27 | preview: string | null; |
| #28 | label: string; |
| #29 | }; |
| #30 | |
| #31 | const DEFAULT_DECLARATION = |
| #32 | 'I, the undersigned, being of sound mind and body, do hereby declare and affirm my standing as a living man or living woman, the sole beneficiary and authorized representative of the above-named trust estate. I am not a fictional entity, corporation, or legal fiction created by the State. I reserve all rights without prejudice under UCC 1-308.'; |
| #33 | |
| #34 | function todayLong() { |
| #35 | return new Date().toLocaleDateString('en-US', { |
| #36 | month: 'long', |
| #37 | day: '2-digit', |
| #38 | year: 'numeric', |
| #39 | }); |
| #40 | } |
| #41 | |
| #42 | function initials(name?: string) { |
| #43 | return (name || 'Member') |
| #44 | .split(/\s+/) |
| #45 | .filter(Boolean) |
| #46 | .slice(0, 2) |
| #47 | .map(part => part[0]?.toUpperCase()) |
| #48 | .join(''); |
| #49 | } |
| #50 | |
| #51 | function FileDrop({ |
| #52 | icon, |
| #53 | label, |
| #54 | hint, |
| #55 | value, |
| #56 | onChange, |
| #57 | }: { |
| #58 | icon: ReactNode; |
| #59 | label: string; |
| #60 | hint: string; |
| #61 | value: UploadState; |
| #62 | onChange: (next: UploadState) => void; |
| #63 | }) { |
| #64 | const handleFile = (file?: File) => { |
| #65 | if (!file) return; |
| #66 | const reader = new FileReader(); |
| #67 | reader.onload = event => onChange({ preview: String(event.target?.result || ''), label: file.name }); |
| #68 | reader.readAsDataURL(file); |
| #69 | }; |
| #70 | |
| #71 | return ( |
| #72 | <label className="affidavit-file-drop"> |
| #73 | <input |
| #74 | type="file" |
| #75 | accept="image/*" |
| #76 | onChange={event => handleFile(event.target.files?.[0])} |
| #77 | /> |
| #78 | {value.preview ? ( |
| #79 | <span className="affidavit-upload-preview"> |
| #80 | <img src={value.preview} alt={label} /> |
| #81 | <span>{value.label}</span> |
| #82 | </span> |
| #83 | ) : ( |
| #84 | <span className="affidavit-upload-empty"> |
| #85 | {icon} |
| #86 | <strong>{label}</strong> |
| #87 | <small>{hint}</small> |
| #88 | </span> |
| #89 | )} |
| #90 | </label> |
| #91 | ); |
| #92 | } |
| #93 | |
| #94 | export default function AffidavitIdentityPage() { |
| #95 | const [profile, setProfile] = useState<ProfileResponse | null>(null); |
| #96 | const [loadedProfile, setLoadedProfile] = useState(false); |
| #97 | const [generated, setGenerated] = useState(false); |
| #98 | const [embossing, setEmbossing] = useState(false); |
| #99 | const [form, setForm] = useState({ |
| #100 | fullName: 'King Bau', |
| #101 | dob: '', |
| #102 | placeOfBirth: '', |
| #103 | domicileAddress: '', |
| #104 | trustName: 'House of Edinburgh Private Express Trust', |
| #105 | trustId: 'HED-TRUST-2025-001', |
| #106 | trusteeRole: 'King Bau, Trustee', |
| #107 | uccFiling: '20250137020X', |
| #108 | filingState: 'Texas', |
| #109 | declaration: DEFAULT_DECLARATION, |
| #110 | }); |
| #111 | const [photo, setPhoto] = useState<UploadState>({ preview: null, label: 'Passport photo' }); |
| #112 | const [seal, setSeal] = useState<UploadState>({ preview: null, label: 'Trust seal' }); |
| #113 | const [crest, setCrest] = useState<UploadState>({ preview: null, label: 'House emblem' }); |
| #114 | |
| #115 | useEffect(() => { |
| #116 | let alive = true; |
| #117 | sameOriginFetch('/api/profile') |
| #118 | .then(response => response.json()) |
| #119 | .then((data: ProfileResponse) => { |
| #120 | if (!alive) return; |
| #121 | setProfile(data); |
| #122 | const trust = data.trust || {}; |
| #123 | setForm(previous => ({ |
| #124 | ...previous, |
| #125 | fullName: data.displayName || previous.fullName, |
| #126 | trustName: trust.name || previous.trustName, |
| #127 | trustId: trust.id || previous.trustId, |
| #128 | trusteeRole: trust.role || data.displayName || previous.trusteeRole, |
| #129 | uccFiling: trust.uccFiling || previous.uccFiling, |
| #130 | filingState: trust.filingState || previous.filingState, |
| #131 | })); |
| #132 | if (trust.sealUrl) { |
| #133 | setSeal({ preview: trust.sealUrl, label: 'Registered trust seal' }); |
| #134 | setCrest({ preview: trust.sealUrl, label: 'House emblem' }); |
| #135 | } |
| #136 | setLoadedProfile(true); |
| #137 | }) |
| #138 | .catch(() => setLoadedProfile(true)); |
| #139 | return () => { |
| #140 | alive = false; |
| #141 | }; |
| #142 | }, []); |
| #143 | |
| #144 | const trustPrimary = profile?.trust?.primaryColor || '#D4AF37'; |
| #145 | const trustSecondary = profile?.trust?.secondaryColor || '#050505'; |
| #146 | const documentRef = useMemo(() => `AOI-${Date.now().toString(36).toUpperCase()}`, []); |
| #147 | const today = todayLong(); |
| #148 | const generatedStamp = generated |
| #149 | ? new Date().toLocaleString('en-US', { month: 'short', day: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }) |
| #150 | : undefined; |
| #151 | const completeEnough = form.fullName.trim() && form.trustName.trim() && form.declaration.trim(); |
| #152 | const style = { |
| #153 | '--affidavit-primary': trustPrimary, |
| #154 | '--affidavit-secondary': trustSecondary, |
| #155 | } as CSSProperties; |
| #156 | |
| #157 | const update = (key: keyof typeof form, value: string) => { |
| #158 | setForm(previous => ({ ...previous, [key]: value })); |
| #159 | }; |
| #160 | |
| #161 | const handleGenerate = () => { |
| #162 | setGenerated(true); |
| #163 | setEmbossing(true); |
| #164 | window.setTimeout(() => { |
| #165 | setEmbossing(false); |
| #166 | window.print(); |
| #167 | }, 900); |
| #168 | }; |
| #169 | |
| #170 | return ( |
| #171 | <main className="affidavit-page" style={style}> |
| #172 | <header className="affidavit-page-header"> |
| #173 | <Link href="/trust/setup" className="trust-back-link">Back to trust setup</Link> |
| #174 | <div> |
| #175 | <p className="trust-eyebrow">Affidavit of Identity</p> |
| #176 | <h1>Universal Affidavit of Identity</h1> |
| #177 | <p> |
| #178 | Build a print-ready sovereign instrument with member trust branding, identity photo, |
| #179 | embossed seal, and notary block. |
| #180 | </p> |
| #181 | </div> |
| #182 | </header> |
| #183 | |
| #184 | <section className="affidavit-workbench"> |
| #185 | <aside className="affidavit-control-panel"> |
| #186 | <div className="affidavit-panel-heading"> |
| #187 | <FileText size={18} /> |
| #188 | <div> |
| #189 | <h2>Walkthrough</h2> |
| #190 | <p>{loadedProfile ? 'Live preview updates as fields change.' : 'Loading profile data...'}</p> |
| #191 | </div> |
| #192 | </div> |
| #193 | |
| #194 | <div className="affidavit-control-group"> |
| #195 | <h3>Images</h3> |
| #196 | <div className="affidavit-upload-grid"> |
| #197 | <FileDrop |
| #198 | icon={<Upload size={18} />} |
| #199 | label="Passport Photo" |
| #200 | hint="Centered, front-facing image" |
| #201 | value={photo} |
| #202 | onChange={setPhoto} |
| #203 | /> |
| #204 | <FileDrop |
| #205 | icon={<ShieldCheck size={18} />} |
| #206 | label="Trust Seal" |
| #207 | hint="Registered seal or generated mark" |
| #208 | value={seal} |
| #209 | onChange={setSeal} |
| #210 | /> |
| #211 | <FileDrop |
| #212 | icon={<PenLine size={18} />} |
| #213 | label="House Emblem" |
| #214 | hint="Crest shown in the header" |
| #215 | value={crest} |
| #216 | onChange={setCrest} |
| #217 | /> |
| #218 | </div> |
| #219 | </div> |
| #220 | |
| #221 | <div className="affidavit-control-group"> |
| #222 | <h3>Declarant</h3> |
| #223 | <label> |
| #224 | Full legal name |
| #225 | <input value={form.fullName} onChange={event => update('fullName', event.target.value)} /> |
| #226 | </label> |
| #227 | <div className="affidavit-two-col"> |
| #228 | <label> |
| #229 | Date of birth |
| #230 | <input type="date" value={form.dob} onChange={event => update('dob', event.target.value)} /> |
| #231 | </label> |
| #232 | <label> |
| #233 | Place of birth |
| #234 | <input value={form.placeOfBirth} onChange={event => update('placeOfBirth', event.target.value)} placeholder="City, State" /> |
| #235 | </label> |
| #236 | </div> |
| #237 | <label> |
| #238 | Domicile address |
| #239 | <input value={form.domicileAddress} onChange={event => update('domicileAddress', event.target.value)} /> |
| #240 | </label> |
| #241 | </div> |
| #242 | |
| #243 | <div className="affidavit-control-group"> |
| #244 | <h3>Trust Estate</h3> |
| #245 | <label> |
| #246 | Trust name |
| #247 | <input value={form.trustName} onChange={event => update('trustName', event.target.value)} /> |
| #248 | </label> |
| #249 | <div className="affidavit-two-col"> |
| #250 | <label> |
| #251 | Trust ID |
| #252 | <input value={form.trustId} onChange={event => update('trustId', event.target.value)} /> |
| #253 | </label> |
| #254 | <label> |
| #255 | UCC filing |
| #256 | <input value={form.uccFiling} onChange={event => update('uccFiling', event.target.value)} /> |
| #257 | </label> |
| #258 | </div> |
| #259 | <label> |
| #260 | Trustee role |
| #261 | <input value={form.trusteeRole} onChange={event => update('trusteeRole', event.target.value)} /> |
| #262 | </label> |
| #263 | </div> |
| #264 | |
| #265 | <div className="affidavit-control-group"> |
| #266 | <h3>Status Declaration</h3> |
| #267 | <textarea |
| #268 | rows={7} |
| #269 | value={form.declaration} |
| #270 | onChange={event => update('declaration', event.target.value)} |
| #271 | /> |
| #272 | </div> |
| #273 | |
| #274 | <button className="affidavit-generate-button" disabled={!completeEnough} onClick={handleGenerate}> |
| #275 | <Download size={17} /> |
| #276 | Generate Print PDF |
| #277 | </button> |
| #278 | {generated && ( |
| #279 | <p className="affidavit-generation-note"> |
| #280 | Seal embossing applied. Use the browser print dialog to save as PDF. |
| #281 | </p> |
| #282 | )} |
| #283 | </aside> |
| #284 | |
| #285 | <section className="affidavit-preview-stage" aria-label="Affidavit live preview"> |
| #286 | <article className={`affidavit-sheet ${embossing ? 'is-embossing' : ''}`}> |
| #287 | <div className="affidavit-sheet-border"> |
| #288 | <header className="affidavit-document-header"> |
| #289 | <div className="affidavit-emblem"> |
| #290 | {crest.preview ? <img src={crest.preview} alt="House emblem" /> : <span>{initials(form.trustName)}</span>} |
| #291 | </div> |
| #292 | <div> |
| #293 | <p>{form.trustName}</p> |
| #294 | <h2>Universal Affidavit of Identity</h2> |
| #295 | <small>Declaration of Living Standing and Trust Authority</small> |
| #296 | </div> |
| #297 | <DocumentSealEmboss |
| #298 | sealUrl={seal.preview} |
| #299 | trustName={form.trustName} |
| #300 | registryNumber={documentRef} |
| #301 | generatedAt={generatedStamp} |
| #302 | placement="affidavit-header" |
| #303 | size="medium" |
| #304 | active={embossing} |
| #305 | className="affidavit-seal-instance" |
| #306 | /> |
| #307 | </header> |
| #308 | |
| #309 | <div className="affidavit-photo-block"> |
| #310 | <div className="affidavit-photo-frame"> |
| #311 | {photo.preview ? <img src={photo.preview} alt="Member portrait" /> : <span>{initials(form.fullName)}</span>} |
| #312 | </div> |
| #313 | <p>Passport-Style Photograph</p> |
| #314 | </div> |
| #315 | |
| #316 | <section className="affidavit-field-section"> |
| #317 | <h3>Personal Identification</h3> |
| #318 | <FieldLine label="Full Legal Name" value={form.fullName} /> |
| #319 | <FieldLine label="Date of Birth" value={form.dob || '[Date of Birth]'} /> |
| #320 | <FieldLine label="Place of Birth" value={form.placeOfBirth || '[Place of Birth]'} /> |
| #321 | <FieldLine label="Domicile Address" value={form.domicileAddress || '[Domicile Address]'} /> |
| #322 | </section> |
| #323 | |
| #324 | <section className="affidavit-field-section"> |
| #325 | <h3>Trust Estate Information</h3> |
| #326 | <FieldLine label="Trust Name" value={form.trustName} /> |
| #327 | <FieldLine label="Trust ID" value={form.trustId || '[Trust ID]'} /> |
| #328 | <FieldLine label="Trustee Capacity" value={form.trusteeRole || '[Trustee]'} /> |
| #329 | <FieldLine label="UCC Filing Number" value={form.uccFiling || '[UCC Filing]'} /> |
| #330 | </section> |
| #331 | |
| #332 | <section className="affidavit-field-section"> |
| #333 | <h3>Declaration of Status</h3> |
| #334 | <p className="affidavit-declaration">{form.declaration}</p> |
| #335 | </section> |
| #336 | |
| #337 | <section className="affidavit-field-section"> |
| #338 | <h3>Attestation</h3> |
| #339 | <p> |
| #340 | I, <strong>{form.fullName || '[Full Legal Name]'}</strong>, do solemnly declare under |
| #341 | penalty of perjury that the foregoing statements are true, correct, and complete to |
| #342 | the best of my knowledge and belief. This affidavit is executed of my own free will |
| #343 | and accord, without duress, coercion, or undue influence of any kind. |
| #344 | </p> |
| #345 | <p>Executed this <strong>{today}</strong>.</p> |
| #346 | </section> |
| #347 | |
| #348 | <section className="affidavit-signature-grid"> |
| #349 | <div> |
| #350 | <span /> |
| #351 | <p>Signature of Declarant: {form.fullName || '[Full Legal Name]'}</p> |
| #352 | <small>All Rights Reserved, UCC 1-308</small> |
| #353 | </div> |
| #354 | <div> |
| #355 | <span /> |
| #356 | <p>{form.trusteeRole || '[Trustee Capacity]'}</p> |
| #357 | <small>Trust authority / capacity</small> |
| #358 | </div> |
| #359 | </section> |
| #360 | |
| #361 | <section className="affidavit-notary-block"> |
| #362 | <h3>Notary Acknowledgment</h3> |
| #363 | <p>State/Republic of: ______________________________</p> |
| #364 | <p>County/Parish of: ______________________________</p> |
| #365 | <p> |
| #366 | On this ______ day of __________________, 20____, before me, the undersigned notary |
| #367 | public, personally appeared <strong>{form.fullName || '[Name]'}</strong>, known to me |
| #368 | or proved to me on the basis of satisfactory evidence to be the person whose name is |
| #369 | subscribed to this instrument, and acknowledged that they executed the same. |
| #370 | </p> |
| #371 | <div className="affidavit-notary-lines"> |
| #372 | <div> |
| #373 | <span /> |
| #374 | <p>Notary Public</p> |
| #375 | </div> |
| #376 | <div> |
| #377 | <span /> |
| #378 | <p>My commission expires</p> |
| #379 | </div> |
| #380 | </div> |
| #381 | </section> |
| #382 | |
| #383 | <footer className="affidavit-footer"> |
| #384 | <span>{form.trustName}</span> |
| #385 | <span>{documentRef}</span> |
| #386 | <span>Page 1 of 1</span> |
| #387 | </footer> |
| #388 | </div> |
| #389 | </article> |
| #390 | </section> |
| #391 | </section> |
| #392 | </main> |
| #393 | ); |
| #394 | } |
| #395 | |
| #396 | function FieldLine({ label, value }: { label: string; value: string }) { |
| #397 | return ( |
| #398 | <div className="affidavit-field-line"> |
| #399 | <strong>{label}:</strong> |
| #400 | <span>{value}</span> |
| #401 | </div> |
| #402 | ); |
| #403 | } |
| #404 |