"use client"; import { useEffect, useState } from "react"; import { AppShell } from "../../components/app-shell"; import { apiFetch } from "@/lib/api"; type TaxReturn = { id: string; taxYear: number; filingType: "individual" | "business"; jurisdictions: string[]; status: "draft" | "ready" | "exported" | "efile_submitted" | "efile_accepted"; summary?: { intake?: TaxIntake; intakeReadiness?: TaxReadiness; eFile?: EFileStatus }; updatedAt: string; documents?: TaxDocument[]; }; type TaxDocument = { id: string; docType: string; metadata?: Record; }; type TaxIntake = { taxpayer: { name?: string; filingStatus?: string; address?: string; }; income: { wages?: number; business?: number; interest?: number; dividends?: number; total?: number; }; deductions: { standard?: boolean; charitable?: number; studentLoanInterest?: number; }; credits: { education?: number; childTax?: number; }; notes?: string; }; type TaxReadiness = { complete: boolean; missingFields: string[]; }; type EFileStatus = { provider?: string; providerMode?: string; submissionId?: string; status?: string; acknowledgementId?: string; lastCheckedAt?: string; }; const emptyIntake: TaxIntake = { taxpayer: { name: "", filingStatus: "Single", address: "" }, income: { wages: 0, business: 0, interest: 0, dividends: 0, total: 0 }, deductions: { standard: true, charitable: 0, studentLoanInterest: 0 }, credits: { education: 0, childTax: 0 }, notes: "", }; export default function TaxPage() { const [returns, setReturns] = useState([]); const [status, setStatus] = useState(""); const [loading, setLoading] = useState(true); const [useSample, setUseSample] = useState(true); const [selectedReturnId, setSelectedReturnId] = useState(""); const [intake, setIntake] = useState(emptyIntake); const [readiness, setReadiness] = useState(null); const [efileConsent, setEfileConsent] = useState(false); const [year, setYear] = useState(new Date().getFullYear()); const [filingType, setFilingType] = useState<"individual" | "business">("individual"); const [jurisdictions, setJurisdictions] = useState(["CA", "NY"]); const sampleProfile = { taxpayer: { name: "John Doe", ssn: "111-22-3333", dob: "1989-04-12", filingStatus: "Single", address: "123 Market St, San Francisco, CA" }, income: { w2: [{ employer: "Northwind Labs", wages: 92000, federalWithheld: 12000 }], interest: [{ payer: "City Bank", amount: 320 }], dividends: [{ payer: "Index Fund", amount: 480 }], selfEmployment: [{ business: "Doe Consulting", income: 28000, expenses: 6400 }] }, deductions: { standard: true, charitable: 600, studentLoanInterest: 900 }, credits: { education: 0, childTax: 0 }, documents: [ { docType: "w2_or_1099", label: "W-2 / 1099 income forms" }, { docType: "interest_and_dividend_forms", label: "1099-INT / 1099-DIV forms" }, { docType: "deduction_support", label: "Deduction support" }, { docType: "identity_information", label: "Identity information" }, { docType: "state_withholding_statement", label: "State withholding statement" }, { docType: "health_insurance_statement", label: "Health insurance 1095-A" } ] }; const states = [ { code: "AL", name: "Alabama" }, { code: "AK", name: "Alaska" }, { code: "AZ", name: "Arizona" }, { code: "AR", name: "Arkansas" }, { code: "CA", name: "California" }, { code: "CO", name: "Colorado" }, { code: "CT", name: "Connecticut" }, { code: "DE", name: "Delaware" }, { code: "FL", name: "Florida" }, { code: "GA", name: "Georgia" }, { code: "HI", name: "Hawaii" }, { code: "ID", name: "Idaho" }, { code: "IL", name: "Illinois" }, { code: "IN", name: "Indiana" }, { code: "IA", name: "Iowa" }, { code: "KS", name: "Kansas" }, { code: "KY", name: "Kentucky" }, { code: "LA", name: "Louisiana" }, { code: "ME", name: "Maine" }, { code: "MD", name: "Maryland" }, { code: "MA", name: "Massachusetts" }, { code: "MI", name: "Michigan" }, { code: "MN", name: "Minnesota" }, { code: "MS", name: "Mississippi" }, { code: "MO", name: "Missouri" }, { code: "MT", name: "Montana" }, { code: "NE", name: "Nebraska" }, { code: "NV", name: "Nevada" }, { code: "NH", name: "New Hampshire" }, { code: "NJ", name: "New Jersey" }, { code: "NM", name: "New Mexico" }, { code: "NY", name: "New York" }, { code: "NC", name: "North Carolina" }, { code: "ND", name: "North Dakota" }, { code: "OH", name: "Ohio" }, { code: "OK", name: "Oklahoma" }, { code: "OR", name: "Oregon" }, { code: "PA", name: "Pennsylvania" }, { code: "RI", name: "Rhode Island" }, { code: "SC", name: "South Carolina" }, { code: "SD", name: "South Dakota" }, { code: "TN", name: "Tennessee" }, { code: "TX", name: "Texas" }, { code: "UT", name: "Utah" }, { code: "VT", name: "Vermont" }, { code: "VA", name: "Virginia" }, { code: "WA", name: "Washington" }, { code: "WV", name: "West Virginia" }, { code: "WI", name: "Wisconsin" }, { code: "WY", name: "Wyoming" } ]; const loadReturns = async () => { setLoading(true); const payload = await apiFetch("/api/tax/returns"); setLoading(false); if (payload.error) { setStatus(payload.error.message ?? "Unable to load returns."); return; } setReturns(payload.data ?? []); if (!selectedReturnId && payload.data?.[0]) { setSelectedReturnId(payload.data[0].id); setIntake({ ...emptyIntake, ...(payload.data[0].summary?.intake ?? {}) }); setReadiness(payload.data[0].summary?.intakeReadiness ?? null); } setStatus(""); }; useEffect(() => { loadReturns().catch(() => { setStatus("Unable to load returns."); }); }, []); const createReturn = async () => { setStatus("Creating return..."); const payload = { taxYear: year, filingType, jurisdictions }; const response = await apiFetch("/api/tax/returns", { method: "POST", body: JSON.stringify(payload) }); if (response.error) { setStatus(response.error?.message ?? "Unable to create return."); return; } if (useSample) { await Promise.all( sampleProfile.documents.map((document) => apiFetch(`/api/tax/returns/${response.data.id}/documents`, { method: "POST", body: JSON.stringify({ docType: document.docType, metadata: { source: "sample", label: document.label, taxpayer: sampleProfile.taxpayer.name }, }), }), ), ); } setStatus("Return created."); await loadReturns(); setSelectedReturnId(response.data.id); if (useSample) { const sampleIntake = intakeFromSample(); setIntake(sampleIntake); await saveIntake(response.data.id, sampleIntake, true); } }; const intakeFromSample = (): TaxIntake => { const wages = sampleProfile.income.w2.reduce((sum, item) => sum + item.wages, 0); const business = sampleProfile.income.selfEmployment.reduce((sum, item) => sum + item.income - item.expenses, 0); const interest = sampleProfile.income.interest.reduce((sum, item) => sum + item.amount, 0); const dividends = sampleProfile.income.dividends.reduce((sum, item) => sum + item.amount, 0); return { taxpayer: { name: sampleProfile.taxpayer.name, filingStatus: sampleProfile.taxpayer.filingStatus, address: sampleProfile.taxpayer.address, }, income: { wages, business, interest, dividends, total: wages + business + interest + dividends }, deductions: sampleProfile.deductions, credits: sampleProfile.credits, notes: "Sample intake generated from John Doe dataset.", }; }; const selectReturn = async (ret: TaxReturn) => { setSelectedReturnId(ret.id); setStatus("Loading intake..."); const response = await apiFetch<{ intake: TaxIntake; readiness: TaxReadiness }>(`/api/tax/returns/${ret.id}/intake`); if (response.error) { setStatus(response.error.message ?? "Unable to load intake."); return; } setIntake({ ...emptyIntake, ...(response.data.intake ?? {}) }); setReadiness(response.data.readiness); setStatus(""); }; const saveIntake = async (returnId = selectedReturnId, nextIntake = intake, submit = false) => { if (!returnId) { setStatus("Select a return before saving intake."); return; } const total = Number(nextIntake.income.wages ?? 0) + Number(nextIntake.income.business ?? 0) + Number(nextIntake.income.interest ?? 0) + Number(nextIntake.income.dividends ?? 0); const normalized = { ...nextIntake, income: { ...nextIntake.income, total } }; setStatus(submit ? "Submitting intake..." : "Saving intake..."); const response = await apiFetch<{ intake: TaxIntake; readiness: TaxReadiness }>(`/api/tax/returns/${returnId}/intake`, { method: "PUT", body: JSON.stringify({ intake: normalized, submit }), }); if (response.error) { setStatus(response.error.message ?? "Unable to save intake."); return; } setIntake(response.data.intake); setReadiness(response.data.readiness); setStatus(submit ? "Intake submitted." : "Intake saved."); await loadReturns(); }; const updateIntake = (section: keyof TaxIntake, key: string, value: string | number | boolean) => { setIntake((current) => ({ ...current, [section]: { ...(current[section] as Record), [key]: value, }, })); }; const exportReturn = async (id: string) => { setStatus("Exporting return..."); const response = await apiFetch<{ return: TaxReturn; documents: unknown[]; }>(`/api/tax/returns/${id}/export`, { method: "POST" }); if (response.error) { setStatus(response.error?.message ?? "Export failed."); return; } const blob = new Blob([JSON.stringify(response.data, null, 2)], { type: "application/json" }); const url = URL.createObjectURL(blob); window.open(url, "_blank", "noopener,noreferrer"); setStatus("Export ready."); await loadReturns(); }; const submitEFile = async (id: string) => { setStatus("Submitting e-file package..."); const response = await apiFetch<{ eFile: EFileStatus }>(`/api/tax/returns/${id}/efile`, { method: "POST", body: JSON.stringify({ consentAccepted: efileConsent }), }); if (response.error) { setStatus(response.error?.message ?? "E-file submission failed."); return; } setStatus(`E-file submitted to ${response.data.eFile.provider ?? "provider"}.`); await loadReturns(); }; const refreshEFileStatus = async (id: string) => { setStatus("Checking e-file status..."); const response = await apiFetch<{ eFile?: EFileStatus; status?: string }>(`/api/tax/returns/${id}/efile`); if (response.error) { setStatus(response.error?.message ?? "Unable to check e-file status."); return; } setStatus(response.data.eFile?.status ? `E-file status: ${response.data.eFile.status}.` : "Return has not been e-filed."); await loadReturns(); }; return (

Create a return

Sample dataset

Use John Doe sample intake data.

{useSample ? (

W-2 wages: $92,000 - 1099-NEC: $28,000

Standard deduction - CA + NY filings

) : null}
setYear(Number(event.target.value))} />

Hold Ctrl/Command to select multiple states.

Required documents

{sampleProfile.documents.map((doc) => (
{doc.label} Pending
))}
{status ?

{status}

: null}

Your returns

{loading ? (

Loading returns...

) : returns.length ? ( returns.map((ret) => (

{ret.taxYear} - {ret.filingType}

States: {ret.jurisdictions.join(", ")}

{ret.documents?.length ? (

Documents: {ret.documents.length}

) : null}
{ret.status}
{ret.summary?.eFile?.submissionId ? (

E-file: {ret.summary.eFile.status} - {ret.summary.eFile.submissionId}

) : null}
)) ) : (

No returns yet.

)}

Tax intake

Capture taxpayer details, income, deductions, and credits before export.

{readiness ? ( {readiness.complete ? "Ready" : `${readiness.missingFields.length} missing`} ) : null}
{selectedReturnId ? (

Taxpayer

updateIntake("taxpayer", "name", e.target.value)} /> updateIntake("taxpayer", "filingStatus", e.target.value)} /> updateIntake("taxpayer", "address", e.target.value)} />

Income

updateIntake("income", "wages", Number(e.target.value))} /> updateIntake("income", "business", Number(e.target.value))} /> updateIntake("income", "interest", Number(e.target.value))} /> updateIntake("income", "dividends", Number(e.target.value))} />

Deductions / Credits

updateIntake("deductions", "charitable", Number(e.target.value))} /> updateIntake("deductions", "studentLoanInterest", Number(e.target.value))} /> updateIntake("credits", "education", Number(e.target.value))} />

Review