@lambda-development/erp-core 0.6.14 → 0.6.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/client.d.ts +1 -0
- package/dist/index.js +98 -98
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/api/client.ts","../src/contexts/auth-context.tsx","../src/components/chat/chat-provider.tsx","../src/lib/utils.ts","../src/components/ui/button.tsx","../src/components/ui/input.tsx","../src/components/ui/dialog.tsx","../src/lib/nav.tsx","../src/lib/branding.ts","../src/components/layout/sidebar.tsx","../src/components/layout/app-shell.tsx","../src/components/auth/protected-route.tsx","../src/components/ui/card.tsx","../src/components/ui/badge.tsx","../src/components/document/status-badge.tsx","../src/hooks/use-base-currency.ts","../src/pages/dashboard.tsx","../src/lib/doc-list-context.ts","../src/hooks/use-document-list.ts","../src/hooks/use-url-state.ts","../src/lib/doctypes.ts","../src/components/document/doc-pager.tsx","../src/components/ui/select.tsx","../src/components/ui/hint-tooltip.tsx","../src/components/ui/notes-markup-help.tsx","../src/hooks/use-currencies.ts","../src/pages/documents/document-form.tsx","../src/components/ui/date-range-presets.tsx","../src/pages/documents/document-list.tsx","../src/components/document/link-field.tsx","../src/pages/proposals/proposal-form.tsx","../src/pages/masters/master-list.tsx","../src/pages/masters/master-form.tsx","../src/hooks/use-report.ts","../src/pages/reports/trial-balance.tsx","../src/pages/reports/chart-of-accounts.tsx","../src/pages/reports/general-ledger.tsx","../src/pages/reports/stock-balance.tsx","../src/pages/reports/profit-loss.tsx","../src/pages/reports/balance-sheet.tsx","../src/pages/reports/ar-aging.tsx","../src/pages/reports/ap-aging.tsx","../src/pages/reports/analytics.tsx","../src/pages/setup.tsx","../src/pages/tutorial.tsx","../src/pages/chat.tsx","../src/pages/login.tsx","../src/pages/demo.tsx","../src/pages/opening-balances.tsx","../src/pages/admin/users.tsx","../src/i18n/index.ts","../src/components/ui/language-select.tsx","../src/pages/admin/settings.tsx","../src/lib/component-registry.tsx","../src/routes.tsx","../src/lib/chat-doctype-redirects.tsx","../src/bootstrap.tsx","../src/components/ui/confirm-button.tsx"],"sourcesContent":["// API base URL. Defaults to the relative \"/api\" (the demo app and most\n// deployments serve the frontend and backend from the same origin). A\n// customer deployment can point the published library at a different backend\n// either at build time (VITE_API_BASE) or at runtime before any request is\n// made (configureApiBase).\nlet BASE = (import.meta.env.VITE_API_BASE as string | undefined) ?? \"/api\";\n\nexport function configureApiBase(base: string) {\n BASE = base.replace(/\\/+$/, \"\");\n}\n\n// The API origin as a browser-navigable URL. Social login is a full-page\n// redirect (not a fetch), so the button must point the browser straight at the\n// backend endpoint — resolving BASE (which may be relative like \"/api\") against\n// the current origin.\nexport function apiUrl(path: string): string {\n return new URL(`${BASE}${path}`, window.location.origin).toString();\n}\n\nexport class ApiError extends Error {\n constructor(public status: number, message: string) {\n super(message);\n }\n}\n\nfunction formatErrorDetail(detail: unknown): string {\n if (!detail) return \"Request failed\";\n if (typeof detail === \"string\") return detail;\n if (Array.isArray(detail)) {\n const parts = detail.map((item) => {\n if (!item || typeof item !== \"object\") return String(item);\n const rec = item as Record<string, unknown>;\n const loc = Array.isArray(rec.loc) ? rec.loc.join(\".\") : \"\";\n const msg = typeof rec.msg === \"string\" ? rec.msg : JSON.stringify(rec);\n return loc ? `${loc}: ${msg}` : msg;\n });\n return parts.join(\"; \");\n }\n if (typeof detail === \"object\") {\n const rec = detail as Record<string, unknown>;\n if (typeof rec.msg === \"string\") return rec.msg;\n return JSON.stringify(detail);\n }\n return String(detail);\n}\n\nexport async function request<T>(path: string, options?: RequestInit): Promise<T> {\n const res = await fetch(`${BASE}${path}`, {\n headers: { \"Content-Type\": \"application/json\" },\n credentials: \"include\",\n ...options,\n });\n if (!res.ok) {\n if (res.status === 401 && !path.startsWith(\"/auth/\")) {\n window.location.href = \"/login\";\n throw new ApiError(401, \"Session expired\");\n }\n const body = await res.json().catch(() => ({ detail: res.statusText }));\n throw new ApiError(res.status, formatErrorDetail(body.detail));\n }\n return res.json();\n}\n\nfunction qs(params?: Record<string, string | number | undefined>) {\n if (!params) return \"\";\n const clean = Object.fromEntries(\n Object.entries(params).filter(([, v]) => v !== undefined && v !== \"\"),\n );\n const s = new URLSearchParams(clean as Record<string, string>).toString();\n return s ? `?${s}` : \"\";\n}\n\nexport const api = {\n // Generic request (used by sidebar for chat sessions)\n request,\n\n // Chat attachments\n uploadChatAttachment: async (sessionId: string, file: File) => {\n const form = new FormData();\n form.append(\"file\", file);\n form.append(\"session_id\", sessionId);\n const res = await fetch(`${BASE}/chat/attachments`, {\n method: \"POST\",\n credentials: \"include\",\n body: form,\n });\n if (!res.ok) {\n if (res.status === 401) {\n window.location.href = \"/login\";\n throw new ApiError(401, \"Session expired\");\n }\n const body = await res.json().catch(() => ({ detail: res.statusText }));\n throw new ApiError(res.status, body.detail || \"Upload failed\");\n }\n return res.json() as Promise<{\n id: string;\n filename: string;\n mime_type: string;\n size_bytes: number;\n created_at: string;\n }>;\n },\n getChatAttachmentUrl: (id: string) => `${BASE}/chat/attachments/${encodeURIComponent(id)}`,\n\n // Chat\n createChatSession: () =>\n request<{ id: string; title: string; created_at: string; updated_at: string; last_message_at?: string | null }>(\n \"/chat/sessions\",\n { method: \"POST\" },\n ),\n\n getChatSession: (id: string) =>\n request<{ id: string; title: string; created_at: string; updated_at: string; last_message_at?: string | null; detail?: string }>(\n `/chat/sessions/${encodeURIComponent(id)}`,\n ),\n\n // Documents\n listDocuments: (doctype: string, params?: Record<string, string | number | undefined>) =>\n request<{ rows: any[]; total: number; limit: number; offset: number }>(\n `/documents/${doctype}${qs(params)}`,\n ),\n\n getDocument: (doctype: string, name: string) =>\n request<any>(`/documents/${doctype}/${encodeURIComponent(name)}`),\n\n // Prev/next record around `name` in the same order+filters the list uses.\n adjacentDocument: (doctype: string, name: string, params?: Record<string, string | number | undefined>) =>\n request<{ prev: string | null; next: string | null }>(\n `/documents/${doctype}/${encodeURIComponent(name)}/adjacent${qs(params)}`,\n ),\n\n // Prev/next master record around `name` in the master list's order (name ASC).\n adjacentMaster: (masterType: string, name: string) =>\n request<{ prev: string | null; next: string | null }>(\n `/masters/${masterType}/${encodeURIComponent(name)}/adjacent`,\n ),\n\n createDocument: (doctype: string, data: any) =>\n request<any>(`/documents/${doctype}`, { method: \"POST\", body: JSON.stringify(data) }),\n\n updateDocument: (doctype: string, name: string, data: any) =>\n request<any>(`/documents/${doctype}/${encodeURIComponent(name)}`, {\n method: \"PUT\",\n body: JSON.stringify(data),\n }),\n\n submitDocument: (doctype: string, name: string) =>\n request<any>(`/documents/${doctype}/${encodeURIComponent(name)}/submit`, { method: \"POST\" }),\n\n cancelDocument: (doctype: string, name: string) =>\n request<any>(`/documents/${doctype}/${encodeURIComponent(name)}/cancel`, { method: \"POST\" }),\n\n discardDocument: (doctype: string, name: string) =>\n request<any>(`/documents/${doctype}/${encodeURIComponent(name)}/discard`, { method: \"POST\" }),\n\n convertDocument: (doctype: string, name: string, targetDoctype: string) =>\n request<any>(`/documents/${doctype}/${encodeURIComponent(name)}/convert`, {\n method: \"POST\",\n body: JSON.stringify({ target_doctype: targetDoctype }),\n }),\n\n // Proposal (Sammelofferte) extras — CRUD goes through the document methods\n // above (doctype \"proposal\"); these cover the appendix blob + cover default.\n getProposalCoverDefault: (company?: string, customer?: string) =>\n request<{ cover_letter: string }>(\n `/proposals/cover-default${qs({ company, customer })}`,\n ),\n\n uploadProposalAppendix: async (name: string, file: File) => {\n const form = new FormData();\n form.append(\"file\", file);\n const res = await fetch(`${BASE}/proposals/${encodeURIComponent(name)}/appendix`, {\n method: \"POST\",\n credentials: \"include\",\n body: form,\n });\n if (!res.ok) {\n if (res.status === 401) {\n window.location.href = \"/login\";\n throw new ApiError(401, \"Session expired\");\n }\n const body = await res.json().catch(() => ({ detail: res.statusText }));\n throw new ApiError(res.status, body.detail || \"Upload failed\");\n }\n return res.json() as Promise<{ appendix_filename: string; size: number }>;\n },\n\n deleteProposalAppendix: (name: string) =>\n request<{ ok: boolean }>(`/proposals/${encodeURIComponent(name)}/appendix`, { method: \"DELETE\" }),\n\n proposalPdfUrl: (name: string) => `${BASE}/documents/proposal/${encodeURIComponent(name)}/pdf`,\n\n // Masters\n listMasters: (type: string, params?: Record<string, string | number | undefined>) =>\n request<{ rows: any[]; total: number; limit: number; offset: number }>(\n `/masters/${type}${qs(params)}`,\n ),\n\n searchMasters: (type: string, q: string) =>\n request<any[]>(`/masters/${type}/search?q=${encodeURIComponent(q)}`),\n\n searchDocuments: (doctype: string, q: string) =>\n request<any[]>(`/documents/${doctype}/search?q=${encodeURIComponent(q)}`),\n\n searchLink: async (type: string, q: string): Promise<any[]> => {\n try {\n const results = await request<any[]>(`/masters/${type}/search?q=${encodeURIComponent(q)}`);\n if (results.length > 0) return results;\n } catch {\n // masters endpoint failed, try documents\n }\n return request<any[]>(`/documents/${type}/search?q=${encodeURIComponent(q)}`);\n },\n\n getMaster: (type: string, name: string) =>\n request<any>(`/masters/${type}/${encodeURIComponent(name)}`),\n\n currencies: (company?: string) =>\n request<{ base_currency: string; currencies: string[] }>(\n `/accounting/currencies${qs({ company })}`,\n ),\n\n createMaster: (type: string, data: any) =>\n request<any>(`/masters/${type}`, { method: \"POST\", body: JSON.stringify(data) }),\n\n updateMaster: (type: string, name: string, data: any) =>\n request<any>(`/masters/${type}/${encodeURIComponent(name)}`, {\n method: \"PUT\",\n body: JSON.stringify(data),\n }),\n\n deleteMaster: (type: string, name: string) =>\n request<any>(`/masters/${type}/${encodeURIComponent(name)}`, { method: \"DELETE\" }),\n\n // Reports\n trialBalance: (params?: Record<string, string>) =>\n request<{ rows: any[]; total_debit: number; total_credit: number; difference: number }>(\n `/reports/trial-balance${qs(params)}`,\n ),\n\n chartOfAccounts: (params?: Record<string, string>) =>\n request<{ accounts: any[]; from_date: string | null; to_date: string | null }>(\n `/reports/chart-of-accounts${qs(params)}`,\n ),\n\n generalLedger: (params?: Record<string, string>) =>\n request<{\n rows: any[];\n total: number;\n limit: number;\n offset: number;\n opening_balance: number;\n }>(`/reports/general-ledger${qs(params)}`),\n\n stockBalance: (params?: Record<string, string>) =>\n request<{ rows: any[] }>(`/reports/stock-balance${qs(params)}`),\n\n dashboardSummary: (company?: string) =>\n request<any>(`/reports/dashboard-summary${qs({ company })}`),\n\n profitAndLoss: (params?: Record<string, string>) =>\n request<any>(`/reports/profit-and-loss${qs(params)}`),\n\n balanceSheet: (params?: Record<string, string>) =>\n request<any>(`/reports/balance-sheet${qs(params)}`),\n\n arAging: (params?: Record<string, string>) =>\n request<any>(`/reports/ar-aging${qs(params)}`),\n\n apAging: (params?: Record<string, string>) =>\n request<any>(`/reports/ap-aging${qs(params)}`),\n\n analyticsMetrics: () =>\n request<{\n metrics: Array<{\n metric: string;\n label: string;\n group_by: string[];\n time_based: boolean;\n }>;\n }>(\"/reports/analytics/metrics\"),\n\n analytics: (params: Record<string, string>) =>\n request<{\n metric: string;\n metric_label: string;\n group_by: string;\n chart_type: \"bar\" | \"line\";\n time_based: boolean;\n from_date: string | null;\n to_date: string | null;\n company: string | null;\n rows: Array<{ label: string; value: number }>;\n total: number;\n }>(`/reports/analytics${qs(params)}`),\n\n runtimeDatasets: () =>\n request<{\n datasets: Array<{\n dataset: string;\n label: string;\n description: string;\n fields: Record<string, string>;\n filter_fields: string[];\n default_limit: number;\n max_limit: number;\n }>;\n }>(\"/reports/runtime/datasets\"),\n\n runtimeData: (data: {\n requests: Array<{\n name?: string;\n dataset: string;\n fields?: string[];\n filters?: Record<string, unknown>;\n limit?: number;\n }>;\n }) =>\n request<{\n datasets: Array<{\n name: string;\n dataset: string;\n rows: Array<Record<string, unknown>>;\n fields: Record<string, string>;\n row_count: number;\n truncated: boolean;\n limit: number;\n }>;\n }>(\"/reports/runtime/data\", { method: \"POST\", body: JSON.stringify(data) }),\n\n createRuntimeDraft: (data: {\n title: string;\n description?: string;\n data_requests: Array<{\n name?: string;\n dataset: string;\n fields?: string[];\n filters?: Record<string, unknown>;\n limit?: number;\n }>;\n transform_js: string;\n }) =>\n request<{\n id: string;\n title: string;\n description?: string;\n definition: Record<string, unknown>;\n url: string;\n created_by?: string;\n }>(\"/reports/runtime/drafts\", { method: \"POST\", body: JSON.stringify(data) }),\n\n getRuntimeDraft: (id: string) =>\n request<{\n id: string;\n title: string;\n description?: string;\n definition: Record<string, unknown>;\n url: string;\n created_by?: string;\n source_chat_session_id?: string;\n created_at?: string;\n updated_at?: string;\n }>(`/reports/runtime/drafts/${encodeURIComponent(id)}`),\n\n listRuntimeDrafts: () =>\n request<{\n drafts: Array<{\n id: string;\n title: string;\n description?: string;\n created_by?: string;\n source_chat_session_id?: string;\n created_at?: string;\n updated_at?: string;\n url: string;\n }>;\n }>(\"/reports/runtime/drafts\"),\n\n deleteRuntimeDraft: (id: string) =>\n request<{ deleted: string }>(`/reports/runtime/drafts/${encodeURIComponent(id)}`, {\n method: \"DELETE\",\n }),\n\n // Setup\n setupStatus: () => request<{ setup_complete: boolean; companies: any[] }>(\"/setup/status\"),\n\n createCompany: (data: {\n name: string;\n currency?: string;\n email?: string;\n phone?: string;\n address?: string;\n city?: string;\n zip_code?: string;\n country?: string;\n tax_id?: string;\n }) => request<any>(\"/setup/company\", { method: \"POST\", body: JSON.stringify(data) }),\n\n seedDemo: () => request<any>(\"/setup/seed-demo\", { method: \"POST\" }),\n\n seedHistory: (data?: { start_date?: string; end_date?: string; seed?: number; intensity?: number }) =>\n request<{ ok: boolean; company: string; start_date: string; end_date: string; stats: Record<string, number> }>(\n \"/setup/seed-history\",\n { method: \"POST\", body: JSON.stringify(data ?? {}) },\n ),\n\n importAccountBalances: (data: any) =>\n request<any>(\"/setup/opening-balances/accounts\", { method: \"POST\", body: JSON.stringify(data) }),\n importStockBalances: (data: any) =>\n request<any>(\"/setup/opening-balances/stock\", { method: \"POST\", body: JSON.stringify(data) }),\n importOutstandingInvoices: (data: any) =>\n request<any>(\"/setup/opening-balances/invoices\", { method: \"POST\", body: JSON.stringify(data) }),\n\n // Auth\n authSetupStatus: () =>\n request<{\n has_users: boolean;\n first_run: boolean;\n public_signup: boolean;\n registration_open: boolean;\n oauth_providers: string[];\n }>(\"/auth/setup-status\"),\n // Social login is a full-page navigation, not a fetch — build the URL the\n // browser should be sent to. `link` starts a \"link to my account\" flow.\n oauthLoginUrl: (provider: string, opts?: { link?: boolean; invite?: string }) => {\n const qs = new URLSearchParams();\n if (opts?.link) qs.set(\"link\", \"1\");\n if (opts?.invite) qs.set(\"invite\", opts.invite);\n const suffix = qs.toString() ? `?${qs.toString()}` : \"\";\n return apiUrl(`/auth/${encodeURIComponent(provider)}/login${suffix}`);\n },\n oauthListIdentities: () => request<{ provider: string; email: string | null; creation: string }[]>(\"/auth/oauth/identities\"),\n authRegister: (data: { email: string; full_name: string; password: string; invite_token?: string }) =>\n request<any>(\"/auth/register\", { method: \"POST\", body: JSON.stringify(data) }),\n authLogin: (email: string, password: string) =>\n request<any>(\"/auth/login\", { method: \"POST\", body: JSON.stringify({ email, password }) }),\n authLogout: () => request<any>(\"/auth/logout\", { method: \"POST\" }),\n authMe: () => request<any>(\"/auth/me\"),\n authChangePassword: (current_password: string, new_password: string) =>\n request<any>(\"/auth/change-password\", {\n method: \"POST\",\n body: JSON.stringify({ current_password, new_password }),\n }),\n authSetPassword: (new_password: string) =>\n request<any>(\"/auth/set-password\", {\n method: \"POST\",\n body: JSON.stringify({ new_password }),\n }),\n authInvite: (email: string, role: string) =>\n request<any>(\"/auth/invite\", { method: \"POST\", body: JSON.stringify({ email, role }) }),\n authListUsers: () => request<any[]>(\"/auth/users\"),\n authChangeRole: (userName: string, role: string) =>\n request<any>(`/auth/users/${encodeURIComponent(userName)}/role`, { method: \"PUT\", body: JSON.stringify({ role }) }),\n authDisableUser: (userName: string) =>\n request<any>(`/auth/users/${encodeURIComponent(userName)}`, { method: \"DELETE\" }),\n authListInvites: () => request<any[]>(\"/auth/invites\"),\n authRevokeInvite: (token: string) =>\n request<any>(`/auth/invites/${encodeURIComponent(token)}`, { method: \"DELETE\" }),\n getPublicManagerStatus: () => request<{ active: boolean; user?: any }>(\"/auth/public-manager\"),\n createPublicManager: () => request<any>(\"/auth/public-manager\", { method: \"POST\" }),\n removePublicManager: () => request<any>(\"/auth/public-manager\", { method: \"DELETE\" }),\n getHealth: () => request<{ status: string; version: string }>(\"/health\"),\n getSettings: () => request<Record<string, string>>(\"/auth/settings\"),\n updateSettings: (data: Record<string, string>) =>\n request<Record<string, string>>(\"/auth/settings\", { method: \"PUT\", body: JSON.stringify(data) }),\n getApiKeys: () =>\n request<Array<{\n id: string; name: string; user?: string; role: string; key_prefix: string;\n created_at?: string; last_used_at?: string | null; revoked: boolean;\n owner_full_name?: string | null; owner_email?: string | null; is_mine?: boolean;\n }>>(\"/auth/api-keys\"),\n createApiKey: (name: string, role: string) =>\n request<{\n id: string; name: string; user?: string; role: string; key_prefix: string; token: string;\n owner_full_name?: string | null; owner_email?: string | null; is_mine?: boolean;\n }>(\"/auth/api-keys\", { method: \"POST\", body: JSON.stringify({ name, role }) }),\n revokeApiKey: (id: string) =>\n request<{ id: string; revoked: boolean }>(\n `/auth/api-keys/${encodeURIComponent(id)}/revoke`, { method: \"POST\" }),\n deleteApiKey: (id: string) =>\n request<{ id: string; deleted: boolean }>(\n `/auth/api-keys/${encodeURIComponent(id)}`, { method: \"DELETE\" }),\n\n getDemoSpend: () =>\n request<{\n caps: { global_hourly_usd: number; per_ip_hourly_usd: number };\n windows: Record<\n string,\n {\n total_usd: number;\n demo_usd: number;\n prompt_tokens: number;\n completion_tokens: number;\n call_count: number;\n unique_ips: number;\n by_provider: Record<\n string,\n {\n cost_usd: number;\n call_count: number;\n prompt_tokens: number;\n completion_tokens: number;\n }\n >;\n }\n >;\n top_ips_24h: Array<{\n ip: string;\n role: string | null;\n cost_usd: number;\n call_count: number;\n }>;\n }>(\"/admin/demo-spend\"),\n};\n","import { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from \"react\";\nimport { api, ApiError } from \"@/api/client\";\n\nexport interface User {\n name: string;\n email: string;\n full_name: string;\n role: \"admin\" | \"manager\" | \"viewer\" | \"public_manager\";\n // Whether the account has a real email+password. Social-login-only users have\n // none (they can set a first one from Settings). Undefined on older sessions\n // until the next /me refresh.\n has_password?: boolean;\n}\n\ninterface AuthContextValue {\n user: User | null;\n loading: boolean;\n login: (email: string, password: string) => Promise<User>;\n register: (email: string, fullName: string, password: string, inviteToken?: string) => Promise<User>;\n logout: () => Promise<void>;\n refreshUser: () => Promise<void>;\n}\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\nexport function AuthProvider({ children }: { children: ReactNode }) {\n const [user, setUser] = useState<User | null>(null);\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n api.authMe()\n .then((u) => setUser(u))\n .catch(() => setUser(null))\n .finally(() => setLoading(false));\n }, []);\n\n const login = useCallback(async (email: string, password: string) => {\n const u = await api.authLogin(email, password);\n setUser(u);\n return u;\n }, []);\n\n const register = useCallback(async (email: string, fullName: string, password: string, inviteToken?: string) => {\n const u = await api.authRegister({ email, full_name: fullName, password, invite_token: inviteToken });\n setUser(u);\n return u;\n }, []);\n\n const logout = useCallback(async () => {\n try { await api.authLogout(); } catch { /* ignore */ }\n setUser(null);\n }, []);\n\n const refreshUser = useCallback(async () => {\n try {\n const u = await api.authMe();\n setUser(u);\n } catch { /* ignore — session check failures are handled elsewhere */ }\n }, []);\n\n return (\n <AuthContext.Provider value={{ user, loading, login, register, logout, refreshUser }}>\n {children}\n </AuthContext.Provider>\n );\n}\n\nexport function useAuth(): AuthContextValue {\n const ctx = useContext(AuthContext);\n if (!ctx) throw new Error(\"useAuth must be used within AuthProvider\");\n return ctx;\n}\n","import {\n createContext,\n useContext,\n useEffect,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { api } from \"@/api/client\";\n\nexport interface ChatSession {\n id: string;\n title: string;\n created_at: string;\n updated_at: string;\n last_message_at?: string | null;\n}\n\nexport interface ChatAttachment {\n id: string;\n filename: string;\n mime_type: string;\n}\n\nexport interface ChatMessage {\n id?: number;\n type: \"user\" | \"assistant\" | \"thinking\" | \"tool_call\" | \"tool_result\" | \"error\";\n content: string;\n tool?: string;\n args?: Record<string, unknown>;\n success?: boolean;\n iteration?: number;\n timestamp?: string;\n attachments?: ChatAttachment[];\n provider?: string;\n model?: string;\n}\n\ntype ConnectionStatus = \"connecting\" | \"connected\" | \"disconnected\";\n\ninterface NavigationFlash {\n group: string;\n item?: string;\n key: number;\n}\n\ninterface PersistedChatMessage {\n id?: number;\n role: string;\n content: string;\n created_at?: string;\n attachments?: ChatAttachment[];\n}\n\ninterface ChatContextValue {\n sessions: ChatSession[];\n connectionStatus: ConnectionStatus;\n connectionVersion: number;\n navigationFlash: NavigationFlash | null;\n createSession: () => Promise<ChatSession>;\n startDemo: (sessionId: string) => Promise<void>;\n completeDemoTyping: (sessionId: string, seq: number) => void;\n deleteSession: (sessionId: string) => Promise<void>;\n loadHistory: (sessionId: string) => Promise<void>;\n loadMoreHistory: (sessionId: string) => Promise<void>;\n clearHistory: (sessionId: string) => Promise<void>;\n sendMessage: (sessionId: string, content: string, attachmentIds?: string[]) => boolean;\n transcribeAudio: (audioBase64: string, audioFormat: string, sessionId?: string) => Promise<string>;\n getMessages: (sessionId?: string) => ChatMessage[];\n hasMoreHistory: (sessionId?: string) => boolean;\n isLoadingOlder: (sessionId?: string) => boolean;\n isThinking: (sessionId?: string) => boolean;\n getDemoStatus: (sessionId?: string) => \"idle\" | \"running\" | \"complete\";\n getDemoTypingCue: (sessionId?: string) => { content: string; seq: number; typingMs: number } | null;\n}\n\ninterface PendingRequest {\n expectedType: string;\n resolve: (value: Record<string, unknown>) => void;\n reject: (error: Error) => void;\n}\n\nconst ChatContext = createContext<ChatContextValue | null>(null);\n\nconst NAV_FLASH_MAP: Record<string, { group: string; item: string }> = {\n \"quotation\": { group: \"Selling\", item: \"Quotation\" },\n \"sales-order\": { group: \"Selling\", item: \"Sales Order\" },\n \"sales-invoice\": { group: \"Selling\", item: \"Sales Invoice\" },\n \"pos-invoice\": { group: \"Selling\", item: \"POS Invoice\" },\n \"purchase-order\": { group: \"Buying\", item: \"Purchase Order\" },\n \"purchase-invoice\": { group: \"Buying\", item: \"Purchase Invoice\" },\n \"payment-entry\": { group: \"Accounting\", item: \"Payment Entry\" },\n \"journal-entry\": { group: \"Accounting\", item: \"Journal Entry\" },\n \"bank-transaction\": { group: \"Accounting\", item: \"Bank Transaction\" },\n \"budget\": { group: \"Accounting\", item: \"Budget\" },\n \"subscription\": { group: \"Accounting\", item: \"Subscription\" },\n \"stock-entry\": { group: \"Stock\", item: \"Stock Entry\" },\n \"delivery-note\": { group: \"Stock\", item: \"Delivery Note\" },\n \"purchase-receipt\": { group: \"Stock\", item: \"Purchase Receipt\" },\n \"pricing-rule\": { group: \"Settings\", item: \"Pricing Rule\" },\n};\n\nconst MASTER_FLASH_MAP: Record<string, { group: string; item: string }> = {\n \"customer\": { group: \"Masters\", item: \"Customer\" },\n \"supplier\": { group: \"Masters\", item: \"Supplier\" },\n \"item\": { group: \"Masters\", item: \"Item\" },\n \"warehouse\": { group: \"Masters\", item: \"Warehouse\" },\n \"company\": { group: \"Masters\", item: \"Company\" },\n};\n\nfunction normalizeDoctype(value: unknown): string | null {\n if (typeof value !== \"string\") return null;\n return value.trim().toLowerCase().replace(/\\s+/g, \"-\");\n}\n\nfunction getNavigationFlashFromTool(tool: string, args?: Record<string, unknown>): { group: string; item: string } | null {\n // Custom analytics tools — flash the sidebar group without targeting an item.\n // (There's no fixed item for custom analytics; the newly touched draft\n // shows up as an entry under the group itself.)\n if (\n tool === \"create_custom_analytics_report\" ||\n tool === \"update_custom_analytics_report\"\n ) {\n return { group: \"Custom Analytics\", item: \"\" };\n }\n\n if (!args) return null;\n\n // Document tools\n let doctype: string | null = null;\n if (\n tool === \"create_document\" ||\n tool === \"update_document\" ||\n tool === \"submit_document\" ||\n tool === \"cancel_document\"\n ) {\n doctype = normalizeDoctype(args.doctype);\n } else if (tool === \"convert_document\") {\n doctype = normalizeDoctype(args.target_doctype);\n }\n if (doctype && NAV_FLASH_MAP[doctype]) {\n return NAV_FLASH_MAP[doctype];\n }\n\n // Master tools\n if (tool === \"create_master\" || tool === \"update_master\") {\n const masterType = normalizeDoctype(args.master_type);\n if (masterType && MASTER_FLASH_MAP[masterType]) {\n return MASTER_FLASH_MAP[masterType];\n }\n }\n\n return null;\n}\n\nfunction mapPersistedMessage(message: PersistedChatMessage): ChatMessage {\n return {\n id: message.id,\n type: message.role === \"user\" ? \"user\" : \"assistant\",\n content: message.content,\n timestamp: message.created_at,\n attachments: message.attachments,\n };\n}\n\nfunction isPersistentMessage(message: ChatMessage): boolean {\n return message.type === \"user\" || message.type === \"assistant\";\n}\n\n// Per-browser memory of chat sessions this visitor has created or opened.\n// Needed because the `public_manager` demo account is shared across all\n// visitors and the server-side list filter hides demo-only chats to prevent\n// pile-up — without this, a visitor's freshly-created demo chat would\n// vanish from the sidebar on page reload.\nconst KNOWN_SESSIONS_KEY = \"lambda-erp:known-chat-sessions\";\n\nfunction getKnownSessionIds(): Set<string> {\n if (typeof localStorage === \"undefined\") return new Set();\n try {\n const raw = localStorage.getItem(KNOWN_SESSIONS_KEY);\n if (!raw) return new Set();\n const parsed = JSON.parse(raw);\n return new Set(Array.isArray(parsed) ? parsed.filter((v) => typeof v === \"string\") : []);\n } catch {\n return new Set();\n }\n}\n\nfunction writeKnownSessionIds(ids: Set<string>) {\n if (typeof localStorage === \"undefined\") return;\n try {\n localStorage.setItem(KNOWN_SESSIONS_KEY, JSON.stringify([...ids]));\n } catch {\n // ignore storage errors (quota / private mode)\n }\n}\n\nexport function rememberSessionId(id: string) {\n const ids = getKnownSessionIds();\n if (ids.has(id)) return;\n ids.add(id);\n writeKnownSessionIds(ids);\n}\n\nfunction forgetSessionId(id: string) {\n const ids = getKnownSessionIds();\n if (!ids.delete(id)) return;\n writeKnownSessionIds(ids);\n}\n\nfunction makeRequestId(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n return `req-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nfunction toSortTime(timestamp?: string): number {\n if (!timestamp) return 0;\n // Normalize SQLite's space-separated format (\"YYYY-MM-DD HH:MM:SS\") to\n // ISO T-form so it parses consistently with Python `now()` output.\n const s = /^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}/.test(timestamp)\n ? timestamp.replace(\" \", \"T\")\n : timestamp;\n const value = new Date(s).getTime();\n return Number.isNaN(value) ? 0 : value;\n}\n\nexport function ChatProvider({ children }: { children: ReactNode }) {\n const queryClient = useQueryClient();\n const [sessions, setSessions] = useState<ChatSession[]>([]);\n const [messagesBySession, setMessagesBySession] = useState<Record<string, ChatMessage[]>>({});\n const [hasMoreBySession, setHasMoreBySession] = useState<Record<string, boolean>>({});\n const [oldestIdBySession, setOldestIdBySession] = useState<Record<string, number | null>>({});\n const [loadingOlderBySession, setLoadingOlderBySession] = useState<Record<string, boolean>>({});\n const [thinkingBySession, setThinkingBySession] = useState<Record<string, boolean>>({});\n const [demoStatusBySession, setDemoStatusBySession] = useState<Record<string, \"idle\" | \"running\" | \"complete\">>({});\n const [demoTypingCueBySession, setDemoTypingCueBySession] = useState<Record<string, { content: string; seq: number; typingMs: number } | null>>({});\n const [navigationFlash, setNavigationFlash] = useState<NavigationFlash | null>(null);\n const [connectionStatus, setConnectionStatus] = useState<ConnectionStatus>(\"connecting\");\n const [connectionVersion, setConnectionVersion] = useState(0);\n const wsRef = useRef<WebSocket | null>(null);\n const reconnectTimerRef = useRef<number | null>(null);\n const pendingRequestsRef = useRef<Map<string, PendingRequest>>(new Map());\n const pendingCreateSessionRef = useRef<Promise<ChatSession> | null>(null);\n const lastMessageAtRef = useRef<Record<string, string>>({});\n const pendingToolCallsRef = useRef<Record<string, { tool: string; args?: Record<string, unknown> } | null>>({});\n const navFlashTimeoutRef = useRef<number | null>(null);\n\n function rejectPendingRequests(message: string) {\n for (const pending of pendingRequestsRef.current.values()) {\n pending.reject(new Error(message));\n }\n pendingRequestsRef.current.clear();\n }\n\n function updateSessionMessages(sessionId: string, updater: (messages: ChatMessage[]) => ChatMessage[]) {\n setMessagesBySession((prev) => ({\n ...prev,\n [sessionId]: updater(prev[sessionId] ?? []),\n }));\n }\n\n function setSessionThinking(sessionId: string, value: boolean) {\n setThinkingBySession((prev) => ({ ...prev, [sessionId]: value }));\n }\n\n function setSessionDemoStatus(sessionId: string, value: \"idle\" | \"running\" | \"complete\") {\n setDemoStatusBySession((prev) => ({ ...prev, [sessionId]: value }));\n }\n\n function setSessionDemoTypingCue(sessionId: string, value: { content: string; seq: number; typingMs: number } | null) {\n setDemoTypingCueBySession((prev) => ({ ...prev, [sessionId]: value }));\n }\n\n function triggerNavigationFlash(group: string, item?: string) {\n if (navFlashTimeoutRef.current !== null) {\n window.clearTimeout(navFlashTimeoutRef.current);\n }\n setNavigationFlash({ group, item, key: Date.now() });\n navFlashTimeoutRef.current = window.setTimeout(() => {\n setNavigationFlash((prev) => (prev?.group === group && prev?.item === item ? null : prev));\n navFlashTimeoutRef.current = null;\n }, 1100);\n }\n\n function sortSessionsByMessageActivity(sessionList: ChatSession[]): ChatSession[] {\n return [...sessionList].sort((left, right) => {\n const leftTime =\n toSortTime(lastMessageAtRef.current[left.id])\n || toSortTime(left.last_message_at || undefined)\n || toSortTime(left.created_at);\n const rightTime =\n toSortTime(lastMessageAtRef.current[right.id])\n || toSortTime(right.last_message_at || undefined)\n || toSortTime(right.created_at);\n return rightTime - leftTime;\n });\n }\n\n function updateSessionList(updater: (sessions: ChatSession[]) => ChatSession[]) {\n setSessions((prev) => sortSessionsByMessageActivity(updater(prev)));\n }\n\n function recordSessionMessage(sessionId: string, timestamp?: string) {\n const nextTimestamp = timestamp || new Date().toISOString();\n const currentTimestamp = lastMessageAtRef.current[sessionId];\n if (toSortTime(nextTimestamp) >= toSortTime(currentTimestamp)) {\n lastMessageAtRef.current = {\n ...lastMessageAtRef.current,\n [sessionId]: nextTimestamp,\n };\n }\n }\n\n function hydrateLastMessageTimes(sessionList: ChatSession[]) {\n const next = { ...lastMessageAtRef.current };\n for (const session of sessionList) {\n if (session.last_message_at && !next[session.id]) {\n next[session.id] = session.last_message_at;\n }\n }\n lastMessageAtRef.current = next;\n }\n\n function sendRaw(payload: Record<string, unknown>) {\n const ws = wsRef.current;\n if (!ws || ws.readyState !== WebSocket.OPEN) {\n throw new Error(\"Chat is disconnected.\");\n }\n ws.send(JSON.stringify(payload));\n }\n\n function sendRequest(type: string, payload: Record<string, unknown>, expectedType: string): Promise<Record<string, unknown>> {\n return new Promise((resolve, reject) => {\n const requestId = makeRequestId();\n pendingRequestsRef.current.set(requestId, {\n expectedType,\n resolve,\n reject,\n });\n\n try {\n sendRaw({ type, request_id: requestId, ...payload });\n } catch (error) {\n pendingRequestsRef.current.delete(requestId);\n reject(error instanceof Error ? error : new Error(\"Chat request failed.\"));\n }\n });\n }\n\n useEffect(() => {\n let disposed = false;\n\n function connect() {\n if (disposed) return;\n\n setConnectionStatus(\"connecting\");\n\n const protocol = window.location.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n const wsUrl = `${protocol}//${window.location.host}/ws/chat`;\n const ws = new WebSocket(wsUrl);\n wsRef.current = ws;\n\n ws.onopen = () => {\n if (disposed) {\n ws.close();\n return;\n }\n setConnectionStatus(\"connected\");\n setConnectionVersion((prev) => prev + 1);\n };\n\n ws.onmessage = (event) => {\n try {\n const data = JSON.parse(event.data) as Record<string, unknown>;\n const requestId = typeof data.request_id === \"string\" ? data.request_id : null;\n const eventType = typeof data.type === \"string\" ? data.type : null;\n const sessionId = typeof data.session_id === \"string\" ? data.session_id : null;\n\n if (requestId) {\n const pending = pendingRequestsRef.current.get(requestId);\n if (pending) {\n if (eventType === \"error\") {\n pendingRequestsRef.current.delete(requestId);\n pending.reject(new Error(String(data.content || \"Request failed.\")));\n } else if (eventType === pending.expectedType) {\n pendingRequestsRef.current.delete(requestId);\n pending.resolve(data);\n }\n }\n }\n\n if (eventType === \"sessions_list\") {\n const nextSessions = Array.isArray(data.sessions) ? (data.sessions as ChatSession[]) : [];\n hydrateLastMessageTimes(nextSessions);\n setSessions(\n sortSessionsByMessageActivity(\n nextSessions,\n ),\n );\n // Merge in any \"mine\" sessions (tracked per-browser in\n // localStorage) that the server hid from the list because\n // they're demo-only on a shared public_manager account.\n const serverIds = new Set(nextSessions.map((s) => s.id));\n const knownIds = getKnownSessionIds();\n const missing = [...knownIds].filter((id) => !serverIds.has(id));\n if (missing.length > 0) {\n void Promise.all(\n missing.map(async (id) => {\n try {\n const row = await api.getChatSession(id);\n if (!row || row.detail || !row.id) {\n forgetSessionId(id);\n return null;\n }\n return row as ChatSession;\n } catch {\n return null;\n }\n }),\n ).then((fetched) => {\n const resolved = fetched.filter((s): s is ChatSession => !!s);\n if (!resolved.length) return;\n hydrateLastMessageTimes(resolved);\n updateSessionList((prev) => [\n ...resolved.filter((s) => !prev.some((p) => p.id === s.id)),\n ...prev,\n ]);\n });\n }\n return;\n }\n\n if (eventType === \"session_created\") {\n const session = data.session as ChatSession | undefined;\n if (!session) return;\n rememberSessionId(session.id);\n hydrateLastMessageTimes([session]);\n updateSessionList((prev) => [session, ...prev.filter((entry) => entry.id !== session.id)]);\n return;\n }\n\n if (eventType === \"session_deleted\" && sessionId) {\n forgetSessionId(sessionId);\n updateSessionList((prev) => prev.filter((session) => session.id !== sessionId));\n setMessagesBySession((prev) => {\n const next = { ...prev };\n delete next[sessionId];\n return next;\n });\n setThinkingBySession((prev) => {\n const next = { ...prev };\n delete next[sessionId];\n return next;\n });\n setDemoStatusBySession((prev) => {\n const next = { ...prev };\n delete next[sessionId];\n return next;\n });\n setDemoTypingCueBySession((prev) => {\n const next = { ...prev };\n delete next[sessionId];\n return next;\n });\n setHasMoreBySession((prev) => {\n const next = { ...prev };\n delete next[sessionId];\n return next;\n });\n setOldestIdBySession((prev) => {\n const next = { ...prev };\n delete next[sessionId];\n return next;\n });\n setLoadingOlderBySession((prev) => {\n const next = { ...prev };\n delete next[sessionId];\n return next;\n });\n const nextLastMessageAt = { ...lastMessageAtRef.current };\n delete nextLastMessageAt[sessionId];\n lastMessageAtRef.current = nextLastMessageAt;\n return;\n }\n\n if (eventType === \"history_loaded\" && sessionId) {\n const persisted = Array.isArray(data.messages)\n ? (data.messages as PersistedChatMessage[]).map(mapPersistedMessage)\n : [];\n const isPrepend = data.before_id != null;\n const hasMore = Boolean(data.has_more);\n const oldestId =\n typeof data.oldest_id === \"number\" ? data.oldest_id : null;\n\n setMessagesBySession((prev) => {\n if (isPrepend) {\n const existing = prev[sessionId] ?? [];\n const existingIds = new Set(\n existing\n .map((entry) => entry.id)\n .filter((id): id is number => typeof id === \"number\"),\n );\n const filtered = persisted.filter(\n (entry) => entry.id === undefined || !existingIds.has(entry.id),\n );\n return { ...prev, [sessionId]: [...filtered, ...existing] };\n }\n return { ...prev, [sessionId]: persisted };\n });\n\n setHasMoreBySession((prev) => ({ ...prev, [sessionId]: hasMore }));\n setOldestIdBySession((prev) => ({ ...prev, [sessionId]: oldestId }));\n setLoadingOlderBySession((prev) => ({ ...prev, [sessionId]: false }));\n\n const title = typeof data.title === \"string\" ? data.title : null;\n if (title) {\n updateSessionList((prev) =>\n prev.map((session) => (\n session.id === sessionId ? { ...session, title } : session\n )),\n );\n }\n\n if (!isPrepend) {\n const lastPersistedMessage = persisted[persisted.length - 1];\n if (lastPersistedMessage?.timestamp) {\n recordSessionMessage(sessionId, lastPersistedMessage.timestamp);\n updateSessionList((prev) => prev);\n }\n }\n return;\n }\n\n if (eventType === \"history_cleared\" && sessionId) {\n setMessagesBySession((prev) => ({ ...prev, [sessionId]: [] }));\n setHasMoreBySession((prev) => ({ ...prev, [sessionId]: false }));\n setOldestIdBySession((prev) => ({ ...prev, [sessionId]: null }));\n setLoadingOlderBySession((prev) => ({ ...prev, [sessionId]: false }));\n setSessionThinking(sessionId, false);\n setSessionDemoStatus(sessionId, \"idle\");\n setSessionDemoTypingCue(sessionId, null);\n return;\n }\n\n if (eventType === \"message_added\" && sessionId) {\n const message = data.message as PersistedChatMessage | undefined;\n if (!message) return;\n recordSessionMessage(sessionId, message.created_at);\n if (message.role === \"user\") {\n setSessionDemoTypingCue(sessionId, null);\n }\n updateSessionMessages(sessionId, (prev) => [\n ...prev.filter((entry) => entry.type !== \"thinking\"),\n mapPersistedMessage(message),\n ]);\n updateSessionList((prev) => prev);\n return;\n }\n\n if (eventType === \"demo_started\" && sessionId) {\n setSessionDemoStatus(sessionId, \"running\");\n setSessionDemoTypingCue(sessionId, null);\n return;\n }\n\n if (eventType === \"demo_typing\" && sessionId) {\n setSessionDemoStatus(sessionId, \"running\");\n setSessionDemoTypingCue(sessionId, {\n content: String(data.content || \"\"),\n seq: Math.max(0, Number(data.seq || 0)),\n typingMs: Math.max(0, Number(data.typing_ms || 0)),\n });\n return;\n }\n\n if (eventType === \"demo_replay_complete\" && sessionId) {\n setSessionDemoStatus(sessionId, \"complete\");\n setSessionDemoTypingCue(sessionId, null);\n return;\n }\n\n if (eventType === \"navigation_flash\") {\n const group = typeof data.group === \"string\" ? data.group : \"\";\n const item = typeof data.item === \"string\" ? data.item : undefined;\n if (group) {\n triggerNavigationFlash(group, item);\n }\n return;\n }\n\n if (eventType === \"session_title_updated\" && sessionId) {\n const title = typeof data.title === \"string\" ? data.title : \"\";\n updateSessionList((prev) =>\n prev.map((session) => (\n session.id === sessionId ? { ...session, title } : session\n )),\n );\n return;\n }\n\n if (eventType === \"thinking\" && sessionId) {\n setSessionThinking(sessionId, true);\n updateSessionMessages(sessionId, (prev) => {\n const prior = prev.find((m) => m.type === \"thinking\");\n return [\n ...prev.filter((message) => message.type !== \"thinking\"),\n {\n type: \"thinking\",\n content: `Thinking (step ${data.iteration})...`,\n provider: prior?.provider,\n model: prior?.model,\n },\n ];\n });\n return;\n }\n\n if (eventType === \"llm_provider\" && sessionId) {\n const provider = typeof data.provider === \"string\" ? data.provider : undefined;\n const model = typeof data.model === \"string\" ? data.model : undefined;\n const role = typeof data.role === \"string\" ? data.role : undefined;\n const content = role === \"code_specialist\"\n ? \"Delegating to code specialist...\"\n : undefined;\n setSessionThinking(sessionId, true);\n updateSessionMessages(sessionId, (prev) => {\n const hasThinking = prev.some((m) => m.type === \"thinking\");\n if (hasThinking) {\n return prev.map((message) => (\n message.type === \"thinking\"\n ? {\n ...message,\n provider,\n model,\n ...(content ? { content } : {}),\n }\n : message\n ));\n }\n // No active thinking bubble (e.g. we're mid-tool_call and the\n // backend just handed off to the code specialist). Add one so\n // the provider handoff is visible in the UI.\n return [\n ...prev,\n {\n type: \"thinking\",\n content: content ?? \"Thinking...\",\n provider,\n model,\n },\n ];\n });\n return;\n }\n\n if (eventType === \"tool_call\" && sessionId) {\n pendingToolCallsRef.current = {\n ...pendingToolCallsRef.current,\n [sessionId]: {\n tool: String(data.tool || \"\"),\n args: data.args as Record<string, unknown> | undefined,\n },\n };\n updateSessionMessages(sessionId, (prev) => [\n ...prev.filter((message) => message.type !== \"thinking\"),\n {\n type: \"tool_call\",\n content: `Calling ${data.tool}...`,\n tool: data.tool as string,\n args: data.args as Record<string, unknown>,\n },\n ]);\n return;\n }\n\n if (eventType === \"tool_result\" && sessionId) {\n const pendingToolCall = pendingToolCallsRef.current[sessionId];\n if (pendingToolCall && pendingToolCall.tool === String(data.tool || \"\") && Boolean(data.success)) {\n const isCustomAnalyticsTool =\n pendingToolCall.tool === \"create_custom_analytics_report\" ||\n pendingToolCall.tool === \"update_custom_analytics_report\";\n if (isCustomAnalyticsTool) {\n // Prefer the id the backend just committed (covers create);\n // fall back to the tool's own args (covers update with an\n // unreturned id). The item value becomes the draft id so the\n // sidebar can highlight that specific row.\n const backendReportId = typeof data.report_id === \"string\" ? data.report_id : undefined;\n const argReportId = typeof pendingToolCall.args?.report_id === \"string\"\n ? (pendingToolCall.args.report_id as string)\n : undefined;\n const reportId = backendReportId || argReportId || \"\";\n triggerNavigationFlash(\"Custom Analytics\", reportId);\n queryClient.invalidateQueries({ queryKey: [\"runtime-drafts\"] });\n } else {\n const flashTarget = getNavigationFlashFromTool(pendingToolCall.tool, pendingToolCall.args);\n if (flashTarget) {\n triggerNavigationFlash(flashTarget.group, flashTarget.item);\n }\n }\n }\n pendingToolCallsRef.current = {\n ...pendingToolCallsRef.current,\n [sessionId]: null,\n };\n updateSessionMessages(sessionId, (prev) => [\n ...prev,\n {\n type: \"tool_result\",\n content: String(data.summary || \"\"),\n tool: data.tool as string,\n success: Boolean(data.success),\n },\n ]);\n return;\n }\n\n if (eventType === \"complete\" && sessionId) {\n setSessionThinking(sessionId, false);\n updateSessionMessages(sessionId, (prev) => prev.filter((message) => message.type !== \"thinking\"));\n return;\n }\n\n if (eventType === \"error\") {\n if (requestId) {\n return;\n }\n\n if (sessionId) {\n setSessionThinking(sessionId, false);\n updateSessionMessages(sessionId, (prev) => [\n ...prev.filter((message) => message.type !== \"thinking\"),\n { type: \"error\", content: String(data.content || \"Chat error.\") },\n ]);\n }\n }\n } catch {\n // Ignore malformed socket events.\n }\n };\n\n ws.onerror = () => {\n ws.close();\n };\n\n ws.onclose = (event) => {\n if (wsRef.current === ws) {\n wsRef.current = null;\n }\n rejectPendingRequests(\"Chat disconnected.\");\n setConnectionStatus(\"disconnected\");\n if (disposed) return;\n if (event.code === 4001 || event.code === 4003) {\n window.location.href = \"/login\";\n return;\n }\n reconnectTimerRef.current = window.setTimeout(connect, 3000);\n };\n }\n\n connect();\n\n return () => {\n disposed = true;\n if (reconnectTimerRef.current !== null) {\n window.clearTimeout(reconnectTimerRef.current);\n }\n if (navFlashTimeoutRef.current !== null) {\n window.clearTimeout(navFlashTimeoutRef.current);\n }\n rejectPendingRequests(\"Chat disconnected.\");\n if (wsRef.current) {\n const ws = wsRef.current;\n wsRef.current = null;\n ws.close();\n }\n };\n }, []);\n\n async function createSession(): Promise<ChatSession> {\n if (pendingCreateSessionRef.current) {\n return pendingCreateSessionRef.current;\n }\n\n const promise = sendRequest(\"create_session\", {}, \"session_created\")\n .then((data) => data.session as ChatSession)\n .finally(() => {\n if (pendingCreateSessionRef.current === promise) {\n pendingCreateSessionRef.current = null;\n }\n });\n\n pendingCreateSessionRef.current = promise;\n return promise;\n }\n\n async function startDemo(sessionId: string): Promise<void> {\n setSessionDemoStatus(sessionId, \"running\");\n setSessionDemoTypingCue(sessionId, null);\n try {\n await sendRequest(\"start_demo\", { session_id: sessionId }, \"demo_started\");\n } catch (error) {\n setSessionDemoStatus(sessionId, \"idle\");\n throw error;\n }\n }\n\n function completeDemoTyping(sessionId: string, seq: number): void {\n try {\n sendRaw({ type: \"demo_typing_done\", session_id: sessionId, seq });\n } catch {\n // Ignore dropped acknowledgements; backend has a timeout fallback.\n }\n }\n\n async function deleteSession(sessionId: string): Promise<void> {\n await sendRequest(\"delete_session\", { session_id: sessionId }, \"session_deleted\");\n }\n\n async function loadHistory(sessionId: string): Promise<void> {\n await sendRequest(\"load_history\", { session_id: sessionId }, \"history_loaded\");\n }\n\n async function loadMoreHistory(sessionId: string): Promise<void> {\n if (loadingOlderBySession[sessionId]) return;\n const oldestId = oldestIdBySession[sessionId];\n if (oldestId == null) return;\n if (!hasMoreBySession[sessionId]) return;\n setLoadingOlderBySession((prev) => ({ ...prev, [sessionId]: true }));\n try {\n await sendRequest(\n \"load_history\",\n { session_id: sessionId, before_id: oldestId },\n \"history_loaded\",\n );\n } catch (error) {\n setLoadingOlderBySession((prev) => ({ ...prev, [sessionId]: false }));\n throw error;\n }\n }\n\n async function clearHistory(sessionId: string): Promise<void> {\n await sendRequest(\"clear_history\", { session_id: sessionId }, \"history_cleared\");\n }\n\n function sendMessage(sessionId: string, content: string, attachmentIds?: string[]): boolean {\n const trimmed = content.trim();\n const hasAttachments = (attachmentIds?.length ?? 0) > 0;\n if (!trimmed && !hasAttachments) return false;\n\n try {\n setSessionThinking(sessionId, true);\n const payload: Record<string, unknown> = {\n type: \"send_message\",\n session_id: sessionId,\n content: trimmed,\n };\n if (hasAttachments) payload.attachment_ids = attachmentIds;\n sendRaw(payload);\n return true;\n } catch {\n setSessionThinking(sessionId, false);\n return false;\n }\n }\n\n async function transcribeAudio(audioBase64: string, audioFormat: string, sessionId?: string): Promise<string> {\n const data = await sendRequest(\n \"transcribe\",\n { audio_data: audioBase64, audio_format: audioFormat, session_id: sessionId },\n \"transcription_result\",\n );\n if (!data.success) {\n throw new Error(typeof data.error === \"string\" ? data.error : \"Transcription failed.\");\n }\n return typeof data.text === \"string\" ? data.text : \"\";\n }\n\n function getMessages(sessionId?: string): ChatMessage[] {\n if (!sessionId) return [];\n return messagesBySession[sessionId] ?? [];\n }\n\n function isThinking(sessionId?: string): boolean {\n if (!sessionId) return false;\n return Boolean(thinkingBySession[sessionId]);\n }\n\n function hasMoreHistory(sessionId?: string): boolean {\n if (!sessionId) return false;\n return Boolean(hasMoreBySession[sessionId]);\n }\n\n function isLoadingOlder(sessionId?: string): boolean {\n if (!sessionId) return false;\n return Boolean(loadingOlderBySession[sessionId]);\n }\n\n function getDemoStatus(sessionId?: string): \"idle\" | \"running\" | \"complete\" {\n if (!sessionId) return \"idle\";\n return demoStatusBySession[sessionId] ?? \"idle\";\n }\n\n function getDemoTypingCue(sessionId?: string): { content: string; seq: number; typingMs: number } | null {\n if (!sessionId) return null;\n return demoTypingCueBySession[sessionId] ?? null;\n }\n\n return (\n <ChatContext.Provider\n value={{\n sessions,\n connectionStatus,\n connectionVersion,\n navigationFlash,\n createSession,\n startDemo,\n completeDemoTyping,\n deleteSession,\n loadHistory,\n loadMoreHistory,\n clearHistory,\n sendMessage,\n transcribeAudio,\n getMessages,\n hasMoreHistory,\n isLoadingOlder,\n isThinking,\n getDemoStatus,\n getDemoTypingCue,\n }}\n >\n {children}\n </ChatContext.Provider>\n );\n}\n\nexport function useChat(): ChatContextValue {\n const context = useContext(ChatContext);\n if (!context) {\n throw new Error(\"useChat must be used within ChatProvider.\");\n }\n return context;\n}\n","/** Merge class names (simplified clsx). */\nexport function cn(...classes: (string | false | null | undefined)[]) {\n return classes.filter(Boolean).join(\" \");\n}\n\n/** Format a number as currency. */\nexport function formatCurrency(value: number | null | undefined, currency = \"USD\") {\n return new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency,\n minimumFractionDigits: 2,\n }).format(value ?? 0);\n}\n\n/** Format a number with commas. */\nexport function formatNumber(value: number | null | undefined, decimals = 2) {\n return new Intl.NumberFormat(\"en-US\", {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n }).format(value ?? 0);\n}\n\n// Display locale for dates. Default: the viewer's browser locale — the old\n// hardcoded \"en-US\" forced US month/day order (and English month names) on\n// every deployment. A deployment can pin it, e.g. setDateLocale(\"de-CH\") for\n// DD.MM.YYYY everywhere, regardless of the viewer's browser.\nlet dateLocale: string | undefined;\n\n/** Pin the locale used by formatDate (undefined = the viewer's browser locale). */\nexport function setDateLocale(locale: string | undefined) {\n dateLocale = locale;\n}\n\n/** Format a date string for display (numeric, day-first per the locale). */\nexport function formatDate(value: string | null | undefined) {\n if (!value) return \"\";\n return new Date(value).toLocaleDateString(dateLocale, {\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n });\n}\n\n/** Safely parse a float, defaulting to 0. */\nexport function flt(value: unknown, precision?: number): number {\n const n = parseFloat(String(value ?? 0)) || 0;\n return precision !== undefined ? parseFloat(n.toFixed(precision)) : n;\n}\n","import { cn } from \"@/lib/utils\";\n\nconst variantClasses: Record<string, string> = {\n // Primary: brand-coloured fill + a 1px inset top highlight for depth\n // (button-highlight shadow). On press, the button shifts down 1px —\n // tiny detail, large perceived \"this is responsive\".\n primary:\n \"bg-brand text-brand-fg shadow-button-highlight hover:bg-brand/90 active:translate-y-px focus-visible:ring-brand/40\",\n secondary:\n \"bg-surface text-fg ring-1 ring-line hover:bg-surface-subtle active:translate-y-px focus-visible:ring-fg/20\",\n danger:\n \"bg-red-600 text-white shadow-button-highlight hover:bg-red-700 active:translate-y-px focus-visible:ring-red-500/40\",\n ghost:\n \"bg-transparent text-fg-muted hover:bg-surface-subtle hover:text-fg focus-visible:ring-fg/20\",\n};\n\nconst sizeClasses: Record<string, string> = {\n sm: \"h-8 px-3 text-sm\",\n md: \"h-10 px-4 text-sm\",\n lg: \"h-11 px-5 text-sm\",\n};\n\ninterface ButtonProps {\n variant?: \"primary\" | \"secondary\" | \"danger\" | \"ghost\";\n size?: \"sm\" | \"md\" | \"lg\";\n disabled?: boolean;\n onClick?: React.MouseEventHandler<HTMLButtonElement>;\n children: React.ReactNode;\n className?: string;\n type?: \"button\" | \"submit\" | \"reset\";\n}\n\nexport function Button({\n variant = \"primary\",\n size = \"md\",\n disabled,\n onClick,\n children,\n className,\n type = \"button\",\n}: ButtonProps) {\n return (\n <button\n type={type}\n disabled={disabled}\n onClick={onClick}\n className={cn(\n // Layout + base interaction. focus-visible (not :focus) so\n // mouse clicks don't leave a permanent ring; only keyboard\n // navigation gets the visible outline.\n \"inline-flex items-center justify-center gap-2 rounded-lg font-medium\",\n \"transition-all duration-150\",\n \"focus-visible:outline-none focus-visible:ring-2\",\n \"disabled:cursor-not-allowed disabled:opacity-50 disabled:active:translate-y-0\",\n variantClasses[variant],\n sizeClasses[size],\n className,\n )}\n >\n {children}\n </button>\n );\n}\n","import { cn } from \"@/lib/utils\";\n\ninterface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n label?: string;\n /** Optional helper text below the input. */\n hint?: string;\n /** Error text — when set, overrides hint and shows a red border. */\n error?: string;\n}\n\nexport function Input({ label, hint, error, className, id, ...props }: InputProps) {\n const inputId = id || (label ? label.toLowerCase().replace(/\\s+/g, \"-\") : undefined);\n\n return (\n <div>\n {label && (\n <label\n htmlFor={inputId}\n className=\"mb-1.5 block text-sm font-medium text-fg\"\n >\n {label}\n </label>\n )}\n <input\n id={inputId}\n aria-invalid={!!error || undefined}\n aria-describedby={error || hint ? `${inputId}-help` : undefined}\n className={cn(\n // Bigger touch target (h-10) than the previous py-2 default;\n // brand-coloured halo on focus instead of a single hard ring.\n // text-sm is fine on desktop; the global media-query in\n // index.css forces 16px on mobile to suppress iOS auto-zoom.\n \"block h-10 w-full rounded-lg bg-surface px-3 text-sm text-fg\",\n \"ring-1 ring-line transition-all\",\n \"placeholder:text-fg-muted/70\",\n \"focus:outline-none focus:ring-2 focus:ring-brand/30 focus:border-transparent\",\n \"disabled:cursor-not-allowed disabled:bg-surface-subtle disabled:text-fg-muted\",\n error && \"ring-red-400 focus:ring-red-400/30\",\n className,\n )}\n {...props}\n />\n {(error || hint) && (\n <p\n id={`${inputId}-help`}\n className={cn(\n \"mt-1.5 text-xs\",\n error ? \"text-red-600\" : \"text-fg-muted\",\n )}\n >\n {error || hint}\n </p>\n )}\n </div>\n );\n}\n","// Shared, styled confirm/prompt dialogs — a replacement for window.confirm /\n// window.prompt. Mount <DialogProvider> once (AppShell does), then anywhere in\n// the tree call the useConfirm() / usePrompt() hooks:\n//\n// const confirm = useConfirm();\n// if (await confirm({ title: \"Delete?\", danger: true })) { ... }\n//\n// const prompt = usePrompt();\n// const name = await prompt({ title: \"Rename\", defaultValue: current });\n//\n// For low-stakes, in-row actions prefer <ConfirmButton> (confirm-button.tsx),\n// which arms inline instead of opening a modal.\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n type ReactNode,\n} from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\n\ntype ConfirmOpts = {\n title: string;\n body?: ReactNode;\n confirmLabel?: string;\n cancelLabel?: string;\n danger?: boolean;\n};\n\ntype PromptOpts = ConfirmOpts & {\n defaultValue?: string;\n placeholder?: string;\n inputType?: \"text\" | \"date\" | \"number\";\n};\n\ntype DialogState =\n | { kind: \"confirm\"; opts: ConfirmOpts; resolve: (v: boolean) => void }\n | { kind: \"prompt\"; opts: PromptOpts; resolve: (v: string | null) => void }\n | null;\n\ntype DialogApi = {\n confirm: (opts: ConfirmOpts) => Promise<boolean>;\n prompt: (opts: PromptOpts) => Promise<string | null>;\n};\n\nconst DialogContext = createContext<DialogApi | null>(null);\n\nexport function DialogProvider({ children }: { children: ReactNode }) {\n const { t } = useTranslation();\n const [state, setState] = useState<DialogState>(null);\n const [value, setValue] = useState(\"\");\n\n const confirm = useCallback(\n (opts: ConfirmOpts) =>\n new Promise<boolean>((resolve) => setState({ kind: \"confirm\", opts, resolve })),\n [],\n );\n const prompt = useCallback(\n (opts: PromptOpts) =>\n new Promise<string | null>((resolve) => {\n setValue(opts.defaultValue ?? \"\");\n setState({ kind: \"prompt\", opts, resolve });\n }),\n [],\n );\n\n const api = useMemo<DialogApi>(() => ({ confirm, prompt }), [confirm, prompt]);\n\n const settle = (result: boolean | string | null) => {\n if (!state) return;\n (state.resolve as (v: boolean | string | null) => void)(result);\n setState(null);\n };\n const onConfirm = () => settle(state?.kind === \"prompt\" ? value : true);\n const onCancel = () => settle(state?.kind === \"prompt\" ? null : false);\n\n return (\n <DialogContext.Provider value={api}>\n {children}\n {state && (\n <div\n className=\"fixed inset-0 z-[100] flex items-center justify-center p-4\"\n role=\"dialog\"\n aria-modal=\"true\"\n onKeyDown={(e) => {\n if (e.key === \"Escape\") onCancel();\n }}\n >\n <div className=\"absolute inset-0 bg-black/40 backdrop-blur-[1px]\" onClick={onCancel} />\n <div className=\"relative w-full max-w-md rounded-xl bg-surface p-5 shadow-card ring-1 ring-line\">\n <h2 className=\"text-lg font-semibold text-fg\">{state.opts.title}</h2>\n {state.opts.body != null && (\n <div className=\"mt-2 text-sm text-fg-muted\">{state.opts.body}</div>\n )}\n {state.kind === \"prompt\" && (\n <Input\n autoFocus\n type={state.opts.inputType ?? \"text\"}\n placeholder={state.opts.placeholder}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") onConfirm();\n }}\n className=\"mt-3\"\n />\n )}\n <div className=\"mt-5 flex justify-end gap-2\">\n <Button variant=\"secondary\" onClick={onCancel}>\n {state.opts.cancelLabel ?? t(\"common.cancel\", { defaultValue: \"Cancel\" })}\n </Button>\n <Button variant={state.opts.danger ? \"danger\" : \"primary\"} onClick={onConfirm}>\n {state.opts.confirmLabel ?? t(\"common.ok\", { defaultValue: \"OK\" })}\n </Button>\n </div>\n </div>\n </div>\n )}\n </DialogContext.Provider>\n );\n}\n\nfunction useDialog(): DialogApi {\n const ctx = useContext(DialogContext);\n if (!ctx) throw new Error(\"useConfirm/usePrompt must be used within <DialogProvider>\");\n return ctx;\n}\n\n/** Returns confirm(opts) => Promise<boolean>. Replaces window.confirm. */\nexport function useConfirm() {\n return useDialog().confirm;\n}\n\n/** Returns prompt(opts) => Promise<string|null>. Replaces window.prompt. */\nexport function usePrompt() {\n return useDialog().prompt;\n}\n","/**\n * Sidebar navigation registry.\n *\n * The default groups below drive the demo app's sidebar. A customer\n * deployment built on the published library can add a group, append items to\n * an existing group, or replace a group wholesale via the registration\n * helpers — without editing the sidebar component. The sidebar reads the\n * registry live (getNavGroups), so registrations made at startup show up.\n */\nimport type { ReactNode } from \"react\";\nimport {\n FileText,\n BarChart3,\n Database,\n Package,\n ShoppingCart,\n CreditCard,\n BookOpen,\n Settings,\n} from \"lucide-react\";\n\nexport interface NavItem {\n label: string;\n path: string;\n}\n\nexport interface NavGroup {\n label: string;\n icon: ReactNode;\n items: NavItem[];\n}\n\nconst NAV_GROUPS: NavGroup[] = [\n {\n label: \"Introduction\",\n icon: <BookOpen className=\"h-4 w-4\" />,\n items: [\n { label: \"Getting Started\", path: \"/tutorial\" },\n { label: \"Company Setup\", path: \"/setup\" },\n { label: \"Opening Balances\", path: \"/setup/opening-balances\" },\n ],\n },\n {\n label: \"Selling\",\n icon: <ShoppingCart className=\"h-4 w-4\" />,\n items: [\n { label: \"Quotation\", path: \"/app/quotation\" },\n { label: \"Proposal\", path: \"/app/proposal\" },\n { label: \"Sales Order\", path: \"/app/sales-order\" },\n { label: \"Sales Invoice\", path: \"/app/sales-invoice\" },\n { label: \"POS Invoice\", path: \"/app/pos-invoice\" },\n ],\n },\n {\n label: \"Buying\",\n icon: <CreditCard className=\"h-4 w-4\" />,\n items: [\n { label: \"Purchase Order\", path: \"/app/purchase-order\" },\n { label: \"Purchase Invoice\", path: \"/app/purchase-invoice\" },\n ],\n },\n {\n label: \"Accounting\",\n icon: <FileText className=\"h-4 w-4\" />,\n items: [\n { label: \"Chart of Accounts\", path: \"/reports/chart-of-accounts\" },\n { label: \"Payment Entry\", path: \"/app/payment-entry\" },\n { label: \"Journal Entry\", path: \"/app/journal-entry\" },\n { label: \"Bank Transaction\", path: \"/app/bank-transaction\" },\n { label: \"Budget\", path: \"/app/budget\" },\n { label: \"Subscription\", path: \"/app/subscription\" },\n ],\n },\n {\n label: \"Stock\",\n icon: <Package className=\"h-4 w-4\" />,\n items: [\n { label: \"Stock Entry\", path: \"/app/stock-entry\" },\n { label: \"Delivery Note\", path: \"/app/delivery-note\" },\n { label: \"Purchase Receipt\", path: \"/app/purchase-receipt\" },\n ],\n },\n {\n label: \"Reports\",\n icon: <BarChart3 className=\"h-4 w-4\" />,\n items: [\n { label: \"Trial Balance\", path: \"/reports/trial-balance\" },\n { label: \"Profit & Loss\", path: \"/reports/profit-and-loss\" },\n { label: \"Balance Sheet\", path: \"/reports/balance-sheet\" },\n { label: \"General Ledger\", path: \"/reports/general-ledger\" },\n { label: \"AR Aging\", path: \"/reports/ar-aging\" },\n { label: \"AP Aging\", path: \"/reports/ap-aging\" },\n { label: \"Analytics\", path: \"/reports/analytics\" },\n { label: \"Stock Balance\", path: \"/reports/stock-balance\" },\n ],\n },\n {\n label: \"Masters\",\n icon: <Database className=\"h-4 w-4\" />,\n items: [\n { label: \"Company\", path: \"/masters/company\" },\n { label: \"Customer\", path: \"/masters/customer\" },\n { label: \"Supplier\", path: \"/masters/supplier\" },\n { label: \"Item\", path: \"/masters/item\" },\n { label: \"Warehouse\", path: \"/masters/warehouse\" },\n ],\n },\n {\n label: \"Settings\",\n icon: <Settings className=\"h-4 w-4\" />,\n items: [\n { label: \"General\", path: \"/admin/settings\" },\n { label: \"Pricing Rule\", path: \"/app/pricing-rule\" },\n { label: \"Users & Team\", path: \"/admin/users\" },\n ],\n },\n];\n\n/** Live list the sidebar renders from. */\nexport function getNavGroups(): NavGroup[] {\n return NAV_GROUPS;\n}\n\n/**\n * Add a nav group, or replace an existing one with the same label. Pass\n * `index` to control placement (default: appended at the end).\n */\nexport function registerNavGroup(group: NavGroup, opts?: { index?: number }) {\n const existing = NAV_GROUPS.findIndex((g) => g.label === group.label);\n if (existing >= 0) {\n NAV_GROUPS[existing] = group;\n return;\n }\n if (opts?.index != null) {\n NAV_GROUPS.splice(opts.index, 0, group);\n } else {\n NAV_GROUPS.push(group);\n }\n}\n\n/** Append an item to an existing group (creating the group if absent). */\nexport function registerNavItem(groupLabel: string, item: NavItem) {\n const group = NAV_GROUPS.find((g) => g.label === groupLabel);\n if (group) {\n group.items.push(item);\n } else {\n NAV_GROUPS.push({ label: groupLabel, icon: null, items: [item] });\n }\n}\n","/**\n * Branding / theme configuration.\n *\n * The visual theme is already CSS-variable based (see index.css `:root`\n * tokens, surfaced to Tailwind as `brand`, `surface`, `fg`, `line`, …). A\n * customer deployment built on the published library rebrands by calling\n * `configureBranding` at startup: override the product name, point at a logo,\n * and/or override any of the `:root` design tokens at runtime.\n *\n * For deeper restyling the customer's own Tailwind build (which scans this\n * package — the \"consumer scans source\" model) can add utilities freely; this\n * helper covers the common case of swapping name/logo/colors without a custom\n * stylesheet.\n */\nexport interface Branding {\n /** Product name — used for the document title and as the sidebar fallback. */\n appName: string;\n /** Optional logo URL (falls back to the core CSS-mask logo when unset). */\n logoUrl?: string;\n /**\n * CSS custom properties to set on :root, e.g. { \"--brand\": \"260 80% 55%\" }.\n * The leading \"--\" is optional. Values follow the token format in index.css\n * (HSL channel triplets for color tokens).\n */\n tokens?: Record<string, string>;\n}\n\nlet branding: Branding = { appName: \"Lambda ERP\" };\n\nexport function configureBranding(next: Partial<Branding>) {\n branding = { ...branding, ...next };\n if (typeof document === \"undefined\") return;\n if (next.appName) document.title = next.appName;\n if (next.tokens) {\n const root = document.documentElement;\n for (const [key, value] of Object.entries(next.tokens)) {\n root.style.setProperty(key.startsWith(\"--\") ? key : `--${key}`, value);\n }\n }\n}\n\nexport function getBranding(): Branding {\n return branding;\n}\n","import { useState, useCallback, useEffect, useMemo } from \"react\";\nimport { NavLink, useLocation, useNavigate } from \"react-router-dom\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useTranslation } from \"react-i18next\";\nimport { api } from \"@/api/client\";\n\n// --- Persist collapsed sidebar groups in localStorage ---\nconst STORAGE_KEY = \"sidebar-collapsed\";\n\nfunction getCollapsed(): Set<string> {\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n return raw ? new Set(JSON.parse(raw)) : new Set();\n } catch {\n return new Set();\n }\n}\n\nfunction setCollapsed(collapsed: Set<string>) {\n localStorage.setItem(STORAGE_KEY, JSON.stringify([...collapsed]));\n}\n\nfunction useSidebarToggle(key: string) {\n const [open, setOpen] = useState(() => !getCollapsed().has(key));\n const toggle = useCallback(() => {\n setOpen((prev) => {\n const collapsed = getCollapsed();\n if (prev) {\n collapsed.add(key);\n } else {\n collapsed.delete(key);\n }\n setCollapsed(collapsed);\n return !prev;\n });\n }, [key]);\n const expand = useCallback(() => {\n setOpen((prev) => {\n if (prev) return prev;\n const collapsed = getCollapsed();\n collapsed.delete(key);\n setCollapsed(collapsed);\n return true;\n });\n }, [key]);\n return [open, toggle, expand] as const;\n}\nimport {\n MessageCircle,\n ChevronDown,\n ChevronRight,\n Plus,\n Trash2,\n LineChart,\n} from \"lucide-react\";\nimport { useMutation } from \"@tanstack/react-query\";\nimport { useChat } from \"@/components/chat/chat-provider\";\nimport { getNavGroups, type NavGroup } from \"@/lib/nav\";\nimport { getBranding } from \"@/lib/branding\";\nimport { cn } from \"@/lib/utils\";\n\nexport const FLASH_STYLES: Record<string, string> = {\n \"Introduction\": \"bg-fuchsia-300 text-fuchsia-950 ring-2 ring-inset ring-fuchsia-100\",\n \"Selling\": \"bg-emerald-300 text-emerald-950 ring-2 ring-inset ring-emerald-100\",\n \"Buying\": \"bg-rose-300 text-rose-950 ring-2 ring-inset ring-rose-100\",\n \"Accounting\": \"bg-amber-300 text-amber-950 ring-2 ring-inset ring-amber-100\",\n \"Stock\": \"bg-blue-300 text-blue-950 ring-2 ring-inset ring-blue-100\",\n \"Reports\": \"bg-indigo-300 text-indigo-950 ring-2 ring-inset ring-indigo-100\",\n \"Masters\": \"bg-lime-300 text-lime-950 ring-2 ring-inset ring-lime-100\",\n \"Settings\": \"bg-purple-300 text-purple-950 ring-2 ring-inset ring-purple-100\",\n \"Custom Analytics\": \"bg-indigo-300 text-indigo-950 ring-2 ring-inset ring-indigo-100\",\n};\n\nfunction ChatGroup() {\n const [open, toggle] = useSidebarToggle(\"chats\");\n const location = useLocation();\n const navigate = useNavigate();\n const { t } = useTranslation();\n const { sessions, createSession, deleteSession } = useChat();\n\n const handleNewChat = async () => {\n try {\n const session = await createSession();\n navigate(`/chat/${session.id}`);\n } catch {\n // ignore\n }\n };\n\n const handleDelete = async (e: React.MouseEvent, sessionId: string) => {\n e.preventDefault();\n e.stopPropagation();\n try {\n await deleteSession(sessionId);\n // If we deleted the active chat, navigate away\n if (window.location.pathname === `/chat/${sessionId}`) {\n navigate(\"/\");\n }\n } catch {\n // ignore\n }\n };\n\n return (\n <div>\n <button\n type=\"button\"\n onClick={toggle}\n className=\"flex w-full items-center gap-2 px-4 py-2 text-xs font-semibold uppercase tracking-wider text-fg-muted transition-colors hover:text-fg\"\n >\n <MessageCircle className=\"h-4 w-4\" />\n <span className=\"flex-1 text-left\">{t(\"nav.chats\")}</span>\n {open ? (\n <ChevronDown className=\"h-3.5 w-3.5\" />\n ) : (\n <ChevronRight className=\"h-3.5 w-3.5\" />\n )}\n </button>\n {open && (\n <ul className=\"mb-1\">\n {/* New Chat button */}\n <li>\n <button\n onClick={handleNewChat}\n className=\"flex w-full items-center gap-2 px-4 py-1.5 pl-10 text-sm text-brand transition-colors hover:bg-brand/5\"\n >\n <Plus className=\"h-3.5 w-3.5\" />\n {t(\"nav.newChat\")}\n </button>\n </li>\n {/* Existing sessions */}\n {sessions.map((session) => {\n const active = location.pathname === `/chat/${session.id}`;\n return (\n <li key={session.id} className=\"group relative\">\n <NavLink\n to={`/chat/${session.id}`}\n className={cn(\n \"relative block truncate px-4 py-1.5 pl-10 pr-8 text-sm transition-colors\",\n active\n ? \"bg-surface-subtle font-medium text-fg\"\n : \"text-fg-muted hover:bg-surface-subtle hover:text-fg\",\n )}\n >\n {session.title}\n </NavLink>\n {active && <ActiveAccent />}\n <button\n onClick={(e) => handleDelete(e, session.id)}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 rounded p-0.5 text-fg-muted opacity-0 transition-opacity hover:text-red-500 group-hover:opacity-100\"\n title={t(\"nav.deleteChat\")}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </button>\n </li>\n );\n })}\n </ul>\n )}\n </div>\n );\n}\n\n/** 2px brand-colored accent strip on the left edge — Linear-style\n * active indicator. Pulled out so all three nav patterns (chats,\n * custom analytics, generic groups) reuse one definition. */\nfunction ActiveAccent() {\n return (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-0 top-1/2 h-5 w-[2px] -translate-y-1/2 rounded-r bg-brand\"\n />\n );\n}\n\nfunction CustomAnalyticsGroup() {\n const [open, toggle, expand] = useSidebarToggle(\"custom-analytics\");\n const location = useLocation();\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n const { t } = useTranslation();\n const { navigationFlash, sessions, createSession } = useChat();\n const isGroupFlashing = navigationFlash?.group === \"Custom Analytics\";\n const flashStyle = FLASH_STYLES[\"Custom Analytics\"];\n\n const { data } = useQuery({\n queryKey: [\"runtime-drafts\"],\n queryFn: () => api.listRuntimeDrafts(),\n staleTime: 30_000,\n });\n const drafts = data?.drafts ?? [];\n\n // Any flash targeting this group should expand the group, refetch the\n // draft list, and let the row-level flash animation draw attention to\n // the newly-created / touched entry.\n useEffect(() => {\n if (navigationFlash?.group !== \"Custom Analytics\") return;\n expand();\n queryClient.invalidateQueries({ queryKey: [\"runtime-drafts\"] });\n }, [navigationFlash?.key, queryClient, expand]);\n\n const deleteMutation = useMutation({\n mutationFn: (id: string) => api.deleteRuntimeDraft(id),\n onSuccess: (_result, id) => {\n queryClient.invalidateQueries({ queryKey: [\"runtime-drafts\"] });\n const match = location.search.includes(`report_id=${id}`);\n if (match) navigate(\"/reports/analytics\");\n },\n });\n\n const handleDelete = async (e: React.MouseEvent, id: string) => {\n e.preventDefault();\n e.stopPropagation();\n deleteMutation.mutate(id);\n };\n\n const handleNew = async () => {\n const prefill =\n \"Build me a custom analytics report: <describe what you want — e.g. top 10 customers by revenue for the last quarter, or monthly purchases trend by supplier>\";\n let targetSessionId = sessions[0]?.id || \"\";\n if (!targetSessionId) {\n try {\n const created = await createSession();\n targetSessionId = created.id;\n } catch {\n navigate(\"/reports/analytics\");\n return;\n }\n }\n navigate(`/chat/${targetSessionId}`, { state: { prefillMessage: prefill } });\n };\n\n return (\n <div>\n <button\n type=\"button\"\n onClick={toggle}\n className={cn(\n \"flex w-full items-center gap-2 px-4 py-2 text-xs font-semibold uppercase tracking-wider text-fg-muted transition-all duration-300 hover:text-fg\",\n isGroupFlashing && flashStyle,\n )}\n >\n <LineChart className=\"h-4 w-4\" />\n <span className=\"flex-1 text-left\">{t(\"nav.customAnalytics\")}</span>\n {open ? (\n <ChevronDown className=\"h-3.5 w-3.5\" />\n ) : (\n <ChevronRight className=\"h-3.5 w-3.5\" />\n )}\n </button>\n {open && (\n <ul className=\"mb-1\">\n <li>\n <button\n onClick={handleNew}\n className=\"flex w-full items-center gap-2 px-4 py-1.5 pl-10 text-sm text-brand transition-colors hover:bg-brand/5\"\n >\n <Plus className=\"h-3.5 w-3.5\" />\n {t(\"nav.newAnalytics\")}\n </button>\n </li>\n {drafts.map((draft) => {\n const path = `/reports/analytics?report_id=${draft.id}`;\n const active = location.pathname === \"/reports/analytics\" && location.search.includes(`report_id=${draft.id}`);\n const isItemFlashing =\n navigationFlash?.group === \"Custom Analytics\" &&\n navigationFlash?.item === draft.id;\n return (\n <li key={draft.id} className=\"group relative\">\n <NavLink\n to={path}\n className={cn(\n \"relative block truncate px-4 py-1.5 pl-10 pr-8 text-sm transition-all duration-300\",\n !active && \"text-fg-muted hover:bg-surface-subtle hover:text-fg\",\n active && \"bg-surface-subtle font-medium text-fg\",\n isItemFlashing && flashStyle,\n )}\n title={draft.title}\n >\n {draft.title}\n </NavLink>\n {active && <ActiveAccent />}\n <button\n onClick={(e) => handleDelete(e, draft.id)}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 rounded p-0.5 text-fg-muted opacity-0 transition-opacity hover:text-red-500 group-hover:opacity-100\"\n title={t(\"nav.deleteReport\")}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </button>\n </li>\n );\n })}\n </ul>\n )}\n </div>\n );\n}\n\nfunction SidebarGroup({ group }: { group: NavGroup }) {\n const [open, toggle] = useSidebarToggle(group.label);\n const { t } = useTranslation();\n const { navigationFlash } = useChat();\n const isGroupFlashing = navigationFlash?.group === group.label;\n const flashStyle = FLASH_STYLES[group.label] ?? \"bg-blue-300 text-blue-950 ring-2 ring-inset ring-blue-100\";\n\n return (\n <div>\n <button\n type=\"button\"\n onClick={toggle}\n className={cn(\n \"flex w-full items-center gap-2 px-4 py-2 text-xs font-semibold uppercase tracking-wider text-fg-muted transition-all duration-300 hover:text-fg\",\n isGroupFlashing && flashStyle,\n )}\n >\n {group.icon}\n <span className=\"flex-1 text-left\">{t(`nav.groups.${group.label}`, { defaultValue: group.label })}</span>\n {open ? (\n <ChevronDown className=\"h-3.5 w-3.5\" />\n ) : (\n <ChevronRight className=\"h-3.5 w-3.5\" />\n )}\n </button>\n {open && (\n <ul className=\"mb-1\">\n {group.items.map((item) => {\n // Exact matching when another item's path is nested under this one\n // (e.g. /setup vs /setup/opening-balances). Without `end`, NavLink\n // treats the shorter path as active on the longer one's page, so\n // both rows highlight grey at once.\n const end = group.items.some(\n (other) => other.path !== item.path && other.path.startsWith(item.path + \"/\"),\n );\n return (\n <li key={item.path} className=\"relative\">\n <NavLink\n to={item.path}\n end={end}\n className={({ isActive }) =>\n cn(\n \"relative block px-4 py-1.5 pl-10 text-sm transition-all duration-300\",\n !isActive && \"text-fg-muted hover:bg-surface-subtle hover:text-fg\",\n isActive && \"bg-surface-subtle font-medium text-fg\",\n navigationFlash?.group === group.label && navigationFlash?.item === item.label &&\n flashStyle,\n )\n }\n >\n {({ isActive }) => (\n <>\n {isActive && <ActiveAccent />}\n {t(`nav.items.${item.label}`, { defaultValue: item.label })}\n </>\n )}\n </NavLink>\n </li>\n );\n })}\n </ul>\n )}\n </div>\n );\n}\n\nconst HIDDEN_PATHS: Record<string, string> = {\n \"/setup/opening-balances\": \"opening_balances_enabled\",\n};\n\ninterface SidebarProps {\n isMobileOpen?: boolean;\n onClose?: () => void;\n}\n\nexport function Sidebar({ isMobileOpen = false, onClose }: SidebarProps) {\n const { data: settings } = useQuery({\n queryKey: [\"settings\"],\n queryFn: () => api.getSettings(),\n staleTime: 60_000,\n });\n\n const { data: setupStatus } = useQuery({\n queryKey: [\"setup-status\"],\n queryFn: () => api.setupStatus(),\n staleTime: 60_000,\n });\n\n const firstCompany = setupStatus?.companies?.[0];\n const companyName: string =\n firstCompany?.company_name || firstCompany?.name || getBranding().appName;\n\n const groups = useMemo(() => {\n const base = getNavGroups();\n return base.map((group) => ({\n ...group,\n items: group.items.filter((item) => {\n // Company Setup is a one-time step — hide it once a company exists.\n if (item.path === \"/setup\" && setupStatus?.setup_complete) return false;\n // Settings-gated items (default to shown until settings load).\n const settingKey = HIDDEN_PATHS[item.path];\n if (!settingKey) return true;\n if (!settings) return true;\n return settings[settingKey] !== \"0\";\n }),\n }));\n }, [settings, setupStatus]);\n\n return (\n <aside\n className={cn(\n \"fixed left-0 top-0 z-40 flex h-dvh w-64 flex-col border-r border-line bg-surface transition-transform duration-300 ease-out\",\n \"md:translate-x-0\",\n isMobileOpen ? \"translate-x-0 shadow-2xl\" : \"-translate-x-full\",\n )}\n >\n <div className=\"relative flex h-10 items-center justify-center gap-3 border-b border-line px-4\">\n <NavLink\n to=\"/\"\n className=\"min-w-0 truncate text-base font-semibold text-fg-muted transition-colors hover:text-brand\"\n title={`${companyName} — Dashboard`}\n >\n {companyName}\n </NavLink>\n <div className=\"hidden h-4 w-px shrink-0 bg-line md:block\" aria-hidden=\"true\" />\n <a\n href=\"https://lambda.dev/erp\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label=\"Lambda ERP\"\n title=\"Lambda ERP\"\n className=\"hidden shrink-0 md:block\"\n >\n <span className=\"lambda-logo-icon block\" role=\"img\" aria-label=\"Lambda ERP\" />\n </a>\n {/* Close button — mobile only. Absolute so it doesn't offset centering. */}\n <button\n onClick={onClose}\n className=\"absolute right-3 top-1/2 -translate-y-1/2 rounded p-1 text-fg-muted transition-colors hover:bg-surface-subtle hover:text-fg md:hidden\"\n aria-label=\"Close menu\"\n >\n <svg viewBox=\"0 0 20 20\" width=\"18\" height=\"18\" fill=\"currentColor\">\n <path d=\"M10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 011.414-1.414L10 8.586z\" />\n </svg>\n </button>\n </div>\n <nav className=\"flex-1 overflow-y-auto py-3\">\n <ChatGroup />\n <CustomAnalyticsGroup />\n {groups.map((group) => (\n <SidebarGroup key={group.label} group={group} />\n ))}\n </nav>\n </aside>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport { Outlet, useLocation, useNavigate } from \"react-router-dom\";\nimport { useTranslation } from \"react-i18next\";\nimport type { TFunction } from \"i18next\";\nimport { ArrowLeft } from \"lucide-react\";\nimport { ChatProvider, useChat } from \"@/components/chat/chat-provider\";\nimport { DialogProvider } from \"@/components/ui/dialog\";\nimport { Sidebar, FLASH_STYLES } from \"@/components/layout/sidebar\";\nimport { useAuth } from \"@/contexts/auth-context\";\nimport { cn } from \"@/lib/utils\";\n\nconst titleCase = (slug: string) =>\n slug.replace(/-/g, \" \").replace(/\\b\\w/g, (c) => c.toUpperCase());\n\n// The page title shown in the header. Looks up a translated label by route;\n// any slug without a translation falls back to a title-cased version of itself\n// (so newly-added doctypes still get a sensible English title).\nfunction deriveTitle(pathname: string, t: TFunction): string {\n const parts = pathname.split(\"/\").filter(Boolean);\n\n if (parts[0] === \"setup\") return t(\"titles.setup\");\n if (parts[0] === \"tutorial\") return t(\"titles.tutorial\");\n if (parts[0] === \"chat\") return t(\"titles.chat\");\n\n if (parts[0] === \"reports\") {\n const slug = parts[1] || \"\";\n return t(`titles.${slug}`, { defaultValue: slug ? titleCase(slug) : t(\"titles.reports\") });\n }\n\n if (parts[0] === \"masters\") {\n const type = parts[1] || \"\";\n const cap = type.charAt(0).toUpperCase() + type.slice(1);\n const one = t(`masters.${type}.one`, { defaultValue: cap });\n if (parts[2] === \"new\") return t(\"header.new\", { label: one });\n if (parts[2]) return `${one}: ${decodeURIComponent(parts[2])}`;\n return t(`masters.${type}.other`, { defaultValue: `${cap}s` });\n }\n\n if (parts[0] === \"app\") {\n const slug = parts[1] || \"\";\n const cap = titleCase(slug);\n const one = t(`doctypes.${slug}.one`, { defaultValue: cap });\n if (parts[2] === \"new\") return t(\"header.new\", { label: one });\n if (parts[2]) return `${one}: ${decodeURIComponent(parts[2])}`;\n return t(`doctypes.${slug}.other`, { defaultValue: `${cap}s` });\n }\n\n return t(\"titles.dashboard\");\n}\n\n// Where the header back button leads. Only pages with a natural \"up\" target\n// get one: doctype/master detail + new forms go to their list, the opening\n// balances page goes back to setup. Top-level pages (lists, dashboard,\n// reports, admin) have no parent list, so they show no back button.\nfunction deriveBackPath(pathname: string): string | null {\n const parts = pathname.split(\"/\").filter(Boolean);\n if ((parts[0] === \"app\" || parts[0] === \"masters\") && parts.length > 2) {\n return `/${parts[0]}/${parts[1]}`;\n }\n if (parts[0] === \"setup\" && parts.length > 1) return \"/setup\";\n return null;\n}\n\nexport function AppShell() {\n return (\n <DialogProvider>\n <ChatProvider>\n <AppShellContent />\n </ChatProvider>\n </DialogProvider>\n );\n}\n\nfunction AppShellContent() {\n const { pathname } = useLocation();\n const navigate = useNavigate();\n const { user, logout } = useAuth();\n const { navigationFlash } = useChat();\n const { t } = useTranslation();\n const pageTitle = deriveTitle(pathname, t);\n const backPath = deriveBackPath(pathname);\n\n const handleBack = () => {\n if (!backPath) return;\n // Prefer real history (restores the list's scroll/filter state); the\n // parent path is the fallback for deep links with no in-app history.\n if (window.history.state?.idx > 0) {\n navigate(-1);\n } else {\n navigate(backPath);\n }\n };\n const [mobileOpen, setMobileOpen] = useState(false);\n\n // Auto-close the mobile sidebar on navigation\n useEffect(() => {\n setMobileOpen(false);\n }, [pathname]);\n\n // When a tool fires a navigation flash and the sidebar is hidden (mobile),\n // pulse the hamburger button in the group's flash color instead.\n const flashStyle = navigationFlash ? FLASH_STYLES[navigationFlash.group] : null;\n\n return (\n <div className=\"flex h-dvh bg-surface-muted\">\n <Sidebar isMobileOpen={mobileOpen} onClose={() => setMobileOpen(false)} />\n {/* Mobile backdrop — only shown when sidebar is open on small screens */}\n {mobileOpen && (\n <div\n onClick={() => setMobileOpen(false)}\n className=\"fixed inset-0 z-30 bg-black/40 md:hidden\"\n aria-hidden=\"true\"\n />\n )}\n <div className=\"flex flex-1 flex-col overflow-hidden md:ml-64\">\n <header className=\"flex h-10 shrink-0 items-center justify-between border-b border-gray-200 bg-white px-4 md:px-6\">\n <div className=\"flex items-center gap-3\">\n <button\n onClick={() => setMobileOpen(true)}\n className={cn(\n \"rounded p-1 text-gray-500 transition-all duration-300 hover:bg-gray-100 hover:text-gray-900 md:hidden\",\n flashStyle,\n )}\n aria-label={t(\"header.openMenu\")}\n >\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" width=\"22\" height=\"22\">\n <path d=\"M6.835 4c-.451.004-.82.012-1.137.038-.386.032-.659.085-.876.162l-.2.086c-.44.224-.807.564-1.063.982l-.103.184c-.126.247-.206.562-.248 1.076-.043.523-.043 1.19-.043 2.135v2.664c0 .944 0 1.612.043 2.135.042.515.122.829.248 1.076l.103.184c.256.418.624.758 1.063.982l.2.086c.217.077.49.13.876.162.316.026.685.034 1.136.038zm11.33 7.327c0 .922 0 1.654-.048 2.243-.043.522-.125.977-.305 1.395l-.082.177a4 4 0 0 1-1.473 1.593l-.276.155c-.465.237-.974.338-1.57.387-.59.048-1.322.048-2.244.048H7.833c-.922 0-1.654 0-2.243-.048-.522-.042-.977-.126-1.395-.305l-.176-.082a4 4 0 0 1-1.594-1.473l-.154-.275c-.238-.466-.34-.975-.388-1.572-.048-.589-.048-1.32-.048-2.243V8.663c0-.922 0-1.654.048-2.243.049-.597.15-1.106.388-1.571l.154-.276a4 4 0 0 1 1.594-1.472l.176-.083c.418-.18.873-.263 1.395-.305.589-.048 1.32-.048 2.243-.048h4.334c.922 0 1.654 0 2.243.048.597.049 1.106.15 1.571.388l.276.154a4 4 0 0 1 1.473 1.594l.082.176c.18.418.262.873.305 1.395.048.589.048 1.32.048 2.243zm-10 4.668h4.002c.944 0 1.612 0 2.135-.043.514-.042.829-.122 1.076-.248l.184-.103c.418-.256.758-.624.982-1.063l.086-.2c.077-.217.13-.49.162-.876.043-.523.043-1.19.043-2.135V8.663c0-.944 0-1.612-.043-2.135-.032-.386-.085-.659-.162-.876l-.086-.2a2.67 2.67 0 0 0-.982-1.063l-.184-.103c-.247-.126-.562-.206-1.076-.248-.523-.043-1.19-.043-2.135-.043H8.164L8.165 4z\"/>\n </svg>\n </button>\n {backPath && (\n <button\n onClick={handleBack}\n className=\"-ml-1 rounded p-1 text-gray-500 hover:bg-gray-100 hover:text-gray-900\"\n aria-label={t(\"header.back\")}\n >\n <ArrowLeft className=\"h-5 w-5\" />\n </button>\n )}\n <h1 className=\"text-base font-semibold text-gray-500 md:text-lg\">{pageTitle}</h1>\n </div>\n <div className=\"flex items-center gap-3\">\n <span className=\"hidden text-sm text-gray-500 sm:inline\">\n {user?.full_name}\n <span className=\"ml-1.5 rounded bg-gray-100 px-1.5 py-0.5 text-xs font-medium text-gray-600\">\n {user?.role}\n </span>\n </span>\n <button\n onClick={logout}\n className=\"text-sm text-gray-500 hover:text-gray-700\"\n >\n {t(\"header.logout\")}\n </button>\n </div>\n </header>\n <main className=\"flex-1 overflow-auto p-4 md:p-6\">\n <Outlet />\n </main>\n </div>\n </div>\n );\n}\n","import { Navigate } from \"react-router-dom\";\nimport { useAuth } from \"@/contexts/auth-context\";\n\nexport function ProtectedRoute({ children }: { children: React.ReactNode }) {\n const { user, loading } = useAuth();\n\n if (loading) {\n return (\n <div className=\"flex h-dvh items-center justify-center\">\n <div className=\"text-gray-400\">Loading...</div>\n </div>\n );\n }\n\n if (!user) {\n return <Navigate to=\"/login\" replace />;\n }\n\n return <>{children}</>;\n}\n","import { cn } from \"@/lib/utils\";\n\ninterface CardProps {\n title?: string;\n children: React.ReactNode;\n className?: string;\n /** When true, renders the hover-elevation shadow + cursor pointer.\n * Use for cards that the whole tile is clickable. */\n interactive?: boolean;\n}\n\nexport function Card({ title, children, className, interactive }: CardProps) {\n return (\n <div\n className={cn(\n // Surface + 1px hairline ring + multi-layer soft shadow gives\n // the card depth on a tinted page background. The shadow is\n // closer in feel to Linear / Vercel than Tailwind's default\n // shadow-sm, which on white-on-white pages was effectively\n // invisible.\n \"rounded-xl bg-surface p-6 ring-1 ring-line shadow-card transition-all\",\n interactive && \"cursor-pointer hover:shadow-card-hover hover:ring-line/80\",\n className,\n )}\n >\n {title && (\n <h3 className=\"mb-4 text-base font-semibold tracking-tight text-fg\">\n {title}\n </h3>\n )}\n {children}\n </div>\n );\n}\n","import { cn } from \"@/lib/utils\";\n\n// Tinted-background + ring-on-inset + leading dot pattern. Reads as\n// \"modern enterprise\" (Linear, Stripe) compared to the previous\n// solid bg-color-100 / text-color-800 chips.\n//\n// Each variant has three matched tones: a near-white tint as the\n// background, a saturated text colour, and a slightly darker ring.\nconst variantClasses: Record<string, string> = {\n default:\n \"bg-brand/10 text-brand ring-1 ring-inset ring-brand/20\",\n success:\n \"bg-emerald-50 text-emerald-700 ring-1 ring-inset ring-emerald-200\",\n warning:\n \"bg-amber-50 text-amber-700 ring-1 ring-inset ring-amber-200\",\n danger:\n \"bg-rose-50 text-rose-700 ring-1 ring-inset ring-rose-200\",\n secondary:\n \"bg-surface-subtle text-fg-muted ring-1 ring-inset ring-line\",\n};\n\ninterface BadgeProps {\n variant?: \"default\" | \"success\" | \"warning\" | \"danger\" | \"secondary\";\n /** Show a leading status dot. Off by default; turn on for status\n * pills (Draft / Submitted / Cancelled etc.). */\n dot?: boolean;\n children: React.ReactNode;\n className?: string;\n}\n\nexport function Badge({ variant = \"default\", dot, children, className }: BadgeProps) {\n return (\n <span\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs font-medium\",\n variantClasses[variant],\n className,\n )}\n >\n {dot && <span className=\"h-1.5 w-1.5 rounded-full bg-current\" />}\n {children}\n </span>\n );\n}\n","import { useTranslation } from \"react-i18next\";\nimport { Badge } from \"@/components/ui/badge\";\n\ntype BadgeVariant = \"default\" | \"success\" | \"warning\" | \"danger\" | \"secondary\";\n\nconst STATUS_VARIANT_MAP: Record<string, BadgeVariant> = {\n Draft: \"secondary\",\n Open: \"default\",\n Submitted: \"default\",\n \"To Deliver and Bill\": \"warning\",\n \"To Deliver\": \"warning\",\n \"To Bill\": \"warning\",\n Completed: \"success\",\n Ordered: \"success\",\n Paid: \"success\",\n Cancelled: \"danger\",\n Discarded: \"secondary\",\n Overdue: \"danger\",\n};\n\ninterface StatusBadgeProps {\n status: string;\n}\n\nexport function StatusBadge({ status }: StatusBadgeProps) {\n const { t } = useTranslation();\n // Variant keys off the backend's English status; only the label is localized.\n const variant = STATUS_VARIANT_MAP[status] ?? \"secondary\";\n\n return <Badge variant={variant}>{t(`status.${status}`, { defaultValue: status })}</Badge>;\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { api } from \"@/api/client\";\n\n/**\n * The company's base/functional currency — what the ledger and all financial\n * statements are expressed in. Reports show this (not per-document currencies).\n * Falls back to USD until the company list loads. Pass a company name to pick\n * its currency in a multi-company setup; otherwise the first company is used.\n */\nexport function useBaseCurrency(company?: string): string {\n const { data } = useQuery({\n queryKey: [\"setup-status\"],\n queryFn: () => api.setupStatus(),\n staleTime: 5 * 60 * 1000,\n });\n const companies: any[] = data?.companies ?? [];\n if (company) {\n const match = companies.find(\n (c) => c.name === company || c.company_name === company,\n );\n if (match?.default_currency) return match.default_currency;\n }\n return companies[0]?.default_currency || \"USD\";\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { Link } from \"react-router-dom\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n TrendingUp,\n ArrowDownRight,\n ArrowUpRight,\n Package,\n Receipt,\n ShoppingCart,\n Wallet,\n FileText,\n type LucideIcon,\n} from \"lucide-react\";\nimport { api } from \"@/api/client\";\nimport { Card } from \"@/components/ui/card\";\nimport { StatusBadge } from \"@/components/document/status-badge\";\nimport { formatCurrency as fmtCurrency, formatDate } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\n\n// ─── Metric cards ──────────────────────────────────────────────────\n\ninterface MetricCardProps {\n title: string;\n value: number | undefined;\n icon: LucideIcon;\n /** Tailwind colour class for the icon halo, e.g. \"text-emerald-600\n * bg-emerald-500/10\". Defaults to brand. */\n tone?: string;\n}\n\nfunction MetricCard({ title, value, icon: Icon, tone }: MetricCardProps) {\n const toneClass = tone ?? \"text-brand bg-brand/10\";\n const baseCurrency = useBaseCurrency();\n const formatCurrency = (v: number | null | undefined) => fmtCurrency(v, baseCurrency);\n return (\n <Card>\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-medium text-fg-muted\">{title}</p>\n <p className=\"mt-1.5 text-2xl font-semibold tracking-tight tabular-nums text-fg\">\n {formatCurrency(value ?? 0)}\n </p>\n </div>\n <div className={`shrink-0 rounded-lg p-2 ${toneClass}`}>\n <Icon className=\"h-5 w-5\" strokeWidth={2} />\n </div>\n </div>\n </Card>\n );\n}\n\nfunction MetricCardSkeleton() {\n return (\n <Card>\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"h-4 w-24 animate-pulse rounded bg-surface-subtle\" />\n <div className=\"mt-2.5 h-7 w-32 animate-pulse rounded bg-surface-subtle\" />\n </div>\n <div className=\"h-9 w-9 shrink-0 animate-pulse rounded-lg bg-surface-subtle\" />\n </div>\n </Card>\n );\n}\n\n// ─── Recent documents ──────────────────────────────────────────────\n\n// Each doctype gets a recognisable icon. Falls back to FileText for\n// anything we haven't mapped yet.\nconst DOCTYPE_ICON: Record<string, LucideIcon> = {\n \"Sales Invoice\": Receipt,\n \"Purchase Invoice\": Receipt,\n \"Payment Entry\": Wallet,\n \"Sales Order\": ShoppingCart,\n \"Quotation\": FileText,\n};\n\ninterface RecentDoc {\n doctype?: string;\n type?: string; // legacy field name — kept for backward compat\n name: string;\n status: string;\n creation?: string;\n date?: string; // legacy field name — kept for backward compat\n}\n\nfunction RecentDocumentRow({ doc }: { doc: RecentDoc }) {\n const { t } = useTranslation();\n const doctype = doc.doctype ?? doc.type ?? \"Document\";\n const date = doc.creation ?? doc.date;\n const Icon = DOCTYPE_ICON[doctype] ?? FileText;\n // Doctype slug — e.g. \"Sales Invoice\" → \"sales-invoice\", matching the\n // routes defined in routes.tsx and used by the sidebar.\n const slug = doctype.toLowerCase().replace(/\\s+/g, \"-\");\n const href = `/app/${slug}/${encodeURIComponent(doc.name)}`;\n\n return (\n <Link\n to={href}\n className=\"grid grid-cols-[auto_1fr_auto_auto] items-center gap-3 rounded-lg px-3 py-2.5 transition-colors hover:bg-surface-subtle\"\n >\n <div className=\"rounded-md bg-surface-subtle p-1.5 text-fg-muted\">\n <Icon className=\"h-4 w-4\" strokeWidth={2} />\n </div>\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-medium text-fg\">{doc.name}</div>\n <div className=\"truncate text-xs text-fg-muted\">{t(`nav.items.${doctype}`, { defaultValue: doctype })}</div>\n </div>\n <StatusBadge status={doc.status} />\n <div className=\"hidden text-xs tabular-nums text-fg-muted sm:block\">\n {date ? formatDate(date) : \"—\"}\n </div>\n </Link>\n );\n}\n\nfunction RecentDocumentRowSkeleton() {\n return (\n <div className=\"grid grid-cols-[auto_1fr_auto_auto] items-center gap-3 px-3 py-2.5\">\n <div className=\"h-7 w-7 animate-pulse rounded-md bg-surface-subtle\" />\n <div className=\"min-w-0 space-y-1.5\">\n <div className=\"h-3.5 w-32 animate-pulse rounded bg-surface-subtle\" />\n <div className=\"h-3 w-20 animate-pulse rounded bg-surface-subtle\" />\n </div>\n <div className=\"h-5 w-16 animate-pulse rounded-full bg-surface-subtle\" />\n <div className=\"hidden h-3 w-16 animate-pulse rounded bg-surface-subtle sm:block\" />\n </div>\n );\n}\n\n// ─── Page ──────────────────────────────────────────────────────────\n\nexport default function DashboardPage() {\n const { t } = useTranslation();\n const { data, isLoading } = useQuery({\n queryKey: [\"dashboard-summary\"],\n queryFn: () => api.dashboardSummary(),\n });\n\n return (\n <div className=\"space-y-6\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n {isLoading ? (\n <>\n <MetricCardSkeleton />\n <MetricCardSkeleton />\n <MetricCardSkeleton />\n <MetricCardSkeleton />\n </>\n ) : (\n <>\n <MetricCard\n title={t(\"dashboard.totalRevenue\")}\n value={data?.total_revenue}\n icon={TrendingUp}\n tone=\"text-emerald-600 bg-emerald-500/10\"\n />\n <MetricCard\n title={t(\"dashboard.outstandingReceivable\")}\n value={data?.outstanding_receivable}\n icon={ArrowDownRight}\n tone=\"text-sky-600 bg-sky-500/10\"\n />\n <MetricCard\n title={t(\"dashboard.outstandingPayable\")}\n value={data?.outstanding_payable}\n icon={ArrowUpRight}\n tone=\"text-amber-600 bg-amber-500/10\"\n />\n <MetricCard\n title={t(\"dashboard.totalStockValue\")}\n value={data?.total_stock_value}\n icon={Package}\n tone=\"text-brand bg-brand/10\"\n />\n </>\n )}\n </div>\n\n <Card title={t(\"dashboard.recentDocuments\")}>\n <div className=\"-mx-3 space-y-0.5\">\n {isLoading ? (\n <>\n <RecentDocumentRowSkeleton />\n <RecentDocumentRowSkeleton />\n <RecentDocumentRowSkeleton />\n <RecentDocumentRowSkeleton />\n <RecentDocumentRowSkeleton />\n </>\n ) : data?.recent_documents && data.recent_documents.length > 0 ? (\n data.recent_documents.map((doc: RecentDoc, idx: number) => (\n <RecentDocumentRow key={`${doc.name}-${idx}`} doc={doc} />\n ))\n ) : (\n <div className=\"px-3 py-10 text-center text-sm text-fg-muted\">\n {t(\"dashboard.noRecentDocuments\")}\n </div>\n )}\n </div>\n </Card>\n </div>\n );\n}\n","// Remembers the list a user was last looking at, per doctype — its filters (so a\n// detail page's prev/next stays within that filtered set) and its query string\n// (so \"back to list\" returns to it). Backed by sessionStorage so it survives a\n// detail-page reload; scoped per tab. Read by DocPager on the detail page.\n\nexport type ListContext = {\n /** Filters as the list built them (status / from_date / to_date / …). */\n filters: Record<string, unknown>;\n /** The list's URL query string (e.g. \"?status=Draft\"), for back-to-list. */\n search: string;\n};\n\nconst KEY = \"lad.docListContext\";\n\nfunction readAll(): Record<string, ListContext> {\n try {\n return JSON.parse(sessionStorage.getItem(KEY) || \"{}\");\n } catch {\n return {};\n }\n}\n\nexport function setListContext(doctype: string, ctx: ListContext): void {\n try {\n const all = readAll();\n all[doctype] = ctx;\n sessionStorage.setItem(KEY, JSON.stringify(all));\n } catch {\n /* sessionStorage unavailable — prev/next just falls back to no filters. */\n }\n}\n\nexport function getListContext(doctype: string): ListContext | undefined {\n return readAll()[doctype];\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { api } from \"@/api/client\";\n\nexport function useDocumentList(\n doctype: string,\n filters?: Record<string, string | number | undefined>,\n) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"documents\", doctype, filters],\n queryFn: () => api.listDocuments(doctype, filters),\n enabled: !!doctype,\n });\n\n return { data, isLoading, error, refetch };\n}\n","import { useCallback } from \"react\";\nimport { useSearchParams } from \"react-router-dom\";\n\n/**\n * Atomic multi-param updater. Works around a react-router-dom quirk:\n * calling several `useUrlState` setters in the same handler races, because\n * each functional updater reads the same cached `prev` and the last call\n * wins — silently dropping the other updates. Pass all changes in one call\n * so they land in a single navigate.\n *\n * `null`, `undefined`, or empty string remove the param from the URL.\n */\nexport function useUrlPatch() {\n const [, setParams] = useSearchParams();\n return useCallback(\n (patch: Record<string, string | number | null | undefined>) => {\n setParams(\n (prev) => {\n const p = new URLSearchParams(prev);\n for (const [key, value] of Object.entries(patch)) {\n if (value === \"\" || value == null) {\n p.delete(key);\n } else {\n p.set(key, String(value));\n }\n }\n return p;\n },\n { replace: true },\n );\n },\n [setParams],\n );\n}\n\n/**\n * A URL-backed useState for a single query param.\n *\n * - Initial value is read from the URL; falls back to `defaultValue`.\n * - Updates use `{ replace: true }` so filter/pagination tweaks don't pollute\n * browser history — the Back button still takes the user to where they came\n * from, not through each intermediate filter state.\n * - Values equal to `defaultValue` (and empty strings) are stripped from the\n * URL so a freshly-loaded page doesn't carry a bunch of `?status=All&page=1`\n * noise.\n * - Coerces to number when `defaultValue` is a number.\n */\nexport function useUrlState<T extends string | number>(\n key: string,\n defaultValue: T,\n): [T, (next: T) => void] {\n const [params, setParams] = useSearchParams();\n const raw = params.get(key);\n\n let value: T;\n if (raw === null) {\n value = defaultValue;\n } else if (typeof defaultValue === \"number\") {\n const parsed = Number(raw);\n value = (Number.isFinite(parsed) ? parsed : defaultValue) as T;\n } else {\n value = raw as T;\n }\n\n const setValue = useCallback(\n (next: T) => {\n setParams(\n (prev) => {\n const p = new URLSearchParams(prev);\n if (next === defaultValue || next === \"\" || next == null) {\n p.delete(key);\n } else {\n p.set(key, String(next));\n }\n return p;\n },\n { replace: true },\n );\n },\n [key, defaultValue, setParams],\n );\n\n return [value, setValue];\n}\n","/**\n * Doctype metadata registry.\n *\n * This drives the generic list and form pages. Instead of coding 8 separate\n * pages, a single registry defines the fields, columns, and actions for each\n * document type.\n */\n\nexport interface FieldDef {\n name: string;\n label: string;\n type: \"text\" | \"number\" | \"currency\" | \"date\" | \"link\" | \"select\" | \"textarea\";\n required?: boolean;\n readOnly?: boolean;\n linkDoctype?: string; // for type=link, which master to search\n linkDoctypeField?: string; // for type=link, read the linkDoctype from this sibling field's value (lowercase)\n // For type=select: either plain strings (shown as-is) or {value, label}\n // pairs when the stored value is machine-friendly (e.g. \"1\"/\"0\") but the\n // user-visible label should read differently (\"Yes\"/\"No\").\n options?: Array<string | { value: string; label: string }>;\n // For type=select with a runtime-populated option list. \"currency\" fills the\n // dropdown from the available-currencies endpoint instead of static options.\n optionsSource?: \"currency\";\n default?: any;\n hint?: string; // tooltip text shown via a help icon next to the label\n}\n\nexport interface ChildTableDef {\n label: string;\n key: string; // field name on the parent doc (e.g. \"items\", \"taxes\", \"accounts\")\n fields: FieldDef[];\n}\n\nexport interface ConversionDef {\n label: string;\n targetDoctype: string;\n}\n\nexport interface DoctypeConfig {\n slug: string;\n label: string;\n dateField: string;\n partyField?: string;\n partyLabel?: string;\n amountField?: string;\n fields: FieldDef[];\n childTables: ChildTableDef[];\n listColumns: string[];\n // Field names to expose as dropdown filters above the list. Each must name a\n // `type: \"select\"` field in `fields`; its options drive the dropdown and the\n // selection is sent as a plain column filter (status=Contacted, fit=A). When\n // set, these replace the built-in Draft/Submitted/Cancelled status dropdown —\n // the right call for non-submittable doctypes whose `status` is a business\n // field, not a docstatus. Omit to keep the default status filter.\n listFilters?: string[];\n // Column names the list's free-text search box matches against (case-\n // insensitive substring), e.g. [\"company_name\", \"uid\", \"town\"]. When set, the\n // list shows a debounced search box; the backend can also match via a\n // registered related-table expansion (register_search_expansion). Omit for no\n // search box.\n searchFields?: string[];\n canSubmit: boolean;\n canCancel: boolean;\n conversions: ConversionDef[];\n}\n\n// --- Shared child table definitions ---\n\nconst ITEM_FIELDS: FieldDef[] = [\n { name: \"item_code\", label: \"Item\", type: \"link\", linkDoctype: \"item\", required: true },\n { name: \"item_name\", label: \"Item Name\", type: \"text\", readOnly: true },\n // Per-line description/blurb. Defaults from the Item master on save (an empty\n // value falls back to the master, so leaving it blank never wipes anything);\n // type here to override it for this document only — like a Proposal position.\n { name: \"description\", label: \"Description\", type: \"textarea\" },\n { name: \"qty\", label: \"Qty\", type: \"number\", required: true },\n { name: \"rate\", label: \"Rate\", type: \"currency\", required: true },\n { name: \"amount\", label: \"Amount\", type: \"currency\", readOnly: true },\n];\n\n// Quotation lines additionally carry a billing frequency: one-time or a\n// recurring cadence. Recurring lines are totalled separately on the offer\n// (their own per-period subtotal), so they don't inflate the one-time total.\n// Values match the Subscription billing intervals exactly (kept in English;\n// the branded PDF localizes them for display).\nconst QUOTATION_ITEM_FIELDS: FieldDef[] = [\n ...ITEM_FIELDS,\n {\n name: \"frequency\",\n label: \"Frequency\",\n type: \"select\",\n options: [\"One-time\", \"Monthly\", \"Quarterly\", \"Half-Yearly\", \"Yearly\"],\n default: \"One-time\",\n },\n];\n\n// Transaction currency picker, shared by all sales/purchase documents. The\n// dropdown is populated at runtime (base + convertible currencies) and the\n// form pre-selects the party's (or company's) default currency on new docs.\nconst CURRENCY_FIELD: FieldDef = {\n name: \"currency\", label: \"Currency\", type: \"select\", optionsSource: \"currency\",\n hint: \"The currency this document is transacted in. Defaults from the party's (or the company's) default currency. The ledger still posts in the company base currency, translated at this document's exchange rate.\",\n};\n\nconst TAX_FIELDS: FieldDef[] = [\n {\n name: \"charge_type\", label: \"Type\", type: \"select\",\n options: [\"On Net Total\", \"On Previous Row Amount\", \"On Previous Row Total\", \"Actual\", \"On Item Quantity\"],\n default: \"On Net Total\",\n },\n { name: \"account_head\", label: \"Account\", type: \"link\", linkDoctype: \"account\" },\n { name: \"description\", label: \"Description\", type: \"text\" },\n { name: \"rate\", label: \"Rate (%)\", type: \"number\" },\n { name: \"tax_amount\", label: \"Amount\", type: \"currency\", readOnly: true },\n];\n\n// --- Doctype configs ---\n\nconst CONFIGS: Record<string, DoctypeConfig> = {\n quotation: {\n slug: \"quotation\",\n label: \"Quotation\",\n dateField: \"transaction_date\",\n partyField: \"customer\",\n partyLabel: \"Customer\",\n amountField: \"grand_total\",\n fields: [\n { name: \"customer\", label: \"Customer\", type: \"link\", linkDoctype: \"customer\", required: true },\n { name: \"transaction_date\", label: \"Date\", type: \"date\", required: true },\n { name: \"valid_till\", label: \"Valid Till\", type: \"date\" },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n CURRENCY_FIELD,\n { name: \"net_total\", label: \"Net Total\", type: \"currency\", readOnly: true },\n { name: \"total_taxes_and_charges\", label: \"Tax\", type: \"currency\", readOnly: true },\n { name: \"grand_total\", label: \"Grand Total\", type: \"currency\", readOnly: true },\n { name: \"remarks\", label: \"Notes / Terms\", type: \"textarea\" },\n ],\n childTables: [\n { key: \"items\", label: \"Items\", fields: QUOTATION_ITEM_FIELDS },\n { key: \"taxes\", label: \"Taxes\", fields: TAX_FIELDS },\n ],\n listColumns: [\"name\", \"customer\", \"transaction_date\", \"grand_total\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [\n { label: \"Create Sales Order\", targetDoctype: \"Sales Order\" },\n { label: \"Create Sales Invoice\", targetDoctype: \"Sales Invoice\" },\n { label: \"Create Delivery Note\", targetDoctype: \"Delivery Note\" },\n ],\n },\n\n // Proposal (Sammelofferte) — the form is a custom builder (see\n // pages/proposals/proposal-form.tsx, routed ahead of the generic form). This\n // config only drives the generic LIST page: columns + label + title.\n proposal: {\n slug: \"proposal\",\n label: \"Proposal\",\n dateField: \"proposal_date\",\n partyField: \"customer\",\n partyLabel: \"Customer\",\n fields: [],\n childTables: [],\n listColumns: [\"name\", \"title\", \"customer\", \"modified\"],\n canSubmit: false,\n canCancel: false,\n conversions: [],\n },\n\n \"sales-order\": {\n slug: \"sales-order\",\n label: \"Sales Order\",\n dateField: \"transaction_date\",\n partyField: \"customer\",\n partyLabel: \"Customer\",\n amountField: \"grand_total\",\n fields: [\n { name: \"customer\", label: \"Customer\", type: \"link\", linkDoctype: \"customer\", required: true },\n { name: \"transaction_date\", label: \"Date\", type: \"date\", required: true },\n { name: \"delivery_date\", label: \"Delivery Date\", type: \"date\" },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n CURRENCY_FIELD,\n { name: \"per_delivered\", label: \"% Delivered\", type: \"number\", readOnly: true },\n { name: \"per_billed\", label: \"% Billed\", type: \"number\", readOnly: true },\n { name: \"net_total\", label: \"Net Total\", type: \"currency\", readOnly: true },\n { name: \"grand_total\", label: \"Grand Total\", type: \"currency\", readOnly: true },\n { name: \"remarks\", label: \"Notes / Terms\", type: \"textarea\" },\n ],\n childTables: [\n { key: \"items\", label: \"Items\", fields: ITEM_FIELDS },\n { key: \"taxes\", label: \"Taxes\", fields: TAX_FIELDS },\n ],\n listColumns: [\"name\", \"customer\", \"transaction_date\", \"grand_total\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [\n { label: \"Create Sales Invoice\", targetDoctype: \"Sales Invoice\" },\n { label: \"Create Delivery Note\", targetDoctype: \"Delivery Note\" },\n ],\n },\n\n \"sales-invoice\": {\n slug: \"sales-invoice\",\n label: \"Sales Invoice\",\n dateField: \"posting_date\",\n partyField: \"customer\",\n partyLabel: \"Customer\",\n amountField: \"grand_total\",\n fields: [\n { name: \"customer\", label: \"Customer\", type: \"link\", linkDoctype: \"customer\", required: true },\n { name: \"posting_date\", label: \"Posting Date\", type: \"date\", required: true },\n { name: \"due_date\", label: \"Due Date\", type: \"date\" },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n CURRENCY_FIELD,\n { name: \"net_total\", label: \"Net Total\", type: \"currency\", readOnly: true },\n { name: \"total_taxes_and_charges\", label: \"Tax\", type: \"currency\", readOnly: true },\n { name: \"grand_total\", label: \"Grand Total\", type: \"currency\", readOnly: true },\n { name: \"outstanding_amount\", label: \"Outstanding\", type: \"currency\", readOnly: true },\n { name: \"remarks\", label: \"Notes / Terms\", type: \"textarea\" },\n ],\n childTables: [\n { key: \"items\", label: \"Items\", fields: [...ITEM_FIELDS, { name: \"income_account\", label: \"Income Account\", type: \"link\", linkDoctype: \"account\" }] },\n { key: \"taxes\", label: \"Taxes\", fields: TAX_FIELDS },\n ],\n listColumns: [\"name\", \"customer\", \"posting_date\", \"grand_total\", \"outstanding_amount\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [\n { label: \"Create Credit Note\", targetDoctype: \"Sales Invoice\" },\n ],\n },\n\n \"purchase-order\": {\n slug: \"purchase-order\",\n label: \"Purchase Order\",\n dateField: \"transaction_date\",\n partyField: \"supplier\",\n partyLabel: \"Supplier\",\n amountField: \"grand_total\",\n fields: [\n { name: \"supplier\", label: \"Supplier\", type: \"link\", linkDoctype: \"supplier\", required: true },\n { name: \"transaction_date\", label: \"Date\", type: \"date\", required: true },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n CURRENCY_FIELD,\n { name: \"net_total\", label: \"Net Total\", type: \"currency\", readOnly: true },\n { name: \"grand_total\", label: \"Grand Total\", type: \"currency\", readOnly: true },\n { name: \"remarks\", label: \"Notes / Terms\", type: \"textarea\" },\n ],\n childTables: [\n { key: \"items\", label: \"Items\", fields: [...ITEM_FIELDS, { name: \"warehouse\", label: \"Warehouse\", type: \"link\", linkDoctype: \"warehouse\" }] },\n { key: \"taxes\", label: \"Taxes\", fields: TAX_FIELDS },\n ],\n listColumns: [\"name\", \"supplier\", \"transaction_date\", \"grand_total\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [\n { label: \"Create Purchase Invoice\", targetDoctype: \"Purchase Invoice\" },\n { label: \"Create Purchase Receipt\", targetDoctype: \"Purchase Receipt\" },\n ],\n },\n\n \"purchase-invoice\": {\n slug: \"purchase-invoice\",\n label: \"Purchase Invoice\",\n dateField: \"posting_date\",\n partyField: \"supplier\",\n partyLabel: \"Supplier\",\n amountField: \"grand_total\",\n fields: [\n { name: \"supplier\", label: \"Supplier\", type: \"link\", linkDoctype: \"supplier\", required: true },\n { name: \"posting_date\", label: \"Posting Date\", type: \"date\", required: true },\n { name: \"due_date\", label: \"Due Date\", type: \"date\" },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n CURRENCY_FIELD,\n { name: \"update_stock\", label: \"Update Stock\", type: \"select\",\n options: [{ value: \"0\", label: \"No\" }, { value: \"1\", label: \"Yes\" }], default: \"0\",\n hint: \"If Yes, submitting this invoice also receives stock into the item warehouses.\",\n },\n { name: \"net_total\", label: \"Net Total\", type: \"currency\", readOnly: true },\n { name: \"grand_total\", label: \"Grand Total\", type: \"currency\", readOnly: true },\n { name: \"outstanding_amount\", label: \"Outstanding\", type: \"currency\", readOnly: true },\n { name: \"remarks\", label: \"Notes / Terms\", type: \"textarea\" },\n ],\n childTables: [\n {\n key: \"items\",\n label: \"Items\",\n fields: [\n ...ITEM_FIELDS,\n { name: \"warehouse\", label: \"Warehouse\", type: \"link\", linkDoctype: \"warehouse\",\n hint: \"Required when Update Stock is Yes — the received goods land in this warehouse.\",\n },\n { name: \"expense_account\", label: \"Expense Account\", type: \"link\", linkDoctype: \"account\" },\n ],\n },\n { key: \"taxes\", label: \"Taxes\", fields: TAX_FIELDS },\n ],\n listColumns: [\"name\", \"supplier\", \"posting_date\", \"grand_total\", \"outstanding_amount\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [\n { label: \"Create Debit Note\", targetDoctype: \"Purchase Invoice\" },\n ],\n },\n\n \"payment-entry\": {\n slug: \"payment-entry\",\n label: \"Payment Entry\",\n dateField: \"posting_date\",\n partyField: \"party\",\n partyLabel: \"Party\",\n amountField: \"paid_amount\",\n fields: [\n {\n name: \"payment_type\", label: \"Payment Type\", type: \"select\",\n options: [\"Receive\", \"Pay\", \"Internal Transfer\"], required: true,\n hint: \"Receive: customer pays you. Pay: you pay a supplier. Internal Transfer: move money between your own accounts.\",\n },\n { name: \"posting_date\", label: \"Posting Date\", type: \"date\", required: true },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n { name: \"party_type\", label: \"Party Type\", type: \"select\", options: [\"Customer\", \"Supplier\"],\n hint: \"Select Customer when receiving money, Supplier when paying.\",\n },\n { name: \"party\", label: \"Party\", type: \"link\", linkDoctypeField: \"party_type\" },\n { name: \"paid_from\", label: \"Paid From\", type: \"link\", linkDoctype: \"account\",\n hint: \"The account money is coming from (e.g. Accounts Receivable when receiving, Bank when paying).\",\n },\n { name: \"paid_to\", label: \"Paid To\", type: \"link\", linkDoctype: \"account\",\n hint: \"The account money is going to (e.g. Bank when receiving, Accounts Payable when paying).\",\n },\n { name: \"paid_amount\", label: \"Paid Amount\", type: \"currency\", required: true,\n hint: \"The total amount of money changing hands. This is the amount that hits the bank account.\",\n },\n ],\n childTables: [\n {\n key: \"references\", label: \"Payment References\", fields: [\n { name: \"reference_doctype\", label: \"Type\", type: \"select\", options: [\"Sales Invoice\", \"Purchase Invoice\"], default: \"Sales Invoice\" },\n { name: \"reference_name\", label: \"Invoice\", type: \"link\", linkDoctypeField: \"reference_doctype\",\n hint: \"The invoice this payment is being applied against.\",\n },\n { name: \"total_amount\", label: \"Total\", type: \"currency\", readOnly: true,\n hint: \"The full amount of the referenced invoice.\",\n },\n { name: \"outstanding_amount\", label: \"Outstanding\", type: \"currency\", readOnly: true,\n hint: \"How much is still unpaid on this invoice.\",\n },\n { name: \"allocated_amount\", label: \"Allocated\", type: \"currency\",\n hint: \"How much of this payment to apply against this invoice. Can be less than Paid Amount for partial payments, or split across multiple invoices.\",\n },\n ],\n },\n ],\n listColumns: [\"name\", \"payment_type\", \"party\", \"posting_date\", \"paid_amount\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [],\n },\n\n \"journal-entry\": {\n slug: \"journal-entry\",\n label: \"Journal Entry\",\n dateField: \"posting_date\",\n amountField: \"total_debit\",\n fields: [\n { name: \"posting_date\", label: \"Posting Date\", type: \"date\", required: true },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n { name: \"remark\", label: \"Remark\", type: \"textarea\" },\n { name: \"total_debit\", label: \"Total Debit\", type: \"currency\", readOnly: true },\n { name: \"total_credit\", label: \"Total Credit\", type: \"currency\", readOnly: true },\n ],\n childTables: [\n {\n key: \"accounts\", label: \"Account Entries\", fields: [\n { name: \"account\", label: \"Account\", type: \"link\", linkDoctype: \"account\", required: true },\n { name: \"party_type\", label: \"Party Type\", type: \"select\", options: [\"\", \"Customer\", \"Supplier\"] },\n { name: \"party\", label: \"Party\", type: \"link\", linkDoctypeField: \"party_type\" },\n { name: \"debit\", label: \"Debit\", type: \"currency\" },\n { name: \"credit\", label: \"Credit\", type: \"currency\" },\n { name: \"cost_center\", label: \"Cost Center\", type: \"link\", linkDoctype: \"cost-center\" },\n ],\n },\n ],\n listColumns: [\"name\", \"posting_date\", \"remark\", \"total_debit\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [],\n },\n\n \"stock-entry\": {\n slug: \"stock-entry\",\n label: \"Stock Entry\",\n dateField: \"posting_date\",\n amountField: \"total_amount\",\n fields: [\n {\n name: \"stock_entry_type\", label: \"Type\", type: \"select\",\n options: [\"Material Receipt\", \"Material Issue\", \"Material Transfer\", \"Opening Stock\"], required: true,\n hint: \"Opening Stock is for one-time initial inventory (contra: Opening Balance Equity). Material Receipt/Issue are for adjustments and write-offs (contra: Stock Adjustment).\",\n },\n { name: \"posting_date\", label: \"Posting Date\", type: \"date\", required: true },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n { name: \"from_warehouse\", label: \"Source Warehouse\", type: \"link\", linkDoctype: \"warehouse\" },\n { name: \"to_warehouse\", label: \"Target Warehouse\", type: \"link\", linkDoctype: \"warehouse\" },\n { name: \"total_incoming_value\", label: \"Incoming Value\", type: \"currency\", readOnly: true },\n { name: \"total_outgoing_value\", label: \"Outgoing Value\", type: \"currency\", readOnly: true },\n ],\n childTables: [\n {\n key: \"items\", label: \"Items\", fields: [\n { name: \"item_code\", label: \"Item\", type: \"link\", linkDoctype: \"item\", required: true },\n { name: \"item_name\", label: \"Item Name\", type: \"text\", readOnly: true },\n { name: \"qty\", label: \"Qty\", type: \"number\", required: true },\n { name: \"s_warehouse\", label: \"Source\", type: \"link\", linkDoctype: \"warehouse\" },\n { name: \"t_warehouse\", label: \"Target\", type: \"link\", linkDoctype: \"warehouse\" },\n { name: \"basic_rate\", label: \"Rate\", type: \"currency\" },\n { name: \"basic_amount\", label: \"Amount\", type: \"currency\", readOnly: true },\n ],\n },\n ],\n listColumns: [\"name\", \"stock_entry_type\", \"posting_date\", \"total_amount\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [],\n },\n\n \"delivery-note\": {\n slug: \"delivery-note\",\n label: \"Delivery Note\",\n dateField: \"posting_date\",\n partyField: \"customer\",\n partyLabel: \"Customer\",\n amountField: \"grand_total\",\n fields: [\n { name: \"customer\", label: \"Customer\", type: \"link\", linkDoctype: \"customer\", required: true },\n { name: \"posting_date\", label: \"Posting Date\", type: \"date\", required: true },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n CURRENCY_FIELD,\n { name: \"net_total\", label: \"Net Total\", type: \"currency\", readOnly: true },\n { name: \"total_taxes_and_charges\", label: \"Tax\", type: \"currency\", readOnly: true },\n { name: \"grand_total\", label: \"Grand Total\", type: \"currency\", readOnly: true },\n { name: \"remarks\", label: \"Notes / Terms\", type: \"textarea\" },\n ],\n childTables: [\n {\n key: \"items\", label: \"Items\", fields: [\n ...ITEM_FIELDS,\n { name: \"warehouse\", label: \"Warehouse\", type: \"link\", linkDoctype: \"warehouse\", required: true },\n ],\n },\n { key: \"taxes\", label: \"Taxes\", fields: TAX_FIELDS },\n ],\n listColumns: [\"name\", \"customer\", \"posting_date\", \"grand_total\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [\n { label: \"Create Return\", targetDoctype: \"Delivery Note\" },\n ],\n },\n\n \"purchase-receipt\": {\n slug: \"purchase-receipt\",\n label: \"Purchase Receipt\",\n dateField: \"posting_date\",\n partyField: \"supplier\",\n partyLabel: \"Supplier\",\n amountField: \"grand_total\",\n fields: [\n { name: \"supplier\", label: \"Supplier\", type: \"link\", linkDoctype: \"supplier\", required: true },\n { name: \"posting_date\", label: \"Posting Date\", type: \"date\", required: true },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n CURRENCY_FIELD,\n { name: \"net_total\", label: \"Net Total\", type: \"currency\", readOnly: true },\n { name: \"total_taxes_and_charges\", label: \"Tax\", type: \"currency\", readOnly: true },\n { name: \"grand_total\", label: \"Grand Total\", type: \"currency\", readOnly: true },\n { name: \"remarks\", label: \"Notes / Terms\", type: \"textarea\" },\n ],\n childTables: [\n {\n key: \"items\", label: \"Items\", fields: [\n ...ITEM_FIELDS,\n { name: \"warehouse\", label: \"Warehouse\", type: \"link\", linkDoctype: \"warehouse\", required: true },\n ],\n },\n { key: \"taxes\", label: \"Taxes\", fields: TAX_FIELDS },\n ],\n listColumns: [\"name\", \"supplier\", \"posting_date\", \"grand_total\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [\n { label: \"Create Return\", targetDoctype: \"Purchase Receipt\" },\n ],\n },\n\n \"pos-invoice\": {\n slug: \"pos-invoice\",\n label: \"POS Invoice\",\n dateField: \"posting_date\",\n partyField: \"customer\",\n partyLabel: \"Customer\",\n amountField: \"grand_total\",\n fields: [\n { name: \"customer\", label: \"Customer\", type: \"link\", linkDoctype: \"customer\", required: true },\n { name: \"posting_date\", label: \"Posting Date\", type: \"date\", required: true },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n CURRENCY_FIELD,\n { name: \"update_stock\", label: \"Update Stock\", type: \"select\",\n options: [{ value: \"1\", label: \"Yes\" }, { value: \"0\", label: \"No\" }], default: \"1\",\n hint: \"If Yes, submitting this invoice also reduces stock from the item warehouses.\",\n },\n { name: \"net_total\", label: \"Net Total\", type: \"currency\", readOnly: true },\n { name: \"total_taxes_and_charges\", label: \"Tax\", type: \"currency\", readOnly: true },\n { name: \"grand_total\", label: \"Grand Total\", type: \"currency\", readOnly: true },\n { name: \"paid_amount\", label: \"Paid Amount\", type: \"currency\", readOnly: true },\n { name: \"change_amount\", label: \"Change\", type: \"currency\", readOnly: true },\n ],\n childTables: [\n {\n key: \"items\", label: \"Items\", fields: [\n ...ITEM_FIELDS,\n { name: \"warehouse\", label: \"Warehouse\", type: \"link\", linkDoctype: \"warehouse\",\n hint: \"Required when Update Stock is Yes — this is where stock is drawn from.\",\n },\n ],\n },\n { key: \"taxes\", label: \"Taxes\", fields: TAX_FIELDS },\n {\n key: \"payments\", label: \"Payments\", fields: [\n { name: \"mode_of_payment\", label: \"Mode\", type: \"select\", options: [\"Cash\", \"Card\", \"Bank Transfer\"], default: \"Cash\" },\n { name: \"account\", label: \"Account\", type: \"link\", linkDoctype: \"account\" },\n { name: \"amount\", label: \"Amount\", type: \"currency\", required: true },\n ],\n },\n ],\n listColumns: [\"name\", \"customer\", \"posting_date\", \"grand_total\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [],\n },\n\n \"pricing-rule\": {\n slug: \"pricing-rule\",\n label: \"Pricing Rule\",\n dateField: \"valid_from\",\n amountField: \"discount_percentage\",\n fields: [\n { name: \"title\", label: \"Title\", type: \"text\", required: true },\n { name: \"item_code\", label: \"Item\", type: \"link\", linkDoctype: \"item\", required: true },\n { name: \"selling\", label: \"Selling\", type: \"select\", options: [\"1\", \"0\"], default: \"1\" },\n { name: \"buying\", label: \"Buying\", type: \"select\", options: [\"1\", \"0\"], default: \"0\" },\n { name: \"rate_or_discount\", label: \"Type\", type: \"select\", options: [\"Discount Percentage\", \"Discount Amount\", \"Rate\"], default: \"Discount Percentage\" },\n { name: \"discount_percentage\", label: \"Discount %\", type: \"number\" },\n { name: \"discount_amount\", label: \"Discount Amt\", type: \"currency\" },\n { name: \"rate\", label: \"Rate\", type: \"currency\" },\n { name: \"min_qty\", label: \"Min Qty\", type: \"number\" },\n { name: \"valid_from\", label: \"Valid From\", type: \"date\" },\n { name: \"valid_upto\", label: \"Valid Upto\", type: \"date\" },\n { name: \"priority\", label: \"Priority\", type: \"number\" },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\" },\n { name: \"enabled\", label: \"Enabled\", type: \"select\", options: [\"1\", \"0\"], default: \"1\" },\n ],\n childTables: [],\n listColumns: [\"name\", \"title\", \"item_code\", \"rate_or_discount\", \"discount_percentage\", \"status\"],\n canSubmit: false,\n canCancel: false,\n conversions: [],\n },\n\n \"budget\": {\n slug: \"budget\",\n label: \"Budget\",\n dateField: \"fiscal_year\",\n amountField: \"budget_amount\",\n fields: [\n { name: \"account\", label: \"Account\", type: \"link\", linkDoctype: \"account\", required: true },\n { name: \"cost_center\", label: \"Cost Center\", type: \"link\", linkDoctype: \"cost-center\" },\n { name: \"fiscal_year\", label: \"Fiscal Year\", type: \"text\", required: true },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n { name: \"budget_amount\", label: \"Budget Amount\", type: \"currency\", required: true },\n { name: \"action_if_exceeded\", label: \"If Exceeded\", type: \"select\", options: [\"Stop\", \"Warn\", \"Ignore\"], default: \"Warn\",\n hint: \"Stop: prevents the transaction. Warn: allows it but logs a warning. Ignore: no check.\",\n },\n ],\n childTables: [\n {\n key: \"monthly_distribution\", label: \"Monthly Distribution\", fields: [\n { name: \"month\", label: \"Month\", type: \"select\", options: [\n \"January\", \"February\", \"March\", \"April\", \"May\", \"June\",\n \"July\", \"August\", \"September\", \"October\", \"November\", \"December\",\n ]},\n { name: \"percentage\", label: \"%\", type: \"number\" },\n ],\n },\n ],\n listColumns: [\"name\", \"account\", \"cost_center\", \"fiscal_year\", \"budget_amount\"],\n canSubmit: false,\n canCancel: false,\n conversions: [],\n },\n\n \"subscription\": {\n slug: \"subscription\",\n label: \"Subscription\",\n dateField: \"start_date\",\n fields: [\n { name: \"party_type\", label: \"Party Type\", type: \"select\", options: [\"Customer\", \"Supplier\"], required: true },\n { name: \"party\", label: \"Party\", type: \"link\", linkDoctypeField: \"party_type\", required: true },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\" },\n { name: \"start_date\", label: \"Start Date\", type: \"date\", required: true },\n { name: \"end_date\", label: \"End Date\", type: \"date\" },\n { name: \"billing_interval\", label: \"Billing Interval\", type: \"select\", options: [\"Monthly\", \"Quarterly\", \"Half-Yearly\", \"Yearly\"], default: \"Monthly\" },\n { name: \"current_invoice_start\", label: \"Current Period Start\", type: \"date\", readOnly: true },\n { name: \"current_invoice_end\", label: \"Current Period End\", type: \"date\", readOnly: true },\n { name: \"status\", label: \"Status\", type: \"text\", readOnly: true },\n ],\n childTables: [\n {\n key: \"plans\", label: \"Plan Items\", fields: [\n { name: \"item_code\", label: \"Item\", type: \"link\", linkDoctype: \"item\", required: true },\n { name: \"item_name\", label: \"Item Name\", type: \"text\", readOnly: true },\n { name: \"qty\", label: \"Qty\", type: \"number\", default: 1 },\n { name: \"rate\", label: \"Rate\", type: \"currency\", required: true },\n ],\n },\n ],\n listColumns: [\"name\", \"party\", \"billing_interval\", \"start_date\", \"status\"],\n canSubmit: false,\n canCancel: false,\n conversions: [],\n },\n\n \"bank-transaction\": {\n slug: \"bank-transaction\",\n label: \"Bank Transaction\",\n dateField: \"posting_date\",\n fields: [\n { name: \"bank_account\", label: \"Bank Account\", type: \"link\", linkDoctype: \"account\", required: true },\n { name: \"posting_date\", label: \"Date\", type: \"date\", required: true },\n { name: \"deposit\", label: \"Deposit\", type: \"currency\" },\n { name: \"withdrawal\", label: \"Withdrawal\", type: \"currency\" },\n { name: \"description\", label: \"Description\", type: \"text\" },\n { name: \"reference_number\", label: \"Reference No\", type: \"text\" },\n { name: \"reference_doctype\", label: \"Matched Type\", type: \"select\", options: [\"\", \"Payment Entry\", \"Sales Invoice\", \"Purchase Invoice\", \"Journal Entry\"] },\n { name: \"reference_name\", label: \"Matched Doc\", type: \"link\", linkDoctypeField: \"reference_doctype\" },\n { name: \"allocated_amount\", label: \"Allocated\", type: \"currency\", readOnly: true },\n { name: \"unallocated_amount\", label: \"Unallocated\", type: \"currency\", readOnly: true },\n { name: \"status\", label: \"Status\", type: \"text\", readOnly: true },\n ],\n childTables: [],\n listColumns: [\"name\", \"posting_date\", \"deposit\", \"withdrawal\", \"status\"],\n canSubmit: false,\n canCancel: false,\n conversions: [],\n },\n};\n\nexport function getDoctypeConfig(slug: string): DoctypeConfig | undefined {\n return CONFIGS[slug];\n}\n\n/**\n * Register (or override) a doctype config. A customer deployment built on the\n * published library calls this at startup to add a new document type or swap\n * the form/list schema of a core one. The list/form pages read CONFIGS live\n * via getDoctypeConfig, so a registration takes effect immediately.\n */\nexport function registerDoctype(config: DoctypeConfig) {\n CONFIGS[config.slug] = config;\n}\n\nexport function getAllDoctypeConfigs(): DoctypeConfig[] {\n return Object.values(CONFIGS);\n}\n\nexport const DOCTYPE_SLUGS = Object.keys(CONFIGS);\n","// Prev/next navigation for a document detail page. Steps through records in the\n// same order + filters as the list the user came from (via the doc-list-context\n// store), using the backend keyset `/adjacent` endpoint. Works on every doctype;\n// exported so a deployment's custom detail page can drop it in too.\n//\n// Buttons: ‹ = previous (up the list), › = next (down). Keyboard (only when not\n// typing in a field): k / ← = prev, j / → = next, Esc / u = back to the list.\n// Cmd/Ctrl+S = save (fires even while typing) when an onSave is provided.\nimport { useEffect } from \"react\";\nimport { useNavigate } from \"react-router-dom\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\nimport { api } from \"@/api/client\";\nimport { getListContext } from \"@/lib/doc-list-context\";\n\nexport function DocPager({ slug, name, onSave, kind = \"document\" }: {\n slug: string;\n name: string;\n /** Called on Cmd/Ctrl+S. Omit if the page has nothing to save. */\n onSave?: () => void;\n /** \"master\" pages through /masters/{slug} (name ASC) instead of /app/{slug}. */\n kind?: \"document\" | \"master\";\n}) {\n const navigate = useNavigate();\n const isMaster = kind === \"master\";\n // Masters get their own context namespace so e.g. a \"lead\" master and a\n // \"lead\" doctype list don't clobber each other's stashed URL.\n const ctx = getListContext(isMaster ? `master:${slug}` : slug);\n const base = isMaster ? `/masters/${slug}` : `/app/${slug}`;\n\n const { data } = useQuery({\n queryKey: [\"adjacent\", kind, slug, name, ctx?.filters ?? null],\n queryFn: () =>\n isMaster\n ? api.adjacentMaster(slug, name)\n : api.adjacentDocument(slug, name, ctx?.filters as any),\n });\n const prev = data?.prev ?? null;\n const next = data?.next ?? null;\n\n useEffect(() => {\n const goPrev = () => prev && navigate(`${base}/${prev}`);\n const goNext = () => next && navigate(`${base}/${next}`);\n const back = () => navigate(`${base}${ctx?.search || \"\"}`);\n\n const onKey = (e: KeyboardEvent) => {\n // Save works even mid-edit.\n if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === \"s\") {\n if (onSave) { e.preventDefault(); onSave(); }\n return;\n }\n const el = document.activeElement as HTMLElement | null;\n const typing = !!el && (/^(input|textarea|select)$/i.test(el.tagName) || el.isContentEditable);\n if (typing || e.metaKey || e.ctrlKey || e.altKey) return;\n if (e.key === \"j\" || e.key === \"ArrowRight\") { e.preventDefault(); goNext(); }\n else if (e.key === \"k\" || e.key === \"ArrowLeft\") { e.preventDefault(); goPrev(); }\n else if (e.key === \"Escape\" || e.key === \"u\") { e.preventDefault(); back(); }\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [prev, next, base, ctx?.search, onSave, navigate]);\n\n const btn =\n \"rounded-md border border-line bg-surface p-1.5 text-fg-muted transition hover:bg-surface-subtle hover:text-fg disabled:cursor-default disabled:opacity-40\";\n\n return (\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n disabled={!prev}\n title=\"Previous record (k / ←)\"\n onClick={() => prev && navigate(`${base}/${prev}`)}\n className={btn}\n >\n <ChevronLeft className=\"h-4 w-4\" />\n </button>\n <button\n type=\"button\"\n disabled={!next}\n title=\"Next record (j / →)\"\n onClick={() => next && navigate(`${base}/${next}`)}\n className={btn}\n >\n <ChevronRight className=\"h-4 w-4\" />\n </button>\n </div>\n );\n}\n","import { cn } from \"@/lib/utils\";\n\n// Either a plain string (shown as both label + value) or an object form for\n// nicer labels (e.g. Yes/No on top of a boolean 1/0 value).\nexport type SelectOption = string | { value: string; label: string };\n\ninterface SelectProps {\n label?: string;\n options: SelectOption[];\n value?: string;\n onChange?: React.ChangeEventHandler<HTMLSelectElement>;\n className?: string;\n required?: boolean;\n disabled?: boolean;\n}\n\nfunction normalizeOption(opt: SelectOption): { value: string; label: string } {\n return typeof opt === \"string\" ? { value: opt, label: opt } : opt;\n}\n\nexport function Select({ label, options, value, onChange, className, required, disabled }: SelectProps) {\n const selectId = label ? label.toLowerCase().replace(/\\s+/g, \"-\") : undefined;\n\n return (\n <div>\n {label && (\n <label\n htmlFor={selectId}\n className=\"mb-1.5 block text-sm font-medium text-fg\"\n >\n {label}\n </label>\n )}\n <select\n id={selectId}\n value={value}\n onChange={onChange}\n required={required}\n disabled={disabled}\n className={cn(\n // Same shape as the Input primitive: h-10, surface bg, line ring,\n // brand-tinted halo on focus.\n \"block h-10 w-full rounded-lg bg-surface px-3 text-sm text-fg\",\n \"ring-1 ring-line transition-all\",\n \"focus:outline-none focus:ring-2 focus:ring-brand/30\",\n \"disabled:cursor-not-allowed disabled:bg-surface-subtle disabled:text-fg-muted\",\n className,\n )}\n >\n <option value=\"\">Select...</option>\n {options.map((opt) => {\n const { value: v, label: l } = normalizeOption(opt);\n return (\n <option key={v} value={v}>\n {l}\n </option>\n );\n })}\n </select>\n </div>\n );\n}\n","import { useState } from \"react\";\n\nexport function HintTooltip({ text }: { text: string }) {\n const [visible, setVisible] = useState(false);\n\n return (\n <span className=\"relative ml-1 inline-flex\">\n <button\n type=\"button\"\n className=\"inline-flex h-4 w-4 items-center justify-center rounded-full border border-gray-300 text-[10px] font-medium text-gray-400 hover:border-gray-400 hover:text-gray-600\"\n onMouseEnter={() => setVisible(true)}\n onMouseLeave={() => setVisible(false)}\n onClick={() => setVisible((v) => !v)}\n >\n ?\n </button>\n {visible && (\n <div className=\"absolute bottom-full left-1/2 z-50 mb-2 w-64 -translate-x-1/2 rounded-md bg-gray-900 px-3 py-2 text-xs leading-relaxed text-white shadow-lg\">\n {text}\n <div className=\"absolute left-1/2 top-full -translate-x-1/2 border-4 border-transparent border-t-gray-900\" />\n </div>\n )}\n </span>\n );\n}\n","import { useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Info } from \"lucide-react\";\n\n// Info icon next to the Notes / Terms label that explains the light markup the\n// field supports on the PDF (see api/remarks_md.py in the core). Opens on hover\n// or click; the handlers sit on the wrapper so the popover stays open while the\n// pointer moves into it to read.\nexport function NotesMarkupHelp() {\n const { t } = useTranslation();\n const [open, setOpen] = useState(false);\n\n const rows: [string, string][] = [\n [\"# Heading\", t(\"notesMarkup.heading\", { defaultValue: \"bold heading\" })],\n [\"*italic* **bold**\", t(\"notesMarkup.emphasis\", { defaultValue: \"italic / bold\" })],\n [\"---\", t(\"notesMarkup.rule\", { defaultValue: \"horizontal divider line\" })],\n [\n \">> Period | Amount\",\n t(\"notesMarkup.price\", {\n defaultValue: \"right-aligned price beside the text above (e.g. Monthly | CHF 380.—)\",\n }),\n ],\n ];\n\n return (\n <span\n className=\"relative ml-1 inline-flex align-middle\"\n onMouseEnter={() => setOpen(true)}\n onMouseLeave={() => setOpen(false)}\n >\n <button\n type=\"button\"\n className=\"inline-flex h-4 w-4 items-center justify-center rounded-full text-fg-muted hover:text-fg\"\n onClick={() => setOpen((v) => !v)}\n aria-label={t(\"notesMarkup.title\", { defaultValue: \"Formatting help\" })}\n >\n <Info className=\"h-3.5 w-3.5\" />\n </button>\n {open && (\n <div className=\"absolute bottom-full left-0 z-50 mb-2 w-80 rounded-md bg-gray-900 px-3 py-2.5 text-xs leading-relaxed text-white shadow-lg\">\n <p className=\"mb-2 text-gray-200\">\n {t(\"notesMarkup.intro\", {\n defaultValue: \"The Notes / Terms text supports light formatting on the PDF:\",\n })}\n </p>\n <table className=\"w-full border-separate border-spacing-y-1\">\n <tbody>\n {rows.map(([syntax, desc]) => (\n <tr key={syntax}>\n <td className=\"pr-3 align-top font-mono text-[11px] text-emerald-300\">{syntax}</td>\n <td className=\"align-top text-gray-200\">{desc}</td>\n </tr>\n ))}\n </tbody>\n </table>\n <p className=\"mt-2 text-gray-400\">\n {t(\"notesMarkup.block\", { defaultValue: \"Separate blocks with a blank line.\" })}\n </p>\n </div>\n )}\n </span>\n );\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { api } from \"@/api/client\";\n\n/**\n * Currencies the ERP can transact in — the company base currency plus any\n * currency that has an exchange rate on file or is set as a party/company\n * default. Used to populate the document currency dropdown, so a document can\n * only be denominated in a currency the books can convert back to base.\n *\n * Pass `enabled=false` to skip the fetch (e.g. from fields that aren't currency\n * pickers, keeping React Query's request count down).\n */\nexport function useCurrencies(company?: string, enabled = true): string[] {\n const { data } = useQuery({\n queryKey: [\"currencies\", company ?? \"\"],\n queryFn: () => api.currencies(company),\n enabled,\n staleTime: 5 * 60 * 1000,\n });\n return data?.currencies ?? [];\n}\n","import { useState, useEffect, useRef, useCallback, useMemo } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { Link, useParams, useNavigate } from \"react-router-dom\";\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { api } from \"@/api/client\";\nimport { getDoctypeConfig, type FieldDef, type ChildTableDef } from \"@/lib/doctypes\";\nimport { StatusBadge } from \"@/components/document/status-badge\";\nimport { DocPager } from \"@/components/document/doc-pager\";\nimport { Button } from \"@/components/ui/button\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Select } from \"@/components/ui/select\";\nimport { formatCurrency, flt } from \"@/lib/utils\";\nimport { HintTooltip } from \"@/components/ui/hint-tooltip\";\nimport { NotesMarkupHelp } from \"@/components/ui/notes-markup-help\";\nimport { useCurrencies } from \"@/hooks/use-currencies\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\nimport { useTranslation } from \"react-i18next\";\n\n// ---------------------------------------------------------------------------\n// Link resolution — where does clicking \"customer\" / \"account\" / etc. lead?\n// ---------------------------------------------------------------------------\n\n// Link doctypes that have a real MasterForm page. Anything else falls through\n// to a special route (Account → GL report) or renders as plain text.\nconst LINKABLE_MASTERS = new Set([\n \"customer\",\n \"supplier\",\n \"item\",\n \"warehouse\",\n]);\n\nexport function linkRefHref(linkDoctype: string | undefined | null, value: string): string | null {\n if (!linkDoctype || !value) return null;\n if (LINKABLE_MASTERS.has(linkDoctype)) {\n return `/masters/${linkDoctype}/${encodeURIComponent(value)}`;\n }\n if (linkDoctype === \"account\") {\n // No standalone Account page — deep-link into the GL report pre-filtered\n // to this account, which is what users actually want to see.\n return `/reports/general-ledger?account=${encodeURIComponent(value)}`;\n }\n // cost_center / company / anything else: no destination yet.\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// FieldLabel -- label with optional hint tooltip\n// ---------------------------------------------------------------------------\n\nfunction FieldLabel({ label, hint, extra }: { label: string; hint?: string; extra?: React.ReactNode }) {\n return (\n <label className=\"mb-1.5 block text-sm font-medium text-fg\">\n {label}\n {hint && <HintTooltip text={hint} />}\n {extra}\n </label>\n );\n}\n\n// ---------------------------------------------------------------------------\n// LinkField -- simple search-as-you-type select for master data\n// ---------------------------------------------------------------------------\n\nfunction LinkField({\n field,\n value,\n onChange,\n disabled,\n hideLabel,\n}: {\n field: FieldDef;\n value: string;\n onChange: (v: string) => void;\n disabled?: boolean;\n hideLabel?: boolean;\n}) {\n const [query, setQuery] = useState(value ?? \"\");\n const [open, setOpen] = useState(false);\n // The dropdown is portaled to <body> so it isn't clipped by the line-items\n // table's overflow-x-auto scroll container; we track the input's viewport\n // rect to position it (and follow it on scroll/resize).\n const wrapRef = useRef<HTMLDivElement>(null);\n const [menuRect, setMenuRect] = useState<{ top: number; left: number; width: number } | null>(null);\n\n const { data: options } = useQuery({\n queryKey: [\"link-search\", field.linkDoctype, query],\n queryFn: () => api.searchLink(field.linkDoctype!, query),\n enabled: !!field.linkDoctype && open,\n });\n\n useEffect(() => {\n setQuery(value ?? \"\");\n }, [value]);\n\n useEffect(() => {\n if (!open) return;\n const update = () => {\n const el = wrapRef.current;\n if (el) {\n const r = el.getBoundingClientRect();\n setMenuRect({ top: r.bottom, left: r.left, width: r.width });\n }\n };\n update();\n // capture=true so scrolling any ancestor (the table's scroller) repositions it.\n window.addEventListener(\"scroll\", update, true);\n window.addEventListener(\"resize\", update);\n return () => {\n window.removeEventListener(\"scroll\", update, true);\n window.removeEventListener(\"resize\", update);\n };\n }, [open]);\n\n if (disabled) {\n return (\n <div>\n {!hideLabel && <label className=\"mb-1.5 block text-sm font-medium text-fg\">{field.label}</label>}\n <p className=\"py-2 text-sm text-fg\">{value || \"-\"}</p>\n </div>\n );\n }\n\n return (\n <div className=\"relative\" ref={wrapRef}>\n <Input\n label={hideLabel ? undefined : field.label}\n value={query}\n onChange={(e) => {\n setQuery(e.target.value);\n setOpen(true);\n }}\n onFocus={() => setOpen(true)}\n onBlur={() => setTimeout(() => setOpen(false), 200)}\n />\n {open && options && options.length > 0 && menuRect && createPortal(\n <ul\n className=\"fixed z-50 mt-1 max-h-40 overflow-auto rounded-lg bg-surface ring-1 ring-line shadow-card-hover\"\n style={{ top: menuRect.top, left: menuRect.left, width: menuRect.width }}\n >\n {options.map((opt: any) => (\n <li\n key={opt.name}\n className=\"cursor-pointer px-3 py-2 text-sm text-fg transition-colors hover:bg-surface-subtle\"\n onMouseDown={() => {\n onChange(opt.name);\n setQuery(opt.name);\n setOpen(false);\n }}\n >\n {opt.name}\n </li>\n ))}\n </ul>,\n document.body,\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// FieldRenderer\n// ---------------------------------------------------------------------------\n\nfunction FieldRenderer({\n field,\n value,\n onChange,\n readOnly,\n rowData,\n hideLabel,\n currency = \"USD\",\n}: {\n field: FieldDef;\n value: any;\n onChange: (v: any) => void;\n readOnly: boolean;\n rowData?: Record<string, any>;\n /** Suppress the in-cell field label. Used by ChildTableEditor where the\n * table column header already shows the label — repeating it inside\n * every row makes mobile cells taller and wider than they need to be. */\n hideLabel?: boolean;\n /** The document's currency, so amounts render with the right symbol\n * (€/£/¥…) instead of always $. */\n currency?: string;\n}) {\n const { t } = useTranslation();\n const isDisabled = readOnly || !!field.readOnly;\n const Label = () =>\n hideLabel ? null : (\n <FieldLabel label={t(`fields.${field.label}`, { defaultValue: field.label })} hint={field.hint} />\n );\n\n // Currency pickers get their options from the available-currencies endpoint\n // rather than a static list. The fetch is skipped for every other field.\n const needsCurrencyOptions =\n field.type === \"select\" && field.optionsSource === \"currency\";\n const currencyOptions = useCurrencies(undefined, needsCurrencyOptions);\n\n if (isDisabled) {\n // Link fields render as a clickable link in read-only mode when there's a\n // real destination. Matches the sky-600 treatment in document lists.\n if (field.type === \"link\" && value) {\n const resolvedLinkDoctype =\n field.linkDoctypeField && rowData\n ? String(rowData[field.linkDoctypeField] ?? \"\")\n .toLowerCase()\n .replace(/\\s+/g, \"-\")\n : field.linkDoctype;\n const href = linkRefHref(resolvedLinkDoctype, String(value));\n if (href) {\n return (\n <div>\n <Label />\n <p className={hideLabel ? \"text-sm\" : \"py-2 text-sm\"}>\n <Link\n to={href}\n className=\"text-sky-600 hover:text-sky-800 hover:underline\"\n >\n {value}\n </Link>\n </p>\n </div>\n );\n }\n }\n\n let display = value ?? \"-\";\n if ((field.type === \"currency\") && typeof value === \"number\") {\n display = formatCurrency(value, currency);\n }\n // Multi-line fields (Notes / Terms) keep their line breaks when shown\n // read-only, instead of collapsing to one paragraph like a <p> does.\n const pClass = [\n hideLabel ? \"text-sm text-fg\" : \"py-2 text-sm text-fg\",\n field.type === \"textarea\" ? \"whitespace-pre-line\" : \"\",\n ].join(\" \").trim();\n return (\n <div>\n <Label />\n <p className={pClass}>{display}</p>\n </div>\n );\n }\n\n if (field.type === \"link\") {\n const resolvedField = field.linkDoctypeField && rowData\n ? { ...field, linkDoctype: rowData[field.linkDoctypeField]?.toLowerCase().replace(/\\s+/g, \"-\") }\n : field;\n return (\n <div>\n <Label />\n <LinkField\n field={resolvedField}\n value={value ?? \"\"}\n onChange={onChange}\n disabled={isDisabled}\n hideLabel\n />\n </div>\n );\n }\n\n if (field.type === \"select\" && (field.options || needsCurrencyOptions)) {\n // Keep the doc's own currency selectable even if it's not in the fetched\n // list (e.g. an older currency no longer on any rate/default).\n const options = needsCurrencyOptions\n ? value && !currencyOptions.includes(value)\n ? [value, ...currencyOptions]\n : currencyOptions\n : field.options!;\n return (\n <div>\n <Label />\n <Select\n options={options}\n value={value ?? \"\"}\n onChange={(e) => onChange(e.target.value)}\n />\n </div>\n );\n }\n\n if (field.type === \"textarea\") {\n // The `remarks` field is rendered from a light markup on the PDF, so it\n // gets the formatting-help icon. Parent textareas (not child-table cells)\n // are roomier since they sit on their own full-width row.\n const showMarkupHelp = field.name === \"remarks\";\n return (\n <div>\n {!hideLabel && (\n <FieldLabel\n label={t(`fields.${field.label}`, { defaultValue: field.label })}\n hint={field.hint}\n extra={showMarkupHelp ? <NotesMarkupHelp /> : undefined}\n />\n )}\n <textarea\n className=\"block w-full rounded-lg bg-surface px-3 py-2 text-sm text-fg ring-1 ring-line transition-all placeholder:text-fg-muted/70 focus:outline-none focus:ring-2 focus:ring-brand/30\"\n rows={hideLabel ? 3 : 7}\n value={value ?? \"\"}\n onChange={(e) => onChange(e.target.value)}\n />\n </div>\n );\n }\n\n const inputType =\n field.type === \"number\" || field.type === \"currency\"\n ? \"number\"\n : field.type === \"date\"\n ? \"date\"\n : \"text\";\n\n return (\n <div>\n <Label />\n <Input\n type={inputType}\n step={field.type === \"currency\" ? \"0.01\" : undefined}\n value={value ?? \"\"}\n onChange={(e) =>\n onChange(\n inputType === \"number\" ? parseFloat(e.target.value) || 0 : e.target.value,\n )\n }\n />\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// ChildTableEditor\n// ---------------------------------------------------------------------------\n\nfunction ChildTableEditor({\n tableDef,\n rows,\n onChange,\n readOnly,\n currency = \"USD\",\n}: {\n tableDef: ChildTableDef;\n rows: any[];\n onChange: (rows: any[]) => void;\n readOnly: boolean;\n currency?: string;\n}) {\n const { t } = useTranslation();\n const updateRow = (idx: number, fieldName: string, value: any) => {\n const updated = rows.map((row, i) =>\n i === idx ? { ...row, [fieldName]: value } : row,\n );\n onChange(updated);\n };\n\n const addRow = () => {\n const blank: any = {};\n tableDef.fields.forEach((f) => {\n blank[f.name] = f.default ?? (f.type === \"number\" || f.type === \"currency\" ? 0 : \"\");\n });\n onChange([...rows, blank]);\n };\n\n const removeRow = (idx: number) => {\n onChange(rows.filter((_, i) => i !== idx));\n };\n\n return (\n <Card title={t(`tables.${tableDef.key}`, { defaultValue: tableDef.label })}>\n <div className=\"-mx-6 overflow-x-auto px-6\">\n <table className=\"min-w-full divide-y divide-line text-sm\">\n <thead>\n <tr>\n <th className=\"px-2 py-2 text-left text-xs font-medium uppercase tracking-wide text-fg-muted\">\n #\n </th>\n {tableDef.fields.map((f) => (\n <th\n key={f.name}\n className=\"px-2 py-2 text-left text-xs font-medium uppercase tracking-wide text-fg-muted\"\n >\n {t(`fields.${f.label}`, { defaultValue: f.label })}\n </th>\n ))}\n {!readOnly && (\n <th className=\"px-2 py-2 text-left text-xs font-medium uppercase tracking-wide text-fg-muted\" />\n )}\n </tr>\n </thead>\n <tbody className=\"divide-y divide-line\">\n {rows.map((row, idx) => (\n <tr key={idx}>\n <td className=\"px-2 py-1 text-fg-muted\">{idx + 1}</td>\n {tableDef.fields.map((f) => (\n <td key={f.name} className=\"px-2 py-1 align-top\">\n <FieldRenderer\n field={f}\n value={row[f.name]}\n onChange={(v) => updateRow(idx, f.name, v)}\n readOnly={readOnly}\n rowData={row}\n hideLabel\n currency={currency}\n />\n </td>\n ))}\n {!readOnly && (\n <td className=\"px-2 py-1\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => removeRow(idx)}\n >\n Remove\n </Button>\n </td>\n )}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n {!readOnly && (\n <div className=\"mt-2\">\n <Button variant=\"secondary\" size=\"sm\" onClick={addRow}>\n {t(\"common.addRow\")}\n </Button>\n </div>\n )}\n </Card>\n );\n}\n\n// ---------------------------------------------------------------------------\n// DocumentActions\n// ---------------------------------------------------------------------------\n\nfunction DocumentActions({\n isNew,\n doctype,\n name,\n docstatus,\n discarded,\n saving,\n config,\n onSave,\n onSubmit,\n onCancel,\n onConvert,\n onDiscard,\n}: {\n isNew: boolean;\n doctype?: string;\n name?: string;\n docstatus: number;\n discarded?: boolean;\n saving: boolean;\n config: ReturnType<typeof getDoctypeConfig>;\n onSave: () => void;\n onSubmit: () => void;\n onCancel: () => void;\n onConvert: (targetDoctype: string) => void;\n onDiscard: () => void;\n}) {\n const { t } = useTranslation();\n // Two-step cancel: clicking \"Cancel\" doesn't cancel — it arms confirmation.\n // The confirm button then renders in a DIFFERENT place (pushed right) while\n // the original spot becomes a safe \"Don't cancel\", so a double-click can't\n // accidentally go through with this irreversible action.\n const [confirmingCancel, setConfirmingCancel] = useState(false);\n // Discard (drafts only) is a soft delete — reversible at the DB level — so a\n // lighter inline two-step arm is enough.\n const [confirmingDiscard, setConfirmingDiscard] = useState(false);\n if (!config) return null;\n\n const pdfUrl = !isNew && doctype && name\n ? `/api/documents/${doctype}/${encodeURIComponent(name)}/pdf`\n : null;\n\n const showCancel = !isNew && config.canCancel && docstatus === 1;\n\n return (\n <div className=\"flex flex-wrap items-center gap-2\">\n {pdfUrl && (\n <Button variant=\"secondary\" onClick={() => window.open(pdfUrl, \"_blank\")}>\n {t(\"common.pdf\")}\n </Button>\n )}\n {docstatus < 1 && !discarded && (\n <Button onClick={onSave} disabled={saving}>\n {saving ? t(\"common.saving\") : t(\"common.save\")}\n </Button>\n )}\n {!isNew && config.canSubmit && docstatus === 0 && !discarded && (\n <Button variant=\"secondary\" onClick={onSubmit}>\n {t(\"common.submit\")}\n </Button>\n )}\n {/* Discard draft (soft delete) — only on an unsubmitted, saved draft. */}\n {!isNew && config.canSubmit && docstatus === 0 && !discarded && (\n confirmingDiscard ? (\n <>\n <Button variant=\"secondary\" onClick={() => setConfirmingDiscard(false)}>\n {t(\"common.keepDraft\")}\n </Button>\n <Button\n variant=\"danger\"\n onClick={() => {\n setConfirmingDiscard(false);\n onDiscard();\n }}\n >\n {t(\"common.discardDraftConfirm\")}\n </Button>\n </>\n ) : (\n <Button variant=\"ghost\" onClick={() => setConfirmingDiscard(true)}>\n {t(\"common.discardDraft\")}\n </Button>\n )\n )}\n {/* Original Cancel button position. In confirm mode it becomes the safe\n \"Don't cancel\" so a stray repeat click here aborts rather than fires. */}\n {showCancel && (\n confirmingCancel ? (\n <Button variant=\"secondary\" onClick={() => setConfirmingCancel(false)}>\n {t(\"common.cancelDocAbort\")}\n </Button>\n ) : (\n <Button variant=\"danger\" onClick={() => setConfirmingCancel(true)}>\n {t(\"common.cancelDoc\")}\n </Button>\n )\n )}\n {/* Conversions are hidden while confirming to keep the choice unambiguous. */}\n {!isNew &&\n docstatus === 1 &&\n !confirmingCancel &&\n config.conversions.map((conv) => (\n <Button\n key={conv.targetDoctype}\n variant=\"secondary\"\n onClick={() => onConvert(conv.targetDoctype)}\n >\n {t(`conversions.${conv.label}`, { defaultValue: conv.label })}\n </Button>\n ))}\n {/* The actual confirm — deliberately placed far from the original button\n (pushed to the opposite end) so it can't be hit by a double-click. */}\n {showCancel && confirmingCancel && (\n <Button\n variant=\"danger\"\n className=\"ml-auto\"\n onClick={() => {\n setConfirmingCancel(false);\n onCancel();\n }}\n >\n {t(\"common.cancelDocConfirmBtn\")}\n </Button>\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Recalculation helper\n// ---------------------------------------------------------------------------\n\nfunction recalculate(formData: any, config: ReturnType<typeof getDoctypeConfig>) {\n if (!config) return formData;\n\n const updated = { ...formData };\n\n // Recalculate item amounts\n const hasItems = config.childTables.some((ct) => ct.key === \"items\");\n if (hasItems && Array.isArray(updated.items)) {\n updated.items = updated.items.map((item: any) => ({\n ...item,\n amount: flt(item.qty, 2) * flt(item.rate, 2),\n }));\n\n updated.net_total = updated.items.reduce(\n (sum: number, item: any) => sum + flt(item.amount, 2),\n 0,\n );\n }\n\n // Recalculate taxes\n const hasTaxes = config.childTables.some((ct) => ct.key === \"taxes\");\n if (hasTaxes && Array.isArray(updated.taxes)) {\n updated.taxes = updated.taxes.map((tax: any) => {\n if (tax.charge_type === \"On Net Total\") {\n return {\n ...tax,\n tax_amount: flt(updated.net_total, 2) * flt(tax.rate, 2) / 100,\n };\n }\n return tax;\n });\n\n const totalTax = updated.taxes.reduce(\n (sum: number, t: any) => sum + flt(t.tax_amount, 2),\n 0,\n );\n updated.total_taxes_and_charges = totalTax;\n updated.grand_total = flt(updated.net_total, 2) + totalTax;\n }\n\n return updated;\n}\n\n// ---------------------------------------------------------------------------\n// Main form page\n// ---------------------------------------------------------------------------\n\nexport default function DocumentFormPage() {\n const { doctype, name } = useParams<{ doctype: string; name: string }>();\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n const { t } = useTranslation();\n const config = getDoctypeConfig(doctype ?? \"\");\n const isNew = !name;\n\n const [formData, setFormData] = useState<any>({});\n // True once the user picks a currency by hand, so auto-defaulting backs off.\n const [currencyTouched, setCurrencyTouched] = useState(false);\n\n // Fetch existing document\n const { data: existingDoc, isLoading } = useQuery({\n queryKey: [\"document\", doctype, name],\n queryFn: () => api.getDocument(doctype!, name!),\n enabled: !!doctype && !!name && !isNew,\n });\n\n // --- Currency defaulting (new documents only) ----------------------------\n // Pre-fill the transaction currency from the selected party's default\n // currency, falling back to the company base — mirroring the backend's\n // precedence — until the user picks one. Only sales/purchase docs have it.\n const hasCurrencyField = useMemo(\n () => !!config?.fields.some((f) => f.name === \"currency\"),\n [config],\n );\n const partyType = config?.partyField;\n const partyName = partyType ? formData[partyType] : undefined;\n const companyCurrency = useBaseCurrency(formData.company);\n\n const { data: partyMaster } = useQuery({\n queryKey: [\"master\", partyType, partyName],\n queryFn: () => api.getMaster(partyType!, partyName!),\n enabled: isNew && hasCurrencyField && !!partyType && !!partyName,\n staleTime: 5 * 60 * 1000,\n });\n\n useEffect(() => {\n if (!isNew || !hasCurrencyField || currencyTouched) return;\n let suggested: string | undefined;\n if (partyName) {\n if (!partyMaster) return; // wait for the party's currency before defaulting\n suggested = partyMaster.default_currency || companyCurrency;\n } else {\n suggested = companyCurrency;\n }\n if (suggested && suggested !== formData.currency) {\n setFormData((prev: any) => ({ ...prev, currency: suggested }));\n }\n }, [\n isNew, hasCurrencyField, currencyTouched,\n partyName, partyMaster, companyCurrency, formData.currency,\n ]);\n\n // Initialize formData\n useEffect(() => {\n if (isNew && config) {\n const defaults: any = {};\n config.fields.forEach((f) => {\n if (f.type === \"date\") {\n defaults[f.name] = new Date().toISOString().split(\"T\")[0];\n } else {\n defaults[f.name] = f.default ?? \"\";\n }\n });\n config.childTables.forEach((ct) => {\n defaults[ct.key] = [];\n });\n defaults.docstatus = 0;\n setFormData(defaults);\n } else if (existingDoc) {\n setFormData(existingDoc);\n }\n }, [isNew, existingDoc, config]);\n\n // Mutations\n const createMut = useMutation({\n mutationFn: (data: any) => api.createDocument(doctype!, data),\n onSuccess: (result) => {\n queryClient.invalidateQueries({ queryKey: [\"documents\", doctype] });\n navigate(`/app/${doctype}/${result.name}`, { replace: true });\n },\n });\n\n const updateMut = useMutation({\n mutationFn: (data: any) => api.updateDocument(doctype!, name!, data),\n onSuccess: (result) => {\n queryClient.invalidateQueries({ queryKey: [\"document\", doctype, name] });\n queryClient.invalidateQueries({ queryKey: [\"documents\", doctype] });\n setFormData(result);\n },\n });\n\n const submitMut = useMutation({\n mutationFn: () => api.submitDocument(doctype!, name!),\n onSuccess: (result) => {\n setFormData(result);\n queryClient.invalidateQueries({ queryKey: [\"document\", doctype, name] });\n queryClient.invalidateQueries({ queryKey: [\"documents\", doctype] });\n },\n });\n\n const cancelMut = useMutation({\n mutationFn: () => api.cancelDocument(doctype!, name!),\n onSuccess: (result) => {\n setFormData(result);\n queryClient.invalidateQueries({ queryKey: [\"document\", doctype, name] });\n queryClient.invalidateQueries({ queryKey: [\"documents\", doctype] });\n },\n });\n\n const discardMut = useMutation({\n mutationFn: () => api.discardDocument(doctype!, name!),\n onSuccess: () => {\n // The draft is now hidden from the default list; leave the editor.\n queryClient.invalidateQueries({ queryKey: [\"documents\", doctype] });\n navigate(`/app/${doctype}`, { replace: true });\n },\n });\n\n const convertMut = useMutation({\n mutationFn: (targetDoctype: string) =>\n api.convertDocument(doctype!, name!, targetDoctype),\n onSuccess: (result, targetDoctype) => {\n const targetSlug = targetDoctype.toLowerCase().replace(/\\s+/g, \"-\");\n navigate(`/app/${targetSlug}/${result.name}`);\n },\n });\n\n // Field change handler with recalculation\n const setField = useCallback(\n (fieldName: string, value: any) => {\n if (fieldName === \"currency\") setCurrencyTouched(true);\n setFormData((prev: any) => {\n const next = { ...prev, [fieldName]: value };\n // A new currency invalidates any prior rate; clear it so the backend\n // re-resolves the exchange rate for the chosen currency.\n if (fieldName === \"currency\") next.conversion_rate = 0;\n return recalculate(next, config);\n });\n },\n [config],\n );\n\n const setChildTable = useCallback(\n (key: string, rows: any[]) => {\n setFormData((prev: any) => {\n const next = { ...prev, [key]: rows };\n return recalculate(next, config);\n });\n },\n [config],\n );\n\n const handleSave = () => {\n if (isNew) {\n createMut.mutate(formData);\n } else {\n updateMut.mutate(formData);\n }\n };\n\n const handleSubmit = () => {\n submitMut.mutate();\n };\n\n const handleCancel = () => {\n // Cancelling reverses all postings (GL + stock) and is irreversible. The\n // two-step confirm UI lives in DocumentActions (the confirm button appears\n // in a different place, so a double-click can't fire it by accident).\n cancelMut.mutate();\n };\n\n const handleConvert = (targetDoctype: string) => {\n convertMut.mutate(targetDoctype);\n };\n\n const handleDiscard = () => {\n // Soft delete of an unwanted draft — no postings to reverse. Confirmation\n // is handled inline in DocumentActions.\n discardMut.mutate();\n };\n\n if (!config) {\n return (\n <p className=\"text-fg-muted\">\n Unknown document type: {doctype}\n </p>\n );\n }\n\n if (!isNew && isLoading) {\n return <p className=\"text-fg-muted\">{t(\"common.loading\")}</p>;\n }\n\n const docstatus: number = formData.docstatus ?? 0;\n const discarded = !!formData.discarded;\n // A discarded draft is voided/terminal — lock it like a submitted document.\n const readOnly = docstatus >= 1 || discarded;\n\n // The document's currency drives how amounts are formatted (€/£/¥ vs $).\n // Documents without a currency field (Stock Entry, …) store their values in\n // the company BASE currency — falling back to a hardcoded USD stamped $ on\n // CHF numbers. Fall back to the company currency instead.\n const docCurrency: string = formData.currency || companyCurrency;\n const docRate: number = flt(formData.conversion_rate ?? 1);\n\n // Separate editable parent fields from computed/totals fields. Textareas\n // (Notes / Terms) are pulled onto their own full-width row below the grid so\n // there's room to write — and to surface the markup the field supports.\n const editableFields = config.fields.filter((f) => !f.readOnly);\n const gridFields = editableFields.filter((f) => f.type !== \"textarea\");\n const noteFields = editableFields.filter((f) => f.type === \"textarea\");\n const totalsFields = config.fields.filter((f) => f.readOnly);\n\n return (\n <div className=\"space-y-6\">\n {/* Header — stacks on mobile (status pill on top, action buttons\n below) since on a narrow screen the action buttons wrap to multiple\n lines and items-center vertically centers the pill against the\n tall buttons column, leaving it floating in dead space. From sm:\n up, side-by-side again. */}\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-center gap-3\">\n {!isNew && <DocPager slug={config.slug} name={name!} onSave={handleSave} />}\n {!isNew && formData.status && (\n <StatusBadge status={formData.status} />\n )}\n {!isNew && formData.currency && (\n <span\n className=\"inline-flex items-center gap-1 rounded-full bg-surface-subtle px-2.5 py-0.5 text-xs font-medium text-fg-muted ring-1 ring-line\"\n title={docRate !== 1 ? `1 ${docCurrency} = ${docRate} base currency` : undefined}\n >\n {docCurrency}\n {docRate !== 1 && <span className=\"text-fg-muted/70\">@ {docRate}</span>}\n </span>\n )}\n </div>\n <DocumentActions\n isNew={isNew}\n doctype={doctype}\n name={name}\n docstatus={docstatus}\n saving={createMut.isPending || updateMut.isPending}\n config={config}\n discarded={discarded}\n onSave={handleSave}\n onSubmit={handleSubmit}\n onCancel={handleCancel}\n onConvert={handleConvert}\n onDiscard={handleDiscard}\n />\n </div>\n\n {/* Error display */}\n {(createMut.error || updateMut.error || submitMut.error || cancelMut.error) && (\n <div className=\"rounded-lg bg-rose-50 p-4 text-sm text-rose-700 ring-1 ring-rose-200\">\n {(createMut.error ?? updateMut.error ?? submitMut.error ?? cancelMut.error)\n ?.message ?? t(\"common.errorOccurred\")}\n </div>\n )}\n\n {/* Parent fields */}\n <Card>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {gridFields.map((field) => (\n <FieldRenderer\n key={field.name}\n field={field}\n value={formData[field.name]}\n onChange={(v) => setField(field.name, v)}\n readOnly={readOnly}\n rowData={formData}\n currency={docCurrency}\n />\n ))}\n </div>\n {/* Notes / Terms — full width, below Company/Currency etc. */}\n {noteFields.length > 0 && (\n <div className=\"mt-4 space-y-4\">\n {noteFields.map((field) => (\n <FieldRenderer\n key={field.name}\n field={field}\n value={formData[field.name]}\n onChange={(v) => setField(field.name, v)}\n readOnly={readOnly}\n rowData={formData}\n currency={docCurrency}\n />\n ))}\n </div>\n )}\n </Card>\n\n {/* Child tables */}\n {config.childTables.map((ct) => (\n <ChildTableEditor\n key={ct.key}\n tableDef={ct}\n rows={formData[ct.key] ?? []}\n onChange={(rows) => setChildTable(ct.key, rows)}\n readOnly={readOnly}\n currency={docCurrency}\n />\n ))}\n\n {/* Totals section */}\n {totalsFields.length > 0 && (\n <Card title={t(\"common.totals\")}>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n {totalsFields.map((field) => (\n <FieldRenderer\n key={field.name}\n field={field}\n value={formData[field.name]}\n onChange={() => {}}\n readOnly={true}\n currency={docCurrency}\n />\n ))}\n </div>\n </Card>\n )}\n </div>\n );\n}\n","function iso(d: Date): string {\n return d.toISOString().split(\"T\")[0];\n}\n\nfunction startOfWeek(d: Date): Date {\n const r = new Date(d);\n const day = r.getDay();\n // Monday = 1; JS Sunday = 0 → treat Sunday as 7\n const diff = day === 0 ? 6 : day - 1;\n r.setDate(r.getDate() - diff);\n return r;\n}\n\nfunction endOfWeek(d: Date): Date {\n const s = startOfWeek(d);\n s.setDate(s.getDate() + 6);\n return s;\n}\n\nfunction startOfMonth(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth(), 1);\n}\n\nfunction endOfMonth(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth() + 1, 0);\n}\n\nfunction startOfQuarter(d: Date): Date {\n const q = Math.floor(d.getMonth() / 3);\n return new Date(d.getFullYear(), q * 3, 1);\n}\n\nfunction endOfQuarter(d: Date): Date {\n const s = startOfQuarter(d);\n return new Date(s.getFullYear(), s.getMonth() + 3, 0);\n}\n\nfunction startOfYear(d: Date): Date {\n return new Date(d.getFullYear(), 0, 1);\n}\n\nfunction endOfYear(d: Date): Date {\n return new Date(d.getFullYear(), 11, 31);\n}\n\ninterface Preset {\n label: string;\n range: () => [string, string];\n}\n\nconst PRESETS: Preset[] = [\n {\n label: \"Today\",\n range: () => {\n const t = iso(new Date());\n return [t, t];\n },\n },\n {\n label: \"This Week\",\n range: () => [iso(startOfWeek(new Date())), iso(endOfWeek(new Date()))],\n },\n {\n label: \"This Month\",\n range: () => [iso(startOfMonth(new Date())), iso(endOfMonth(new Date()))],\n },\n {\n label: \"This Quarter\",\n range: () => [iso(startOfQuarter(new Date())), iso(endOfQuarter(new Date()))],\n },\n {\n label: \"This Year\",\n range: () => [iso(startOfYear(new Date())), iso(endOfYear(new Date()))],\n },\n {\n label: \"Last Month\",\n range: () => {\n const now = new Date();\n const lastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);\n return [iso(startOfMonth(lastMonth)), iso(endOfMonth(lastMonth))];\n },\n },\n {\n label: \"Last Quarter\",\n range: () => {\n const now = new Date();\n const lastQuarter = new Date(now.getFullYear(), now.getMonth() - 3, 1);\n return [iso(startOfQuarter(lastQuarter)), iso(endOfQuarter(lastQuarter))];\n },\n },\n {\n label: \"Last Year\",\n range: () => {\n const lastYear = new Date(new Date().getFullYear() - 1, 6, 1);\n return [iso(startOfYear(lastYear)), iso(endOfYear(lastYear))];\n },\n },\n];\n\ninterface DateRangePresetsProps {\n onSelect: (from: string, to: string) => void;\n}\n\nexport function DateRangePresets({ onSelect }: DateRangePresetsProps) {\n return (\n <div className=\"flex flex-wrap gap-1.5\">\n {PRESETS.map((p) => (\n <button\n key={p.label}\n type=\"button\"\n onClick={() => {\n const [from, to] = p.range();\n onSelect(from, to);\n }}\n className=\"rounded-full bg-surface px-3 py-1 text-xs text-fg-muted ring-1 ring-line transition-all hover:bg-surface-subtle hover:text-fg hover:ring-brand/30\"\n >\n {p.label}\n </button>\n ))}\n </div>\n );\n}\n\ninterface SingleDatePresetsProps {\n onSelect: (date: string) => void;\n}\n\nexport function SingleDatePresets({ onSelect }: SingleDatePresetsProps) {\n const presets: { label: string; value: () => string }[] = [\n { label: \"Today\", value: () => iso(new Date()) },\n { label: \"End of This Month\", value: () => iso(endOfMonth(new Date())) },\n { label: \"End of Last Month\", value: () => {\n const now = new Date();\n return iso(endOfMonth(new Date(now.getFullYear(), now.getMonth() - 1, 1)));\n } },\n { label: \"End of This Quarter\", value: () => iso(endOfQuarter(new Date())) },\n { label: \"End of This Year\", value: () => iso(endOfYear(new Date())) },\n { label: \"End of Last Year\", value: () => iso(endOfYear(new Date(new Date().getFullYear() - 1, 0, 1))) },\n ];\n\n return (\n <div className=\"flex flex-wrap gap-1.5\">\n {presets.map((p) => (\n <button\n key={p.label}\n type=\"button\"\n onClick={() => onSelect(p.value())}\n className=\"rounded-full bg-surface px-3 py-1 text-xs text-fg-muted ring-1 ring-line transition-all hover:bg-surface-subtle hover:text-fg hover:ring-brand/30\"\n >\n {p.label}\n </button>\n ))}\n </div>\n );\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { Link, useParams, useLocation } from \"react-router-dom\";\nimport { setListContext } from \"@/lib/doc-list-context\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n useReactTable,\n getCoreRowModel,\n flexRender,\n createColumnHelper,\n type ColumnDef,\n} from \"@tanstack/react-table\";\nimport { useDocumentList } from \"@/hooks/use-document-list\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\nimport { useUrlState, useUrlPatch } from \"@/hooks/use-url-state\";\nimport { getDoctypeConfig } from \"@/lib/doctypes\";\nimport { linkRefHref } from \"@/pages/documents/document-form\";\nimport { StatusBadge } from \"@/components/document/status-badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Select } from \"@/components/ui/select\";\nimport { DateRangePresets } from \"@/components/ui/date-range-presets\";\nimport { formatCurrency, formatDate } from \"@/lib/utils\";\n\nconst STATUS_OPTIONS = [\"All\", \"Draft\", \"Submitted\", \"Cancelled\"];\n\nconst CURRENCY_FIELDS = new Set([\n \"grand_total\",\n \"outstanding_amount\",\n \"paid_amount\",\n \"total_debit\",\n \"total_amount\",\n \"net_total\",\n]);\n\nconst DATE_FIELDS = new Set([\n \"transaction_date\",\n \"posting_date\",\n \"due_date\",\n \"delivery_date\",\n \"valid_till\",\n \"date\",\n]);\n\n// Columns that reference a master record — rendered as clickable links to the master page.\nconst MASTER_REF_FIELDS: Record<string, string> = {\n customer: \"customer\",\n supplier: \"supplier\",\n item_code: \"item\",\n item: \"item\",\n warehouse: \"warehouse\",\n company: \"company\",\n account: \"account\",\n cost_center: \"cost-center\",\n};\n\n// `party` references different master types depending on `party_type` in the row.\nfunction partyMasterType(partyType: unknown): string | null {\n if (typeof partyType !== \"string\") return null;\n const t = partyType.toLowerCase();\n if (t === \"customer\") return \"customer\";\n if (t === \"supplier\") return \"supplier\";\n return null;\n}\n\nconst PAGE_SIZE_OPTIONS = [\"25\", \"50\", \"100\", \"200\"];\n\n// Pagination controls, rendered both above and below the table so long lists\n// don't force a scroll to the bottom to page. The current page is a typeable\n// field (commit on Enter/blur, clamped to 1..totalPages).\nfunction ListPager({\n page,\n totalPages,\n pageSize,\n total,\n rangeStart,\n rangeEnd,\n setPage,\n setPageSize,\n}: {\n page: number;\n totalPages: number;\n pageSize: number;\n total: number;\n rangeStart: number;\n rangeEnd: number;\n setPage: (p: number) => void;\n setPageSize: (n: number) => void;\n}) {\n const { t } = useTranslation();\n const [pageInput, setPageInput] = useState(String(page + 1));\n useEffect(() => setPageInput(String(page + 1)), [page]);\n\n const commit = () => {\n const n = parseInt(pageInput, 10);\n if (!isNaN(n)) setPage(Math.min(totalPages, Math.max(1, n)) - 1);\n else setPageInput(String(page + 1));\n };\n\n return (\n <div className=\"flex flex-wrap items-center justify-between gap-3 text-sm text-fg-muted\">\n <div>\n {t(\"common.showing\")} <span className=\"font-medium text-fg\">{rangeStart}–{rangeEnd}</span>{\" \"}\n {t(\"common.of\")} <span className=\"font-medium text-fg\">{total}</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <label className=\"flex items-center gap-1.5\">\n <span className=\"text-xs text-fg-muted\">{t(\"common.perPage\")}</span>\n <select\n value={pageSize}\n onChange={(e) => setPageSize(Number(e.target.value))}\n className=\"h-8 rounded-md bg-surface px-2 text-sm text-fg ring-1 ring-line transition-all focus:outline-none focus:ring-2 focus:ring-brand/30\"\n >\n {PAGE_SIZE_OPTIONS.map((n) => (\n <option key={n} value={n}>{n}</option>\n ))}\n </select>\n </label>\n <button\n onClick={() => setPage(Math.max(0, page - 1))}\n disabled={page === 0}\n className=\"rounded-md bg-surface px-3 py-1 text-sm text-fg ring-1 ring-line transition-colors hover:bg-surface-subtle disabled:cursor-not-allowed disabled:opacity-40\"\n >\n {t(\"common.prev\")}\n </button>\n <span className=\"flex items-center gap-1 text-xs\">\n {t(\"common.page\")}\n <input\n aria-label={t(\"common.page\")}\n inputMode=\"numeric\"\n value={pageInput}\n onChange={(e) => setPageInput(e.target.value.replace(/[^0-9]/g, \"\"))}\n onBlur={commit}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") e.currentTarget.blur();\n }}\n className=\"h-7 w-12 rounded-md bg-surface px-1 text-center text-sm font-medium text-fg ring-1 ring-line focus:outline-none focus:ring-2 focus:ring-brand/30\"\n />\n {t(\"common.of\")} <span className=\"font-medium text-fg\">{totalPages}</span>\n </span>\n <button\n onClick={() => setPage(Math.min(totalPages - 1, page + 1))}\n disabled={page >= totalPages - 1}\n className=\"rounded-md bg-surface px-3 py-1 text-sm text-fg ring-1 ring-line transition-colors hover:bg-surface-subtle disabled:cursor-not-allowed disabled:opacity-40\"\n >\n {t(\"common.next\")}\n </button>\n </div>\n </div>\n );\n}\n\nexport default function DocumentListPage() {\n const { t } = useTranslation();\n // Rows without a per-document currency (Stock Entry, …) hold base-currency\n // values — format them with the company currency, not a hardcoded USD.\n const baseCurrency = useBaseCurrency();\n const { doctype } = useParams<{ doctype: string }>();\n const config = getDoctypeConfig(doctype ?? \"\");\n const location = useLocation();\n\n // Config-driven filter dropdowns (opt-in via config.listFilters). Their values\n // live in the URL like every other filter; read them generically since the\n // field names are dynamic. Each names a select field whose options drive the\n // dropdown; the selection is sent as a plain column filter.\n const configFilters = config?.listFilters ?? [];\n const filterValues = useMemo(() => {\n const params = new URLSearchParams(location.search);\n const out: Record<string, string> = {};\n for (const f of configFilters) out[f] = params.get(f) ?? \"\";\n return out;\n }, [location.search, configFilters]);\n\n // All user-facing filter state lives in the URL. The param names are the\n // short human-readable form (`from` / `to` / `per_page`); the backend still\n // wants `from_date` / `to_date` / `limit` / `offset`, translated below.\n const [status] = useUrlState<string>(\"status\", \"All\");\n const [fromDate] = useUrlState<string>(\"from\", \"\");\n const [toDate] = useUrlState<string>(\"to\", \"\");\n const [showDiscarded] = useUrlState<string>(\"discarded\", \"\");\n const [pageSize] = useUrlState<number>(\"per_page\", 50);\n // Free-text search (opt-in via config.searchFields). The committed query lives\n // in the URL (`q`); a local input debounces into it so we don't refetch on\n // every keystroke.\n const searchFields = config?.searchFields ?? [];\n const [urlQ] = useUrlState<string>(\"q\", \"\");\n const [searchInput, setSearchInput] = useState(urlQ);\n // URL is human-friendly 1-indexed; internal state stays 0-indexed for\n // offset calculation. setPage accepts the 0-indexed value.\n const [urlPage] = useUrlState<number>(\"page\", 1);\n const page = urlPage - 1;\n const patchUrl = useUrlPatch();\n\n // All writes go through one atomic patch so multiple params update together\n // — calling two individual setters in the same handler races (react-router\n // caches the previous searchParams, so the last call wins).\n const setPage = (p: number) => patchUrl({ page: p === 0 ? null : p + 1 });\n const setStatus = (s: string) => patchUrl({ status: s === \"All\" ? null : s, page: null });\n const setFromDate = (s: string) => patchUrl({ from: s || null, page: null });\n const setToDate = (s: string) => patchUrl({ to: s || null, page: null });\n const setShowDiscarded = (on: boolean) => patchUrl({ discarded: on ? \"1\" : null, page: null });\n const setPageSize = (n: number) => patchUrl({ per_page: n, page: null });\n\n // Keep the box in sync when `q` changes from outside typing (back/forward, a\n // cleared filter), then debounce local edits back into the URL after a pause.\n useEffect(() => { setSearchInput(urlQ); }, [urlQ]);\n useEffect(() => {\n if (searchInput === urlQ) return; // idle — nothing to commit, no timer\n const t = setTimeout(() => patchUrl({ q: searchInput || null, page: null }), 300);\n return () => clearTimeout(t);\n }, [searchInput, urlQ]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const filters = useMemo(() => {\n const f: Record<string, string | number | undefined> = {};\n // The default status dropdown is hidden when a doctype opts into its own\n // filters, so only apply it in that default case.\n if (configFilters.length === 0 && status !== \"All\") f.status = status;\n if (fromDate) f.from_date = fromDate;\n if (toDate) f.to_date = toDate;\n // Tell the backend which column the date range filters on. Without this the\n // server only knows the built-in core doctypes; plugin doctypes' date\n // pickers would be silently ignored.\n if (config?.dateField) f.date_field = config.dateField;\n for (const key of configFilters) {\n if (filterValues[key]) f[key] = filterValues[key];\n }\n // Free-text search across the config's searchFields (the committed URL `q`).\n if (searchFields.length > 0 && urlQ) {\n f.search = urlQ;\n f.search_fields = searchFields.join(\",\");\n }\n if (showDiscarded) f.include_discarded = \"true\";\n f.limit = pageSize;\n f.offset = page * pageSize;\n return f;\n }, [status, fromDate, toDate, showDiscarded, pageSize, page, config?.dateField, configFilters, filterValues, searchFields, urlQ]);\n\n const { data, isLoading } = useDocumentList(doctype ?? \"\", filters);\n const rows = data?.rows ?? [];\n const total = data?.total ?? 0;\n\n // Remember this list's filters + URL so a detail page's prev/next (DocPager)\n // follows it, and \"back to list\" returns here. Pagination is dropped — it's\n // not a record filter.\n useEffect(() => {\n const { limit, offset, ...ctxFilters } = filters;\n setListContext(doctype ?? \"\", { filters: ctxFilters, search: location.search });\n }, [doctype, filters, location.search]);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n const rangeStart = total === 0 ? 0 : page * pageSize + 1;\n const rangeEnd = Math.min(total, (page + 1) * pageSize);\n\n const columns = useMemo<ColumnDef<any, any>[]>(() => {\n if (!config) return [];\n const helper = createColumnHelper<any>();\n // Title-case a column slug, then translate it (English title-case is the\n // fallback when a field has no translation yet).\n const headerLabel = (c: string) => {\n const titleCased = c\n .split(\"_\")\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(\" \");\n return t(`fields.${titleCased}`, { defaultValue: titleCased });\n };\n\n return config.listColumns.map((col) => {\n if (col === \"name\") {\n return helper.accessor(\"name\", {\n header: t(\"fields.Name\", { defaultValue: \"Name\" }),\n cell: (info) => (\n <Link\n to={`/app/${config.slug}/${info.getValue()}`}\n className=\"font-medium text-brand transition-colors hover:text-brand/80\"\n >\n {info.getValue()}\n </Link>\n ),\n });\n }\n\n if (col === \"status\") {\n return helper.accessor(\"status\", {\n header: t(\"fields.Status\", { defaultValue: \"Status\" }),\n cell: (info) => <StatusBadge status={info.getValue()} />,\n });\n }\n\n if (CURRENCY_FIELDS.has(col)) {\n return helper.accessor(col, {\n header: headerLabel(col),\n cell: (info) => formatCurrency(info.getValue(), (info.row.original as any)?.currency || baseCurrency),\n });\n }\n\n if (col === \"party\") {\n return helper.accessor(\"party\", {\n header: t(\"fields.Party\", { defaultValue: \"Party\" }),\n cell: (info) => {\n const value = info.getValue();\n if (!value) return \"-\";\n const masterType = partyMasterType(info.row.original.party_type);\n const href = masterType ? linkRefHref(masterType, String(value)) : null;\n if (!href) return String(value);\n return (\n <Link\n to={href}\n onClick={(e) => e.stopPropagation()}\n className=\"text-brand transition-colors hover:text-brand/80 hover:underline\"\n >\n {value}\n </Link>\n );\n },\n });\n }\n\n if (MASTER_REF_FIELDS[col]) {\n const masterType = MASTER_REF_FIELDS[col];\n return helper.accessor(col, {\n header: headerLabel(col),\n cell: (info) => {\n const value = info.getValue();\n if (!value) return \"-\";\n const href = linkRefHref(masterType, String(value));\n if (!href) return String(value);\n return (\n <Link\n to={href}\n onClick={(e) => e.stopPropagation()}\n className=\"text-brand transition-colors hover:text-brand/80 hover:underline\"\n >\n {value}\n </Link>\n );\n },\n });\n }\n\n if (DATE_FIELDS.has(col)) {\n return helper.accessor(col, {\n header: headerLabel(col),\n cell: (info) => formatDate(info.getValue()),\n });\n }\n\n return helper.accessor(col, {\n header: headerLabel(col),\n });\n });\n }, [config, t, baseCurrency]);\n\n const table = useReactTable({\n data: rows,\n columns,\n getCoreRowModel: getCoreRowModel(),\n });\n\n if (!config) {\n return (\n <p className=\"text-fg-muted\">\n Unknown document type: {doctype}\n </p>\n );\n }\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-end\">\n <Link to={`/app/${config.slug}/new`}>\n <Button>{t(\"common.new\")}</Button>\n </Link>\n </div>\n\n <div className=\"flex flex-wrap items-end gap-4\">\n {searchFields.length > 0 && (\n <Input\n label={t(\"common.search\", { defaultValue: \"Search\" })}\n type=\"search\"\n placeholder={t(\"common.searchPlaceholder\", { defaultValue: \"Search…\" })}\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n className=\"min-w-[16rem]\"\n />\n )}\n {configFilters.length === 0 ? (\n <Select\n label={t(\"fields.Status\", { defaultValue: \"Status\" })}\n options={STATUS_OPTIONS.map((s) => ({\n value: s,\n label: s === \"All\" ? t(\"common.all\") : t(`status.${s}`, { defaultValue: s }),\n }))}\n value={status}\n onChange={(e) => setStatus(e.target.value)}\n />\n ) : (\n configFilters.map((key) => {\n const field = config.fields.find((f) => f.name === key);\n const opts = (field?.options ?? []).map((o) =>\n typeof o === \"string\" ? { value: o, label: o } : o,\n );\n return (\n <Select\n key={key}\n label={t(`fields.${field?.label ?? key}`, { defaultValue: field?.label ?? key })}\n options={[{ value: \"\", label: t(\"common.all\") }, ...opts]}\n value={filterValues[key]}\n onChange={(e) => patchUrl({ [key]: e.target.value || null, page: null })}\n />\n );\n })\n )}\n <Input\n label={t(\"fields.From Date\", { defaultValue: \"From Date\" })}\n type=\"date\"\n value={fromDate}\n onChange={(e) => setFromDate(e.target.value)}\n />\n <Input\n label={t(\"fields.To Date\", { defaultValue: \"To Date\" })}\n type=\"date\"\n value={toDate}\n onChange={(e) => setToDate(e.target.value)}\n />\n <label className=\"flex h-10 items-center gap-2 text-sm text-fg-muted\">\n <input\n type=\"checkbox\"\n className=\"h-4 w-4 rounded border-line text-brand focus:ring-brand/30\"\n checked={!!showDiscarded}\n onChange={(e) => setShowDiscarded(e.target.checked)}\n />\n {t(\"common.showDiscarded\")}\n </label>\n </div>\n <DateRangePresets onSelect={(from, to) => patchUrl({ from, to, page: null })} />\n\n {isLoading ? (\n <p className=\"text-fg-muted\">{t(\"common.loading\")}</p>\n ) : rows.length === 0 ? (\n <p className=\"py-8 text-center text-fg-muted\">{t(\"reports.noDocuments\")}</p>\n ) : (\n <>\n <ListPager\n page={page}\n totalPages={totalPages}\n pageSize={pageSize}\n total={total}\n rangeStart={rangeStart}\n rangeEnd={rangeEnd}\n setPage={setPage}\n setPageSize={setPageSize}\n />\n <div className=\"overflow-x-auto rounded-xl bg-surface ring-1 ring-line shadow-card\">\n <table className=\"min-w-full divide-y divide-line text-sm\">\n <thead className=\"bg-surface-subtle\">\n {table.getHeaderGroups().map((headerGroup) => (\n <tr key={headerGroup.id}>\n {headerGroup.headers.map((header) => (\n <th\n key={header.id}\n className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-fg-muted\"\n >\n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n </th>\n ))}\n </tr>\n ))}\n </thead>\n <tbody className=\"divide-y divide-line\">\n {table.getRowModel().rows.map((row) => (\n <tr key={row.id} className=\"transition-colors hover:bg-surface-subtle\">\n {row.getVisibleCells().map((cell) => (\n <td key={cell.id} className=\"px-4 py-2.5 text-fg\">\n {flexRender(\n cell.column.columnDef.cell,\n cell.getContext(),\n )}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n\n <ListPager\n page={page}\n totalPages={totalPages}\n pageSize={pageSize}\n total={total}\n rangeStart={rangeStart}\n rangeEnd={rangeEnd}\n setPage={setPage}\n setPageSize={setPageSize}\n />\n </>\n )}\n </div>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { api } from \"@/api/client\";\nimport { cn } from \"@/lib/utils\";\n\ninterface LinkFieldProps {\n label: string;\n value: string;\n onChange: (value: string) => void;\n linkDoctype: string;\n readOnly: boolean;\n}\n\nexport function LinkField({\n label,\n value,\n onChange,\n linkDoctype,\n readOnly,\n}: LinkFieldProps) {\n const [query, setQuery] = useState(value ?? \"\");\n const [results, setResults] = useState<any[]>([]);\n const [open, setOpen] = useState(false);\n const [loading, setLoading] = useState(false);\n const [dropdownStyle, setDropdownStyle] = useState<React.CSSProperties>({});\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const selectingRef = useRef(false);\n\n // Sync external value changes\n useEffect(() => {\n setQuery(value ?? \"\");\n }, [value]);\n\n const updateDropdownPosition = useCallback(() => {\n if (inputRef.current) {\n const rect = inputRef.current.getBoundingClientRect();\n setDropdownStyle({\n position: \"fixed\",\n top: rect.bottom + 4,\n left: rect.left,\n width: rect.width,\n zIndex: 9999,\n });\n }\n }, []);\n\n const search = useCallback(\n (q: string) => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(async () => {\n setLoading(true);\n try {\n const data = await api.searchLink(linkDoctype, q);\n setResults(data);\n setOpen(true);\n } catch {\n setResults([]);\n } finally {\n setLoading(false);\n }\n }, 300);\n },\n [linkDoctype],\n );\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const q = e.target.value;\n setQuery(q);\n search(q);\n };\n\n const handleSelect = (item: any) => {\n const name = item.name ?? item.id ?? String(item);\n setQuery(name);\n onChange(name);\n setOpen(false);\n setResults([]);\n };\n\n const handleBlur = () => {\n setTimeout(() => {\n if (selectingRef.current) {\n selectingRef.current = false;\n return;\n }\n setOpen(false);\n if (query !== value) {\n onChange(query);\n }\n }, 150);\n };\n\n // Close dropdown on outside click (check both container and portal dropdown)\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n const target = e.target as Node;\n if (containerRef.current?.contains(target)) return;\n if (dropdownRef.current?.contains(target)) return;\n setOpen(false);\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, []);\n\n if (readOnly) {\n return (\n <div>\n {label && (\n <span className=\"mb-1.5 block text-sm font-medium text-fg\">\n {label}\n </span>\n )}\n <span className=\"text-sm text-fg\">{value || \"\\u2014\"}</span>\n </div>\n );\n }\n\n return (\n <div ref={containerRef} className=\"relative\">\n {label && (\n <label className=\"mb-1.5 block text-sm font-medium text-fg\">\n {label}\n </label>\n )}\n <input\n ref={inputRef}\n type=\"text\"\n value={query}\n onChange={handleInputChange}\n onFocus={() => {\n updateDropdownPosition();\n search(query);\n }}\n onBlur={handleBlur}\n placeholder={`Search ${linkDoctype}...`}\n className={cn(\n \"block h-9 w-full rounded-lg bg-surface px-3 text-sm text-fg ring-1 ring-line transition-all placeholder:text-fg-muted/70 focus:outline-none focus:ring-2 focus:ring-brand/30\",\n loading && \"bg-surface-subtle\",\n )}\n />\n {open && results.length > 0 && createPortal(\n <div ref={dropdownRef} style={dropdownStyle} className=\"max-h-48 overflow-y-auto rounded-lg bg-surface ring-1 ring-line shadow-card-hover\">\n {results.map((item, i) => {\n const name = item.name ?? item.id ?? String(item);\n return (\n <button\n key={i}\n type=\"button\"\n onMouseDown={() => { selectingRef.current = true; }}\n onClick={() => handleSelect(item)}\n className=\"block w-full px-3 py-1.5 text-left text-sm text-fg transition-colors hover:bg-surface-subtle\"\n >\n {name}\n </button>\n );\n })}\n </div>,\n document.body,\n )}\n </div>\n );\n}\n","import { useState, useEffect, useRef } from \"react\";\nimport { useParams, useNavigate } from \"react-router-dom\";\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { useTranslation } from \"react-i18next\";\nimport { api } from \"@/api/client\";\nimport { LinkField } from \"@/components/document/link-field\";\nimport { Button } from \"@/components/ui/button\";\nimport { useConfirm } from \"@/components/ui/dialog\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\n\n// A Proposal (Sammelofferte) bundles several independent quotations into one\n// branded PDF. It is print-only: nothing here touches the quotations' own\n// lifecycle. Saving lets the user reopen/duplicate so cover text isn't retyped.\n\ninterface PositionRow {\n quotation: string;\n position_title: string;\n position_blurb: string;\n is_recommended: number;\n}\n\nconst blankRow = (): PositionRow => ({\n quotation: \"\",\n position_title: \"\",\n position_blurb: \"\",\n is_recommended: 0,\n});\n\nconst LETTERS = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n\nexport default function ProposalForm() {\n const { name } = useParams<{ name: string }>();\n const isNew = !name;\n const navigate = useNavigate();\n const qc = useQueryClient();\n const { t } = useTranslation();\n const tr = (k: string, dflt: string) => t(k, { defaultValue: dflt });\n const confirm = useConfirm();\n\n const [form, setForm] = useState<Record<string, string>>({\n title: \"Offerte\",\n customer: \"\",\n company: \"\",\n proposal_date: new Date().toISOString().slice(0, 10),\n partner_name: \"\",\n partner_email: \"\",\n cover_letter: \"\",\n });\n const [rows, setRows] = useState<PositionRow[]>([blankRow()]);\n const [appendix, setAppendix] = useState<string | null>(null);\n const [appendixBusy, setAppendixBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const fileRef = useRef<HTMLInputElement>(null);\n\n const set = (k: string, v: string) => setForm((f) => ({ ...f, [k]: v }));\n\n // Load an existing proposal.\n const { data: existing } = useQuery({\n queryKey: [\"document\", \"proposal\", name],\n queryFn: () => api.getDocument(\"proposal\", name!),\n enabled: !isNew,\n });\n\n useEffect(() => {\n if (!existing) return;\n setForm({\n title: existing.title ?? \"Offerte\",\n customer: existing.customer ?? \"\",\n company: existing.company ?? \"\",\n proposal_date: existing.proposal_date ?? \"\",\n partner_name: existing.partner_name ?? \"\",\n partner_email: existing.partner_email ?? \"\",\n cover_letter: existing.cover_letter ?? \"\",\n });\n const qs = (existing.quotations ?? []) as PositionRow[];\n setRows(qs.length ? qs.map((r) => ({ ...blankRow(), ...r })) : [blankRow()]);\n setAppendix(existing.appendix_filename ?? null);\n }, [existing]);\n\n // Pre-fill the cover letter from the company template once a customer is\n // chosen on a NEW proposal and the letter is still empty — so the salutation\n // and intro aren't retyped. Never clobbers text the user has entered.\n const loadCoverDefault = async () => {\n try {\n const { cover_letter } = await api.getProposalCoverDefault(form.company, form.customer);\n if (cover_letter) set(\"cover_letter\", cover_letter);\n } catch {\n /* a missing template is fine */\n }\n };\n useEffect(() => {\n if (isNew && form.customer && !form.cover_letter) loadCoverDefault();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [form.customer, form.company]);\n\n const payload = () => ({\n ...form,\n quotations: rows\n .filter((r) => r.quotation)\n .map((r, i) => ({ ...r, idx: i + 1, is_recommended: r.is_recommended ? 1 : 0 })),\n });\n\n const saveMut = useMutation({\n mutationFn: async () => {\n if (isNew) return api.createDocument(\"proposal\", payload());\n return api.updateDocument(\"proposal\", name!, payload());\n },\n onSuccess: (res) => {\n setError(null);\n qc.invalidateQueries({ queryKey: [\"documents\", \"proposal\"] });\n qc.invalidateQueries({ queryKey: [\"document\", \"proposal\", res.name] });\n if (isNew) navigate(`/app/proposal/${encodeURIComponent(res.name)}`);\n },\n onError: (e: any) => setError(e?.message ?? \"Save failed\"),\n });\n\n const discardMut = useMutation({\n mutationFn: () => api.discardDocument(\"proposal\", name!),\n onSuccess: () => {\n qc.invalidateQueries({ queryKey: [\"documents\", \"proposal\"] });\n navigate(\"/app/proposal\");\n },\n onError: (e: any) => setError(e?.message ?? \"Discard failed\"),\n });\n\n // --- Position rows ---\n const updateRow = (i: number, patch: Partial<PositionRow>) =>\n setRows((rs) => rs.map((r, j) => (j === i ? { ...r, ...patch } : r)));\n const addRow = () => setRows((rs) => [...rs, blankRow()]);\n const removeRow = (i: number) => setRows((rs) => (rs.length > 1 ? rs.filter((_, j) => j !== i) : rs));\n const moveRow = (i: number, dir: -1 | 1) =>\n setRows((rs) => {\n const j = i + dir;\n if (j < 0 || j >= rs.length) return rs;\n const next = [...rs];\n [next[i], next[j]] = [next[j], next[i]];\n return next;\n });\n\n // --- Appendix ---\n const onPickAppendix = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n e.target.value = \"\";\n if (!file || isNew) return;\n setAppendixBusy(true);\n setError(null);\n try {\n const res = await api.uploadProposalAppendix(name!, file);\n setAppendix(res.appendix_filename);\n qc.invalidateQueries({ queryKey: [\"document\", \"proposal\", name] });\n } catch (err: any) {\n setError(err?.message ?? \"Upload failed\");\n } finally {\n setAppendixBusy(false);\n }\n };\n const removeAppendix = async () => {\n if (isNew) return;\n setAppendixBusy(true);\n try {\n await api.deleteProposalAppendix(name!);\n setAppendix(null);\n } catch (err: any) {\n setError(err?.message ?? \"Failed\");\n } finally {\n setAppendixBusy(false);\n }\n };\n\n return (\n <div className=\"mx-auto max-w-4xl space-y-5 pb-16\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-xl font-semibold text-fg\">\n {isNew ? tr(\"proposal.new\", \"New Proposal\") : (form.title || tr(\"proposal.title\", \"Proposal\"))}\n </h1>\n {!isNew && <p className=\"text-sm text-fg-muted\">{name}</p>}\n </div>\n <div className=\"flex gap-2\">\n {!isNew && (\n <Button\n variant=\"danger\"\n disabled={discardMut.isPending}\n onClick={async () => {\n if (await confirm({\n title: tr(\"proposal.discardConfirm\", \"Discard this proposal? It will be hidden from the list.\"),\n confirmLabel: tr(\"common.discard\", \"Discard\"),\n danger: true,\n })) {\n discardMut.mutate();\n }\n }}\n >\n {discardMut.isPending ? tr(\"common.discarding\", \"Discarding…\") : tr(\"common.discard\", \"Discard\")}\n </Button>\n )}\n {!isNew && (\n <Button variant=\"secondary\" onClick={() => window.open(api.proposalPdfUrl(name!), \"_blank\")}>\n {tr(\"common.pdf\", \"PDF\")}\n </Button>\n )}\n <Button onClick={() => saveMut.mutate()} disabled={saveMut.isPending}>\n {saveMut.isPending ? tr(\"common.saving\", \"Saving…\") : tr(\"common.save\", \"Save\")}\n </Button>\n </div>\n </div>\n\n {error && (\n <div className=\"rounded-lg bg-red-50 px-4 py-2 text-sm text-red-700 ring-1 ring-red-200\">{error}</div>\n )}\n\n {/* Header fields */}\n <Card className=\"space-y-4 p-5\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <Input label={tr(\"fields.Title\", \"Title\")} value={form.title} onChange={(e) => set(\"title\", e.target.value)} />\n <Input label={tr(\"fields.Date\", \"Date\")} type=\"date\" value={form.proposal_date} onChange={(e) => set(\"proposal_date\", e.target.value)} />\n <LinkField label={tr(\"fields.Customer\", \"Customer\")} value={form.customer} onChange={(v) => set(\"customer\", v)} linkDoctype=\"customer\" readOnly={false} />\n <LinkField label={tr(\"fields.Company\", \"Company\")} value={form.company} onChange={(v) => set(\"company\", v)} linkDoctype=\"company\" readOnly={false} />\n <Input label={tr(\"fields.Partner\", \"Account Manager\")} value={form.partner_name} onChange={(e) => set(\"partner_name\", e.target.value)} />\n <Input label={tr(\"fields.Partner Email\", \"Account Manager Email\")} value={form.partner_email} onChange={(e) => set(\"partner_email\", e.target.value)} />\n </div>\n <div>\n <div className=\"mb-1.5 flex items-center justify-between\">\n <label className=\"block text-sm font-medium text-fg\">{tr(\"proposal.coverLetter\", \"Cover letter\")}</label>\n <button type=\"button\" onClick={loadCoverDefault} className=\"text-xs text-brand hover:underline\">\n {tr(\"proposal.loadTemplate\", \"Load from template\")}\n </button>\n </div>\n <textarea\n value={form.cover_letter}\n onChange={(e) => set(\"cover_letter\", e.target.value)}\n rows={5}\n className=\"block w-full rounded-lg bg-surface px-3 py-2 text-sm text-fg ring-1 ring-line focus:outline-none focus:ring-2 focus:ring-brand/30\"\n />\n </div>\n </Card>\n\n {/* Positions */}\n <Card className=\"space-y-4 p-5\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"font-semibold text-fg\">{tr(\"proposal.offers\", \"Offers\")}</h2>\n <Button size=\"sm\" variant=\"secondary\" onClick={addRow}>\n {tr(\"proposal.addOffer\", \"Add offer\")}\n </Button>\n </div>\n {rows.map((row, i) => (\n <div key={i} className=\"rounded-lg p-3 ring-1 ring-line\">\n <div className=\"mb-2 flex items-center gap-2\">\n <span className=\"flex h-6 w-6 items-center justify-center rounded-full bg-brand/10 text-sm font-bold text-brand\">\n {LETTERS[i] ?? i + 1}\n </span>\n <div className=\"flex-1\">\n <LinkField label=\"\" value={row.quotation} onChange={(v) => updateRow(i, { quotation: v })} linkDoctype=\"quotation\" readOnly={false} />\n </div>\n <button type=\"button\" onClick={() => moveRow(i, -1)} disabled={i === 0} className=\"px-1 text-fg-muted disabled:opacity-30\">↑</button>\n <button type=\"button\" onClick={() => moveRow(i, 1)} disabled={i === rows.length - 1} className=\"px-1 text-fg-muted disabled:opacity-30\">↓</button>\n <button type=\"button\" onClick={() => removeRow(i)} className=\"px-1 text-red-500 hover:text-red-700\">✕</button>\n </div>\n <div className=\"grid grid-cols-1 gap-2 pl-8 sm:grid-cols-2\">\n <Input label={tr(\"proposal.positionTitle\", \"Position title\")} value={row.position_title} onChange={(e) => updateRow(i, { position_title: e.target.value })} placeholder={tr(\"proposal.positionTitleHint\", \"defaults to the offer's first item\")} />\n <label className=\"flex items-center gap-2 self-end pb-2 text-sm text-fg\">\n <input type=\"checkbox\" checked={!!row.is_recommended} onChange={(e) => updateRow(i, { is_recommended: e.target.checked ? 1 : 0 })} />\n {tr(\"proposal.recommended\", \"Mark as recommendation\")}\n </label>\n <div className=\"sm:col-span-2\">\n <Input label={tr(\"proposal.blurb\", \"Description\")} value={row.position_blurb} onChange={(e) => updateRow(i, { position_blurb: e.target.value })} placeholder={tr(\"proposal.blurbHint\", \"defaults to the offer's notes\")} />\n </div>\n </div>\n </div>\n ))}\n </Card>\n\n {/* Appendix */}\n <Card className=\"space-y-3 p-5\">\n <h2 className=\"font-semibold text-fg\">{tr(\"proposal.appendix\", \"Appendix PDF\")}</h2>\n {isNew ? (\n <p className=\"text-sm text-fg-muted\">{tr(\"proposal.saveFirst\", \"Save the proposal first to attach an appendix.\")}</p>\n ) : appendix ? (\n <div className=\"flex items-center gap-3 text-sm\">\n <span className=\"text-fg\">📎 {appendix}</span>\n <button type=\"button\" onClick={removeAppendix} disabled={appendixBusy} className=\"text-red-500 hover:underline\">\n {tr(\"common.remove\", \"Remove\")}\n </button>\n </div>\n ) : (\n <div>\n <input ref={fileRef} type=\"file\" accept=\"application/pdf\" onChange={onPickAppendix} className=\"hidden\" />\n <Button size=\"sm\" variant=\"secondary\" disabled={appendixBusy} onClick={() => fileRef.current?.click()}>\n {appendixBusy ? tr(\"common.uploading\", \"Uploading…\") : tr(\"proposal.uploadAppendix\", \"Upload appendix PDF\")}\n </Button>\n <p className=\"mt-1 text-xs text-fg-muted\">{tr(\"proposal.appendixHint\", \"Appended after the offers — e.g. a price overview.\")}</p>\n </div>\n )}\n </Card>\n </div>\n );\n}\n","import { useEffect, useMemo } from \"react\";\nimport { Link, useParams, useNavigate, useLocation } from \"react-router-dom\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useUrlState, useUrlPatch } from \"@/hooks/use-url-state\";\nimport {\n useReactTable,\n getCoreRowModel,\n flexRender,\n createColumnHelper,\n type ColumnDef,\n} from \"@tanstack/react-table\";\nimport { api } from \"@/api/client\";\nimport { setListContext } from \"@/lib/doc-list-context\";\nimport { Button } from \"@/components/ui/button\";\n\nconst TYPE_LABELS: Record<string, string> = {\n customer: \"Customer\",\n supplier: \"Supplier\",\n item: \"Item\",\n warehouse: \"Warehouse\",\n company: \"Company\",\n};\n\nconst PAGE_SIZE_OPTIONS = [\"25\", \"50\", \"100\", \"200\"];\n\nexport default function MasterListPage() {\n const { type } = useParams<{ type: string }>();\n const navigate = useNavigate();\n const location = useLocation();\n const label = TYPE_LABELS[type ?? \"\"] ?? type ?? \"\";\n const notice = (location.state as { notice?: string } | null)?.notice;\n\n // Stash the list URL so the detail page's DocPager can come \"back\" to this\n // exact page (Esc/u). Masters have no filter UI, so filters stays empty.\n useEffect(() => {\n if (type) setListContext(`master:${type}`, { filters: {}, search: location.search });\n }, [type, location.search]);\n\n const [pageSize] = useUrlState<number>(\"per_page\", 50);\n // URL page is 1-indexed; internal 0-indexed for offset math.\n const [urlPage] = useUrlState<number>(\"page\", 1);\n const page = urlPage - 1;\n const patchUrl = useUrlPatch();\n const setPage = (p: number) => patchUrl({ page: p === 0 ? null : p + 1 });\n const setPageSize = (n: number) => patchUrl({ per_page: n, page: null });\n\n const { data, isLoading } = useQuery({\n queryKey: [\"masters\", type, page, pageSize],\n queryFn: () => api.listMasters(type!, {\n include_disabled: 1,\n limit: pageSize,\n offset: page * pageSize,\n }),\n enabled: !!type,\n });\n\n const rows = data?.rows ?? [];\n const total = data?.total ?? 0;\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n const rangeStart = total === 0 ? 0 : page * pageSize + 1;\n const rangeEnd = Math.min(total, (page + 1) * pageSize);\n\n const columns = useMemo<ColumnDef<any, any>[]>(() => {\n if (!rows || rows.length === 0) return [];\n const helper = createColumnHelper<any>();\n const keys = Object.keys(rows[0]);\n\n return keys.map((key) =>\n helper.accessor(key, {\n header: key\n .split(\"_\")\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(\" \"),\n cell: (info) => {\n const val = info.getValue();\n if (key === \"name\") {\n const isDisabled = info.row.original.disabled === 1;\n return (\n <Link\n to={`/masters/${type}/${val}`}\n className={isDisabled ? \"font-medium text-fg-muted\" : \"font-medium text-brand transition-colors hover:text-brand/80\"}\n >\n {val}\n </Link>\n );\n }\n if (key === \"disabled\") {\n return val === 1 ? \"Disabled\" : \"Active\";\n }\n return val ?? \"-\";\n },\n }),\n );\n }, [rows, type]);\n\n const table = useReactTable({\n data: rows,\n columns,\n getCoreRowModel: getCoreRowModel(),\n });\n\n return (\n <div className=\"space-y-4\">\n {notice && (\n <div className=\"rounded-md bg-amber-50 px-4 py-3 text-sm text-amber-800\">\n {notice}\n </div>\n )}\n <div className=\"flex items-center justify-end\">\n <Link to={`/masters/${type}/new`}>\n <Button>New</Button>\n </Link>\n </div>\n\n {isLoading ? (\n <p className=\"text-fg-muted\">Loading...</p>\n ) : rows.length === 0 ? (\n <p className=\"py-8 text-center text-fg-muted\">No records found</p>\n ) : (\n <>\n <div className=\"overflow-x-auto rounded-xl bg-surface ring-1 ring-line shadow-card\">\n <table className=\"min-w-full divide-y divide-line text-sm\">\n <thead className=\"bg-surface-subtle\">\n {table.getHeaderGroups().map((headerGroup) => (\n <tr key={headerGroup.id}>\n {headerGroup.headers.map((header) => (\n <th\n key={header.id}\n className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-fg-muted\"\n >\n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n </th>\n ))}\n </tr>\n ))}\n </thead>\n <tbody className=\"divide-y divide-line\">\n {table.getRowModel().rows.map((row) => (\n <tr\n key={row.id}\n className={\n row.original.disabled === 1\n ? \"cursor-pointer bg-surface-subtle text-fg-muted transition-colors hover:bg-surface-subtle/80\"\n : \"cursor-pointer text-fg transition-colors hover:bg-surface-subtle\"\n }\n onClick={() =>\n navigate(`/masters/${type}/${row.original.name}`)\n }\n >\n {row.getVisibleCells().map((cell) => (\n <td key={cell.id} className=\"px-4 py-2.5\">\n {flexRender(\n cell.column.columnDef.cell,\n cell.getContext(),\n )}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n\n <div className=\"flex flex-wrap items-center justify-between gap-3 text-sm text-fg-muted\">\n <div>\n Showing <span className=\"font-medium text-fg\">{rangeStart}–{rangeEnd}</span>{\" \"}\n of <span className=\"font-medium text-fg\">{total}</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <label className=\"flex items-center gap-1.5\">\n <span className=\"text-xs text-fg-muted\">Per page</span>\n <select\n value={pageSize}\n onChange={(e) => setPageSize(Number(e.target.value))}\n className=\"h-8 rounded-md bg-surface px-2 text-sm text-fg ring-1 ring-line transition-all focus:outline-none focus:ring-2 focus:ring-brand/30\"\n >\n {PAGE_SIZE_OPTIONS.map((n) => (\n <option key={n} value={n}>{n}</option>\n ))}\n </select>\n </label>\n <button\n onClick={() => setPage(Math.max(0, page - 1))}\n disabled={page === 0}\n className=\"rounded-md bg-surface px-3 py-1 text-sm text-fg ring-1 ring-line transition-colors hover:bg-surface-subtle disabled:cursor-not-allowed disabled:opacity-40\"\n >\n Prev\n </button>\n <span className=\"text-xs\">\n Page <span className=\"font-medium text-fg\">{page + 1}</span> of{\" \"}\n <span className=\"font-medium text-fg\">{totalPages}</span>\n </span>\n <button\n onClick={() => setPage(Math.min(totalPages - 1, page + 1))}\n disabled={page >= totalPages - 1}\n className=\"rounded-md bg-surface px-3 py-1 text-sm text-fg ring-1 ring-line transition-colors hover:bg-surface-subtle disabled:cursor-not-allowed disabled:opacity-40\"\n >\n Next\n </button>\n </div>\n </div>\n </>\n )}\n </div>\n );\n}\n","import { useState, useEffect } from \"react\";\nimport { useParams, useNavigate } from \"react-router-dom\";\nimport { useTranslation } from \"react-i18next\";\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { api } from \"@/api/client\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\nimport { Button } from \"@/components/ui/button\";\nimport { useConfirm } from \"@/components/ui/dialog\";\nimport { DocPager } from \"@/components/document/doc-pager\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Select } from \"@/components/ui/select\";\nimport type { FieldDef } from \"@/lib/doctypes\";\n\n// ---------------------------------------------------------------------------\n// Field registry per master type\n// ---------------------------------------------------------------------------\n\nconst MASTER_FIELDS: Record<string, FieldDef[]> = {\n customer: [\n { name: \"name\", label: \"ID\", type: \"text\", required: true },\n { name: \"customer_name\", label: \"Customer Name\", type: \"text\", required: true },\n { name: \"customer_group\", label: \"Customer Group\", type: \"select\", options: [\"Individual\", \"Commercial\", \"Government\", \"Non-Profit\", \"Premium\"] },\n { name: \"territory\", label: \"Territory\", type: \"text\" },\n { name: \"default_currency\", label: \"Currency\", type: \"select\", options: [\"\", \"USD\", \"EUR\", \"GBP\", \"CHF\", \"JPY\", \"CAD\", \"AUD\", \"CNY\", \"INR\"] },\n { name: \"credit_limit\", label: \"Credit Limit\", type: \"currency\" },\n { name: \"email\", label: \"Email\", type: \"text\" },\n { name: \"phone\", label: \"Phone\", type: \"text\" },\n { name: \"address\", label: \"Address\", type: \"textarea\" },\n { name: \"city\", label: \"City\", type: \"text\" },\n { name: \"zip_code\", label: \"Zip Code\", type: \"text\" },\n { name: \"country\", label: \"Country\", type: \"text\" },\n { name: \"tax_id\", label: \"Tax ID\", type: \"text\" },\n { name: \"contact_person\", label: \"Contact Person\", type: \"text\" },\n { name: \"contact_email\", label: \"Contact Email\", type: \"text\" },\n { name: \"contact_phone\", label: \"Contact Phone\", type: \"text\" },\n ],\n supplier: [\n { name: \"name\", label: \"ID\", type: \"text\", required: true },\n { name: \"supplier_name\", label: \"Supplier Name\", type: \"text\", required: true },\n { name: \"supplier_group\", label: \"Supplier Group\", type: \"select\", options: [\"Local\", \"Distributor\", \"Services\", \"Raw Materials\"] },\n { name: \"default_currency\", label: \"Currency\", type: \"select\", options: [\"\", \"USD\", \"EUR\", \"GBP\", \"CHF\", \"JPY\", \"CAD\", \"AUD\", \"CNY\", \"INR\"] },\n { name: \"email\", label: \"Email\", type: \"text\" },\n { name: \"phone\", label: \"Phone\", type: \"text\" },\n { name: \"address\", label: \"Address\", type: \"textarea\" },\n { name: \"city\", label: \"City\", type: \"text\" },\n { name: \"zip_code\", label: \"Zip Code\", type: \"text\" },\n { name: \"country\", label: \"Country\", type: \"text\" },\n { name: \"tax_id\", label: \"Tax ID\", type: \"text\" },\n ],\n item: [\n { name: \"name\", label: \"Item Code\", type: \"text\", required: true },\n { name: \"item_name\", label: \"Item Name\", type: \"text\", required: true },\n { name: \"item_group\", label: \"Item Group\", type: \"select\", options: [\"Products\", \"Raw Material\", \"Services\", \"Consumable\"] },\n { name: \"stock_uom\", label: \"Stock UOM\", type: \"select\", options: [\"Nos\", \"Kg\", \"Ltr\", \"Mtr\", \"Box\", \"Set\"] },\n { name: \"standard_rate\", label: \"Standard Rate\", type: \"currency\" },\n { name: \"description\", label: \"Description\", type: \"textarea\" },\n ],\n warehouse: [\n { name: \"warehouse_name\", label: \"Warehouse Name\", type: \"text\", required: true },\n { name: \"warehouse_type\", label: \"Type\", type: \"select\", options: [\"Stores\", \"Manufacturing\", \"Transit\", \"Rejected\"] },\n { name: \"company\", label: \"Company\", type: \"text\" },\n { name: \"address\", label: \"Address\", type: \"textarea\" },\n { name: \"city\", label: \"City\", type: \"text\" },\n { name: \"zip_code\", label: \"Zip Code\", type: \"text\" },\n { name: \"country\", label: \"Country\", type: \"text\" },\n ],\n company: [\n { name: \"company_name\", label: \"Company Name\", type: \"text\", required: true },\n // No static default — a new record's currency is pre-filled with the\n // company base currency by the effect in the form component below.\n { name: \"default_currency\", label: \"Currency\", type: \"text\" },\n { name: \"email\", label: \"Email\", type: \"text\" },\n { name: \"phone\", label: \"Phone\", type: \"text\" },\n { name: \"address\", label: \"Address\", type: \"textarea\" },\n { name: \"city\", label: \"City\", type: \"text\" },\n { name: \"zip_code\", label: \"Zip Code\", type: \"text\" },\n { name: \"country\", label: \"Country\", type: \"text\" },\n { name: \"tax_id\", label: \"Tax ID\", type: \"text\" },\n { name: \"iban\", label: \"IBAN\", type: \"text\" },\n ],\n};\n\nconst TYPE_LABELS: Record<string, string> = {\n customer: \"Customer\",\n supplier: \"Supplier\",\n item: \"Item\",\n warehouse: \"Warehouse\",\n company: \"Company\",\n};\n\nconst AUTO_NAME_TYPES = new Set([\"customer\", \"supplier\", \"item\", \"warehouse\"]);\n\n// ---------------------------------------------------------------------------\n// MasterFormPage\n// ---------------------------------------------------------------------------\n\nexport default function MasterFormPage() {\n const { type, name } = useParams<{ type: string; name: string }>();\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n const { t } = useTranslation();\n const isNew = !name || name === \"new\";\n const label = TYPE_LABELS[type ?? \"\"] ?? type ?? \"\";\n const labelTr = t(`masters.${type}.one`, { defaultValue: label });\n const fields = MASTER_FIELDS[type ?? \"\"] ?? [];\n const fieldLabel = (f: FieldDef) => t(`fields.${f.label}`, { defaultValue: f.label });\n\n const [formData, setFormData] = useState<Record<string, any>>({});\n\n // Fetch existing record\n const { data: existing, isLoading } = useQuery({\n queryKey: [\"master\", type, name],\n queryFn: () => api.getMaster(type!, name!),\n enabled: !!type && !!name && !isNew,\n });\n\n useEffect(() => {\n if (isNew) {\n const defaults: Record<string, any> = {};\n fields.forEach((f) => {\n defaults[f.name] = f.default ?? \"\";\n });\n setFormData(defaults);\n } else if (existing) {\n setFormData(existing);\n }\n }, [isNew, existing, fields]);\n\n // New masters with a default_currency field are pre-filled with the COMPANY\n // base currency (a hardcoded \"USD\" default gave new customers USD in a CHF\n // shop). Separate effect so the base-currency query resolving doesn't wipe\n // other fields the user already typed; it only fills an untouched currency.\n const companyCurrency = useBaseCurrency();\n useEffect(() => {\n if (!isNew || !companyCurrency) return;\n if (!fields.some((f) => f.name === \"default_currency\")) return;\n setFormData((prev: Record<string, any>) => {\n const current = prev.default_currency;\n if (current && current !== \"USD\") return prev; // user already chose one\n if (current === companyCurrency) return prev;\n return { ...prev, default_currency: companyCurrency };\n });\n }, [isNew, fields, companyCurrency]);\n\n // Mutations\n const createMut = useMutation({\n mutationFn: (data: any) => api.createMaster(type!, data),\n onSuccess: (result) => {\n queryClient.invalidateQueries({ queryKey: [\"masters\", type] });\n navigate(`/masters/${type}/${result.name}`, { replace: true });\n },\n });\n\n const updateMut = useMutation({\n mutationFn: (data: any) => api.updateMaster(type!, name!, data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [\"master\", type, name] });\n queryClient.invalidateQueries({ queryKey: [\"masters\", type] });\n },\n });\n\n const deleteMut = useMutation({\n mutationFn: () => api.deleteMaster(type!, name!),\n onSuccess: (result) => {\n queryClient.invalidateQueries({ queryKey: [\"masters\", type] });\n if (result?.status === \"disabled\") {\n navigate(`/masters/${type}`, {\n replace: true,\n state: {\n notice: t(\"masterForm.disabledOnDelete\", {\n label: labelTr,\n name,\n reason: result.reason ?? \"other records\",\n }),\n },\n });\n return;\n }\n navigate(`/masters/${type}`, { replace: true });\n },\n });\n\n const handleSave = () => {\n if (missingRequiredFields.length > 0) return;\n const payload =\n type === \"company\" && !formData.name\n ? { ...formData, name: formData.company_name }\n : formData;\n if (isNew) {\n createMut.mutate(payload);\n } else {\n updateMut.mutate(payload);\n }\n };\n\n const confirm = useConfirm();\n const handleDelete = async () => {\n if (await confirm({\n title: t(\"masterForm.deleteConfirm\", { label: labelTr }),\n confirmLabel: t(\"common.delete\", { defaultValue: \"Delete\" }),\n danger: true,\n })) {\n deleteMut.mutate();\n }\n };\n\n const setField = (fieldName: string, value: any) => {\n setFormData((prev) => ({ ...prev, [fieldName]: value }));\n };\n\n if (!isNew && isLoading) {\n return <p className=\"text-fg-muted\">{t(\"common.loading\")}</p>;\n }\n\n const saving = createMut.isPending || updateMut.isPending;\n const missingRequiredFields = fields.filter((field) => {\n if (!field.required || field.readOnly) return false;\n if (isNew && field.name === \"name\" && AUTO_NAME_TYPES.has(type ?? \"\")) return false;\n const value = formData[field.name];\n return value === undefined || value === null || String(value).trim() === \"\";\n });\n\n return (\n <div className=\"space-y-6\">\n {/* Header: prev/next through the master list on the left, actions right */}\n <div className=\"flex items-center justify-between\">\n {!isNew ? (\n <DocPager kind=\"master\" slug={type!} name={name!} onSave={handleSave} />\n ) : (\n <div />\n )}\n <div className=\"flex gap-2\">\n <Button onClick={handleSave} disabled={saving || missingRequiredFields.length > 0}>\n {saving ? t(\"common.saving\") : t(\"common.save\")}\n </Button>\n {!isNew && (\n <Button\n variant=\"danger\"\n onClick={handleDelete}\n disabled={deleteMut.isPending}\n >\n {t(\"common.delete\")}\n </Button>\n )}\n </div>\n </div>\n\n {/* Error display */}\n {(createMut.error || updateMut.error || deleteMut.error) && (\n <div className=\"rounded-lg bg-rose-50 p-4 text-sm text-rose-700 ring-1 ring-rose-200\">\n {(createMut.error ?? updateMut.error ?? deleteMut.error)?.message ??\n t(\"common.errorOccurred\")}\n </div>\n )}\n {missingRequiredFields.length > 0 && (\n <div className=\"rounded-lg bg-amber-50 p-4 text-sm text-amber-800 ring-1 ring-amber-200\">\n {t(\"masterForm.required\", { fields: missingRequiredFields.map(fieldLabel).join(\", \") })}\n </div>\n )}\n {formData.disabled === 1 && (\n <div className=\"rounded-lg bg-amber-50 p-4 text-sm text-amber-800 ring-1 ring-amber-200\">\n {t(\"masterForm.disabledNotice\", { label: labelTr })}\n </div>\n )}\n\n {/* Form fields */}\n <Card>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n {fields.map((field) => {\n // Name field is read-only on edit\n const isNameField = field.name === \"name\" && !isNew;\n const isReadOnly = isNameField || field.readOnly;\n const isRequired = field.required && !(isNew && field.name === \"name\" && AUTO_NAME_TYPES.has(type ?? \"\"));\n\n if (field.type === \"select\" && field.options) {\n // A value saved through the API/chat can lie outside the hardcoded\n // option list (e.g. stock_uom \"Stück\") — a controlled <select> would\n // then silently render the \"Select...\" placeholder as if the field\n // were unset. Surface the stored value as an extra option so the GUI\n // shows what the backend actually holds.\n const current = formData[field.name];\n const options =\n typeof current === \"string\" && current !== \"\" && !field.options.includes(current)\n ? [...field.options, current]\n : field.options;\n return (\n <div key={field.name}>\n <Select\n label={fieldLabel(field)}\n options={options}\n value={formData[field.name] ?? \"\"}\n required={isRequired}\n disabled={isReadOnly}\n onChange={(e) => setField(field.name, e.target.value)}\n />\n </div>\n );\n }\n\n if (field.type === \"textarea\") {\n return (\n <div key={field.name} className=\"sm:col-span-2\">\n <label className=\"mb-1.5 block text-sm font-medium text-fg\">\n {fieldLabel(field)}\n </label>\n <textarea\n className=\"block w-full rounded-lg bg-surface px-3 py-2 text-sm text-fg ring-1 ring-line transition-all placeholder:text-fg-muted/70 focus:outline-none focus:ring-2 focus:ring-brand/30 disabled:bg-surface-subtle disabled:text-fg-muted\"\n rows={3}\n value={formData[field.name] ?? \"\"}\n required={isRequired}\n readOnly={isReadOnly}\n disabled={isReadOnly}\n onChange={(e) => setField(field.name, e.target.value)}\n />\n </div>\n );\n }\n\n const inputType =\n field.type === \"number\" || field.type === \"currency\"\n ? \"number\"\n : field.type === \"date\"\n ? \"date\"\n : \"text\";\n\n return (\n <Input\n key={field.name}\n label={fieldLabel(field)}\n type={inputType}\n step={field.type === \"currency\" ? \"0.01\" : undefined}\n required={isRequired}\n readOnly={isReadOnly}\n disabled={isReadOnly}\n value={formData[field.name] ?? \"\"}\n onChange={(e) =>\n setField(\n field.name,\n inputType === \"number\"\n ? parseFloat(e.target.value) || 0\n : e.target.value,\n )\n }\n />\n );\n })}\n </div>\n </Card>\n </div>\n );\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { api } from \"@/api/client\";\n\nexport function useTrialBalance(params?: Record<string, string>) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"trial-balance\", params],\n queryFn: () => api.trialBalance(params),\n });\n return { data, isLoading, error, refetch };\n}\n\nexport function useChartOfAccounts(params?: Record<string, string>) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"chart-of-accounts\", params],\n queryFn: () => api.chartOfAccounts(params),\n });\n return { data, isLoading, error, refetch };\n}\n\nexport function useGeneralLedger(params?: Record<string, string>) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"general-ledger\", params],\n queryFn: () => api.generalLedger(params),\n });\n return { data, isLoading, error, refetch };\n}\n\nexport function useStockBalance(params?: Record<string, string>) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"stock-balance\", params],\n queryFn: () => api.stockBalance(params),\n });\n return { data, isLoading, error, refetch };\n}\n\nexport function useProfitAndLoss(params?: Record<string, string>) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"profit-and-loss\", params],\n queryFn: () => api.profitAndLoss(params),\n });\n return { data, isLoading, error, refetch };\n}\n\nexport function useBalanceSheet(params?: Record<string, string>) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"balance-sheet\", params],\n queryFn: () => api.balanceSheet(params),\n });\n return { data, isLoading, error, refetch };\n}\n\nexport function useArAging(params?: Record<string, string>) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"ar-aging\", params],\n queryFn: () => api.arAging(params),\n });\n return { data, isLoading, error, refetch };\n}\n\nexport function useApAging(params?: Record<string, string>) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"ap-aging\", params],\n queryFn: () => api.apAging(params),\n });\n return { data, isLoading, error, refetch };\n}\n\nexport function useAnalyticsMetrics() {\n const { data, isLoading } = useQuery({\n queryKey: [\"analytics-metrics\"],\n queryFn: () => api.analyticsMetrics(),\n staleTime: 60_000,\n });\n return { data, isLoading };\n}\n\nexport function useAnalytics(params?: Record<string, string>) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"analytics\", params],\n queryFn: () => api.analytics(params!),\n enabled: Boolean(params?.metric && params?.group_by),\n });\n return { data, isLoading, error, refetch };\n}\n\nexport function useRuntimeDatasets() {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"runtime-datasets\"],\n queryFn: () => api.runtimeDatasets(),\n staleTime: 60_000,\n });\n return { data, isLoading, error, refetch };\n}\n","import { useState, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useTrialBalance } from \"@/hooks/use-report\";\nimport { useUrlState, useUrlPatch } from \"@/hooks/use-url-state\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { LinkField } from \"@/components/document/link-field\";\nimport { DateRangePresets } from \"@/components/ui/date-range-presets\";\nimport { formatCurrency as fmtCurrency } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\n\nexport default function TrialBalancePage() {\n const { t } = useTranslation();\n const [urlCompany] = useUrlState<string>(\"company\", \"\");\n const [urlFromDate] = useUrlState<string>(\"from\", \"\");\n const [urlToDate] = useUrlState<string>(\"to\", \"\");\n const patchUrl = useUrlPatch();\n\n const [company, setCompany] = useState(urlCompany);\n const [fromDate, setFromDate] = useState(urlFromDate);\n const [toDate, setToDate] = useState(urlToDate);\n const baseCurrency = useBaseCurrency(company);\n const formatCurrency = (v: number | null | undefined) => fmtCurrency(v, baseCurrency);\n\n const filters = useMemo(() => {\n const f: Record<string, string> = {};\n if (urlCompany) f.company = urlCompany;\n if (urlFromDate) f.from_date = urlFromDate;\n if (urlToDate) f.to_date = urlToDate;\n return f;\n }, [urlCompany, urlFromDate, urlToDate]);\n\n const { data, isLoading, refetch } = useTrialBalance(filters);\n\n const handleApply = () => {\n patchUrl({\n company: company || null,\n from: fromDate || null,\n to: toDate || null,\n });\n refetch();\n };\n\n const isBalanced = data ? data.difference === 0 : false;\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <LinkField\n label={t(\"fields.Company\", { defaultValue: \"Company\" })}\n value={company}\n onChange={setCompany}\n linkDoctype=\"company\"\n readOnly={false}\n />\n <Input\n label={t(\"fields.From Date\", { defaultValue: \"From Date\" })}\n type=\"date\"\n value={fromDate}\n onChange={(e) => setFromDate(e.target.value)}\n />\n <Input\n label={t(\"fields.To Date\", { defaultValue: \"To Date\" })}\n type=\"date\"\n value={toDate}\n onChange={(e) => setToDate(e.target.value)}\n />\n <Button onClick={handleApply}>{t(\"common.apply\")}</Button>\n </div>\n <DateRangePresets onSelect={(from, to) => {\n setFromDate(from);\n setToDate(to);\n patchUrl({ from, to });\n }} />\n\n {isLoading ? (\n <p className=\"text-fg-muted\">{t(\"common.loading\")}</p>\n ) : !data || !data.rows || data.rows.length === 0 ? (\n <p className=\"py-8 text-center text-fg-muted\">{t(\"reports.noData\")}</p>\n ) : (\n <Card>\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full divide-y divide-line text-sm\">\n <thead className=\"bg-surface-subtle\">\n <tr>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-fg-muted\">\n {t(\"fields.Account\", { defaultValue: \"Account\" })}\n </th>\n <th className=\"px-4 py-3 text-right text-xs font-medium uppercase tracking-wide text-fg-muted\">\n {t(\"fields.Debit\", { defaultValue: \"Debit\" })}\n </th>\n <th className=\"px-4 py-3 text-right text-xs font-medium uppercase tracking-wide text-fg-muted\">\n {t(\"fields.Credit\", { defaultValue: \"Credit\" })}\n </th>\n <th className=\"px-4 py-3 text-right text-xs font-medium uppercase tracking-wide text-fg-muted\">\n {t(\"fields.Balance\", { defaultValue: \"Balance\" })}\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-line\">\n {data.rows.map((row: any, idx: number) => (\n <tr key={idx} className=\"transition-colors hover:bg-surface-subtle\">\n <td className=\"px-4 py-2 text-fg\">{row.account}</td>\n <td className=\"px-4 py-2 text-right tabular-nums text-fg\">\n {formatCurrency(row.debit)}\n </td>\n <td className=\"px-4 py-2 text-right tabular-nums text-fg\">\n {formatCurrency(row.credit)}\n </td>\n <td className=\"px-4 py-2 text-right font-medium tabular-nums text-fg\">\n {formatCurrency(row.balance)}\n </td>\n </tr>\n ))}\n </tbody>\n <tfoot className=\"border-t border-line bg-surface-subtle font-semibold\">\n <tr>\n <td className=\"px-4 py-3 text-fg\">{t(\"common.total\")}</td>\n <td className=\"px-4 py-3 text-right tabular-nums text-fg\">\n {formatCurrency(data.total_debit)}\n </td>\n <td className=\"px-4 py-3 text-right tabular-nums text-fg\">\n {formatCurrency(data.total_credit)}\n </td>\n <td className=\"px-4 py-3 text-right tabular-nums text-fg\">\n {formatCurrency(data.difference)}\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n\n <div className=\"mt-4 text-center\">\n {isBalanced ? (\n <span className=\"inline-flex items-center gap-1.5 rounded-full bg-emerald-50 px-4 py-1.5 text-sm font-semibold text-emerald-700 ring-1 ring-emerald-200\">\n <span className=\"h-1.5 w-1.5 rounded-full bg-emerald-500\" />\n {t(\"reports.balanced\")}\n </span>\n ) : (\n <span className=\"inline-flex items-center gap-1.5 rounded-full bg-rose-50 px-4 py-1.5 text-sm font-semibold text-rose-700 ring-1 ring-rose-200\">\n <span className=\"h-1.5 w-1.5 rounded-full bg-rose-500\" />\n {t(\"reports.imbalanced\")}\n </span>\n )}\n </div>\n </Card>\n )}\n </div>\n );\n}\n","import { useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Link } from \"react-router-dom\";\nimport { ChevronDown, ChevronRight } from \"lucide-react\";\nimport { useChartOfAccounts } from \"@/hooks/use-report\";\nimport { Card } from \"@/components/ui/card\";\nimport { Select } from \"@/components/ui/select\";\nimport { formatCurrency as fmtCurrency } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\n\n// The account tree grouped by root type, with period balances. Each leaf links\n// to the General Ledger pre-filtered to that account + period — the GL page is\n// URL-backed (?account=&from=&to=), so the drill-down needs no extra plumbing.\n\ninterface CoaRow {\n name: string;\n account_name: string | null;\n parent_account: string | null;\n root_type: string | null;\n account_type: string | null;\n is_group: boolean;\n disabled: boolean;\n balance: number;\n has_entries: boolean;\n}\n\nconst ROOT_ORDER = [\"Asset\", \"Liability\", \"Equity\", \"Income\", \"Expense\"];\n\nexport default function ChartOfAccountsPage() {\n const { t } = useTranslation();\n const currentYear = new Date().getFullYear();\n const [year, setYear] = useState(String(currentYear));\n const [collapsed, setCollapsed] = useState<Set<string>>(new Set());\n\n const yearOptions = useMemo(() => {\n const opts: { value: string; label: string }[] = [];\n for (let y = currentYear; y >= currentYear - 6; y--) {\n opts.push({ value: String(y), label: String(y) });\n }\n opts.push({ value: \"all\", label: t(\"coa.allTime\", { defaultValue: \"All time\" }) });\n return opts;\n }, [currentYear, t]);\n\n const filters = useMemo(() => {\n const f: Record<string, string> = {};\n if (year !== \"all\") {\n f.from_date = `${year}-01-01`;\n f.to_date = `${year}-12-31`;\n }\n return f;\n }, [year]);\n\n const { data, isLoading } = useChartOfAccounts(filters);\n const baseCurrency = useBaseCurrency(\"\");\n const fmt = (v: number) => fmtCurrency(v, baseCurrency);\n\n const accounts: CoaRow[] = data?.accounts ?? [];\n\n // parent -> children, and the roots of each root_type section. An account\n // whose parent is missing from the result set is treated as a root.\n const { childrenOf, rootsByType } = useMemo(() => {\n const byName = new Map(accounts.map((a) => [a.name, a]));\n const childrenOf = new Map<string, CoaRow[]>();\n const rootsByType = new Map<string, CoaRow[]>();\n for (const acc of accounts) {\n if (acc.parent_account && byName.has(acc.parent_account)) {\n const list = childrenOf.get(acc.parent_account) ?? [];\n list.push(acc);\n childrenOf.set(acc.parent_account, list);\n } else {\n const key = acc.root_type ?? \"Other\";\n const list = rootsByType.get(key) ?? [];\n list.push(acc);\n rootsByType.set(key, list);\n }\n }\n return { childrenOf, rootsByType };\n }, [accounts]);\n\n const toggle = (name: string) => {\n setCollapsed((prev) => {\n const next = new Set(prev);\n if (next.has(name)) next.delete(name);\n else next.add(name);\n return next;\n });\n };\n\n const glLink = (name: string) => {\n const params = new URLSearchParams({ account: name });\n if (year !== \"all\") {\n params.set(\"from\", `${year}-01-01`);\n params.set(\"to\", `${year}-12-31`);\n }\n return `/reports/general-ledger?${params.toString()}`;\n };\n\n const renderRow = (acc: CoaRow, depth: number): React.ReactNode => {\n const kids = childrenOf.get(acc.name) ?? [];\n const isCollapsed = collapsed.has(acc.name);\n const dim = !acc.has_entries || acc.disabled;\n return (\n <div key={acc.name}>\n <div\n className={`flex items-center gap-2 rounded px-2 py-1.5 text-sm hover:bg-surface-subtle ${dim ? \"text-fg-muted\" : \"text-fg\"}`}\n style={{ paddingLeft: `${8 + depth * 20}px` }}\n >\n {kids.length > 0 ? (\n <button\n type=\"button\"\n onClick={() => toggle(acc.name)}\n className=\"shrink-0 text-fg-muted transition-colors hover:text-fg\"\n >\n {isCollapsed ? <ChevronRight className=\"h-3.5 w-3.5\" /> : <ChevronDown className=\"h-3.5 w-3.5\" />}\n </button>\n ) : (\n <span className=\"w-3.5 shrink-0\" />\n )}\n <span className={`min-w-0 flex-1 truncate ${acc.is_group ? \"font-medium\" : \"\"}`}>\n {acc.is_group ? (\n <>{acc.account_name || acc.name}</>\n ) : (\n <Link to={glLink(acc.name)} className=\"hover:text-brand hover:underline\">\n <span className=\"font-mono text-xs text-fg-muted\">{acc.name}</span>{\" \"}\n {acc.account_name || acc.name}\n </Link>\n )}\n {acc.disabled && (\n <span className=\"ml-2 text-xs text-fg-muted\">\n {t(\"coa.disabled\", { defaultValue: \"disabled\" })}\n </span>\n )}\n </span>\n {acc.account_type && (\n <span className=\"hidden shrink-0 text-xs text-fg-muted sm:inline\">{acc.account_type}</span>\n )}\n <span className=\"w-32 shrink-0 text-right font-mono text-sm tabular-nums\">\n {acc.has_entries || acc.is_group ? fmt(acc.balance) : \"—\"}\n </span>\n </div>\n {!isCollapsed && kids.map((kid) => renderRow(kid, depth + 1))}\n </div>\n );\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <div className=\"w-40\">\n <Select\n label={t(\"coa.period\", { defaultValue: \"Period\" })}\n options={yearOptions}\n value={year}\n onChange={(e) => setYear(e.target.value)}\n />\n </div>\n <p className=\"pb-2 text-xs text-fg-muted\">\n {t(\"coa.semantics\", {\n defaultValue:\n \"Balance-sheet accounts: closing balance at period end. P&L accounts: movement within the period. Click an account for its ledger.\",\n })}\n </p>\n </div>\n\n {isLoading && (\n <Card>\n <p className=\"text-sm text-fg-muted\">{t(\"common.loading\", { defaultValue: \"Loading…\" })}</p>\n </Card>\n )}\n\n {!isLoading && accounts.length === 0 && (\n <Card>\n <p className=\"text-sm text-fg-muted\">\n {t(\"coa.empty\", { defaultValue: \"No accounts found. Complete the company setup first.\" })}\n </p>\n </Card>\n )}\n\n {!isLoading &&\n ROOT_ORDER.filter((rt) => (rootsByType.get(rt) ?? []).length > 0).map((rootType) => (\n <Card key={rootType}>\n <h3 className=\"mb-2 px-2 text-xs font-semibold uppercase tracking-wider text-fg-muted\">\n {t(`coa.rootType.${rootType}`, { defaultValue: rootType })}\n </h3>\n <div>{(rootsByType.get(rootType) ?? []).map((acc) => renderRow(acc, 0))}</div>\n </Card>\n ))}\n </div>\n );\n}\n","import { useState, useMemo } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { useTranslation } from \"react-i18next\";\nimport { useGeneralLedger } from \"@/hooks/use-report\";\nimport { useUrlState, useUrlPatch } from \"@/hooks/use-url-state\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { LinkField } from \"@/components/document/link-field\";\nimport { DateRangePresets } from \"@/components/ui/date-range-presets\";\nimport { formatCurrency as fmtCurrency, formatDate } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\n\n/** Convert a voucher type like \"Sales Invoice\" to a URL slug \"sales-invoice\". */\nfunction toSlug(voucherType: string): string {\n return voucherType.toLowerCase().replace(/\\s+/g, \"-\");\n}\n\nconst PAGE_SIZE_OPTIONS = [\"25\", \"50\", \"100\", \"200\"];\n\nexport default function GeneralLedgerPage() {\n const { t } = useTranslation();\n // URL-backed filter and pagination state. Param names match the backend\n // where it's natural (account, party) and use human-friendly short forms\n // for pagination and dates (page, per_page, from, to).\n const [urlAccount] = useUrlState<string>(\"account\", \"\");\n const [urlParty] = useUrlState<string>(\"party\", \"\");\n const [urlFromDate] = useUrlState<string>(\"from\", \"\");\n const [urlToDate] = useUrlState<string>(\"to\", \"\");\n const [pageSize] = useUrlState<number>(\"per_page\", 50);\n const [urlPage] = useUrlState<number>(\"page\", 1);\n const page = urlPage - 1;\n const patchUrl = useUrlPatch();\n const setPage = (p: number) => patchUrl({ page: p === 0 ? null : p + 1 });\n const setPageSize = (n: number) => patchUrl({ per_page: n, page: null });\n\n // The input fields let the user type/pick without firing the query on\n // every keystroke — they only flush on Apply / preset click. Seed from the\n // URL so a cold open with filters pre-populates the inputs too.\n const [account, setAccount] = useState(urlAccount);\n const [party, setParty] = useState(urlParty);\n const [fromDate, setFromDate] = useState(urlFromDate);\n const [toDate, setToDate] = useState(urlToDate);\n const baseCurrency = useBaseCurrency();\n const formatCurrency = (v: number | null | undefined) => fmtCurrency(v, baseCurrency);\n\n const filters = useMemo(() => {\n const f: Record<string, string> = {};\n if (urlAccount) f.account = urlAccount;\n if (urlParty) f.party = urlParty;\n if (urlFromDate) f.from_date = urlFromDate;\n if (urlToDate) f.to_date = urlToDate;\n f.limit = String(pageSize);\n f.offset = String(page * pageSize);\n return f;\n }, [urlAccount, urlParty, urlFromDate, urlToDate, pageSize, page]);\n\n const { data, isLoading, refetch } = useGeneralLedger(filters);\n\n const rows = data?.rows ?? [];\n const total = data?.total ?? 0;\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n const rangeStart = total === 0 ? 0 : page * pageSize + 1;\n const rangeEnd = Math.min(total, (page + 1) * pageSize);\n\n const handleApply = () => {\n patchUrl({\n account: account || null,\n party: party || null,\n from: fromDate || null,\n to: toDate || null,\n page: null,\n });\n refetch();\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <LinkField\n label={t(\"fields.Account\", { defaultValue: \"Account\" })}\n value={account}\n onChange={setAccount}\n linkDoctype=\"account\"\n readOnly={false}\n />\n <LinkField\n label={t(\"fields.Party\", { defaultValue: \"Party\" })}\n value={party}\n onChange={setParty}\n linkDoctype=\"customer\"\n readOnly={false}\n />\n <Input\n label={t(\"fields.From Date\", { defaultValue: \"From Date\" })}\n type=\"date\"\n value={fromDate}\n onChange={(e) => setFromDate(e.target.value)}\n />\n <Input\n label={t(\"fields.To Date\", { defaultValue: \"To Date\" })}\n type=\"date\"\n value={toDate}\n onChange={(e) => setToDate(e.target.value)}\n />\n <Button onClick={handleApply}>{t(\"common.apply\")}</Button>\n </div>\n <DateRangePresets onSelect={(from, to) => {\n setFromDate(from);\n setToDate(to);\n patchUrl({ from, to, page: null });\n }} />\n\n {isLoading ? (\n <p className=\"text-gray-500\">{t(\"common.loading\")}</p>\n ) : rows.length === 0 ? (\n <p className=\"py-8 text-center text-gray-400\">{t(\"reports.noEntries\")}</p>\n ) : (\n <>\n <Card>\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">\n {t(\"fields.Date\", { defaultValue: \"Date\" })}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">\n {t(\"fields.Account\", { defaultValue: \"Account\" })}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">\n {t(\"fields.Party\", { defaultValue: \"Party\" })}\n </th>\n <th className=\"px-4 py-3 text-right font-medium text-gray-500\">\n {t(\"fields.Debit\", { defaultValue: \"Debit\" })}\n </th>\n <th className=\"px-4 py-3 text-right font-medium text-gray-500\">\n {t(\"fields.Credit\", { defaultValue: \"Credit\" })}\n </th>\n <th className=\"px-4 py-3 text-right font-medium text-gray-500\">\n {t(\"fields.Balance\", { defaultValue: \"Balance\" })}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">\n {t(\"fields.Voucher Type\", { defaultValue: \"Voucher Type\" })}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">\n {t(\"fields.Voucher No\", { defaultValue: \"Voucher No\" })}\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {rows.map((row: any, idx: number) => (\n <tr key={idx} className=\"hover:bg-gray-50\">\n <td className=\"px-4 py-2 text-gray-500\">\n {formatDate(row.posting_date ?? row.date)}\n </td>\n <td className=\"px-4 py-2 text-gray-900\">{row.account}</td>\n <td className=\"px-4 py-2 text-gray-700\">\n {row.party ?? \"-\"}\n </td>\n <td className=\"px-4 py-2 text-right\">\n {formatCurrency(row.debit)}\n </td>\n <td className=\"px-4 py-2 text-right\">\n {formatCurrency(row.credit)}\n </td>\n <td className=\"px-4 py-2 text-right font-medium\">\n {formatCurrency(row.balance)}\n </td>\n <td className=\"px-4 py-2 text-gray-700\">\n {row.voucher_type ?? \"-\"}\n </td>\n <td className=\"px-4 py-2\">\n {row.voucher_type && row.voucher_no ? (\n <Link\n to={`/app/${toSlug(row.voucher_type)}/${row.voucher_no}`}\n className=\"font-medium text-blue-600 hover:text-blue-800\"\n >\n {row.voucher_no}\n </Link>\n ) : (\n row.voucher_no ?? \"-\"\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </Card>\n\n <div className=\"flex flex-wrap items-center justify-between gap-3 text-sm text-gray-600\">\n <div>\n {t(\"common.showing\")} <span className=\"font-medium text-gray-900\">{rangeStart}–{rangeEnd}</span>{\" \"}\n {t(\"common.of\")} <span className=\"font-medium text-gray-900\">{total}</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <label className=\"flex items-center gap-1.5\">\n <span className=\"text-xs text-gray-500\">{t(\"common.perPage\")}</span>\n <select\n value={pageSize}\n onChange={(e) => setPageSize(Number(e.target.value))}\n className=\"rounded border border-gray-300 bg-white px-2 py-1 text-sm\"\n >\n {PAGE_SIZE_OPTIONS.map((n) => (\n <option key={n} value={n}>{n}</option>\n ))}\n </select>\n </label>\n <button\n onClick={() => setPage(Math.max(0, page - 1))}\n disabled={page === 0}\n className=\"rounded border border-gray-300 bg-white px-3 py-1 text-sm text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-40\"\n >\n {t(\"common.prev\")}\n </button>\n <span className=\"text-xs\">\n {t(\"common.page\")} <span className=\"font-medium text-gray-900\">{page + 1}</span> {t(\"common.of\")}{\" \"}\n <span className=\"font-medium text-gray-900\">{totalPages}</span>\n </span>\n <button\n onClick={() => setPage(Math.min(totalPages - 1, page + 1))}\n disabled={page >= totalPages - 1}\n className=\"rounded border border-gray-300 bg-white px-3 py-1 text-sm text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-40\"\n >\n {t(\"common.next\")}\n </button>\n </div>\n </div>\n </>\n )}\n </div>\n );\n}\n","import { useState, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useStockBalance } from \"@/hooks/use-report\";\nimport { useUrlState, useUrlPatch } from \"@/hooks/use-url-state\";\nimport { Card } from \"@/components/ui/card\";\nimport { Button } from \"@/components/ui/button\";\nimport { LinkField } from \"@/components/document/link-field\";\nimport { formatCurrency as fmtCurrency, formatNumber } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\n\nexport default function StockBalancePage() {\n const { t } = useTranslation();\n const [urlItemCode] = useUrlState<string>(\"item_code\", \"\");\n const [urlWarehouse] = useUrlState<string>(\"warehouse\", \"\");\n const patchUrl = useUrlPatch();\n\n const [itemCode, setItemCode] = useState(urlItemCode);\n const [warehouse, setWarehouse] = useState(urlWarehouse);\n const baseCurrency = useBaseCurrency();\n const formatCurrency = (v: number | null | undefined) => fmtCurrency(v, baseCurrency);\n\n const filters = useMemo(() => {\n const f: Record<string, string> = {};\n if (urlItemCode) f.item_code = urlItemCode;\n if (urlWarehouse) f.warehouse = urlWarehouse;\n return f;\n }, [urlItemCode, urlWarehouse]);\n\n const { data, isLoading, refetch } = useStockBalance(filters);\n\n const handleApply = () => {\n patchUrl({\n item_code: itemCode || null,\n warehouse: warehouse || null,\n });\n refetch();\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <LinkField\n label={t(\"fields.Item Code\", { defaultValue: \"Item Code\" })}\n value={itemCode}\n onChange={setItemCode}\n linkDoctype=\"item\"\n readOnly={false}\n />\n <LinkField\n label={t(\"fields.Warehouse\", { defaultValue: \"Warehouse\" })}\n value={warehouse}\n onChange={setWarehouse}\n linkDoctype=\"warehouse\"\n readOnly={false}\n />\n <Button onClick={handleApply}>{t(\"common.apply\")}</Button>\n </div>\n\n {isLoading ? (\n <p className=\"text-gray-500\">{t(\"common.loading\")}</p>\n ) : !data || !data.rows || data.rows.length === 0 ? (\n <p className=\"py-8 text-center text-gray-400\">{t(\"reports.noStockData\")}</p>\n ) : (\n <Card>\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">\n {t(\"fields.Item Code\", { defaultValue: \"Item Code\" })}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">\n {t(\"fields.Item Name\", { defaultValue: \"Item Name\" })}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">\n {t(\"fields.Warehouse\", { defaultValue: \"Warehouse\" })}\n </th>\n <th className=\"px-4 py-3 text-right font-medium text-gray-500\">\n {t(\"fields.Qty\", { defaultValue: \"Qty\" })}\n </th>\n <th className=\"px-4 py-3 text-right font-medium text-gray-500\">\n {t(\"fields.Valuation Rate\", { defaultValue: \"Valuation Rate\" })}\n </th>\n <th className=\"px-4 py-3 text-right font-medium text-gray-500\">\n {t(\"fields.Stock Value\", { defaultValue: \"Stock Value\" })}\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {data.rows.map((row: any, idx: number) => (\n <tr key={idx} className=\"hover:bg-gray-50\">\n <td className=\"px-4 py-2 font-medium text-gray-900\">\n {row.item_code}\n </td>\n <td className=\"px-4 py-2 text-gray-700\">\n {row.item_name}\n </td>\n <td className=\"px-4 py-2 text-gray-700\">\n {row.warehouse}\n </td>\n <td className=\"px-4 py-2 text-right\">\n {formatNumber(row.actual_qty)}\n </td>\n <td className=\"px-4 py-2 text-right\">\n {formatCurrency(row.valuation_rate)}\n </td>\n <td className=\"px-4 py-2 text-right font-medium\">\n {formatCurrency(row.stock_value)}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </Card>\n )}\n </div>\n );\n}\n","import { useState, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useProfitAndLoss } from \"@/hooks/use-report\";\nimport { useUrlState, useUrlPatch } from \"@/hooks/use-url-state\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { LinkField } from \"@/components/document/link-field\";\nimport { DateRangePresets } from \"@/components/ui/date-range-presets\";\nimport { formatCurrency as fmtCurrency } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\n\nexport default function ProfitLossPage() {\n const { t } = useTranslation();\n const [urlCompany] = useUrlState<string>(\"company\", \"\");\n const [urlFromDate] = useUrlState<string>(\"from\", \"\");\n const [urlToDate] = useUrlState<string>(\"to\", \"\");\n const patchUrl = useUrlPatch();\n\n const [company, setCompany] = useState(urlCompany);\n const baseCurrency = useBaseCurrency(company);\n const formatCurrency = (v: number | null | undefined) => fmtCurrency(v, baseCurrency);\n const [fromDate, setFromDate] = useState(urlFromDate);\n const [toDate, setToDate] = useState(urlToDate);\n\n const filters = useMemo(() => {\n const f: Record<string, string> = {};\n if (urlCompany) f.company = urlCompany;\n if (urlFromDate) f.from_date = urlFromDate;\n if (urlToDate) f.to_date = urlToDate;\n return f;\n }, [urlCompany, urlFromDate, urlToDate]);\n\n const { data, isLoading, refetch } = useProfitAndLoss(filters);\n\n const handleApply = () => {\n patchUrl({\n company: company || null,\n from: fromDate || null,\n to: toDate || null,\n });\n refetch();\n };\n\n const hasData = data && ((data.income && data.income.length > 0) || (data.expense && data.expense.length > 0));\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <LinkField label={t(\"fields.Company\", { defaultValue: \"Company\" })} value={company} onChange={setCompany} linkDoctype=\"company\" readOnly={false} />\n <Input label={t(\"fields.From Date\", { defaultValue: \"From Date\" })} type=\"date\" value={fromDate} onChange={(e) => setFromDate(e.target.value)} />\n <Input label={t(\"fields.To Date\", { defaultValue: \"To Date\" })} type=\"date\" value={toDate} onChange={(e) => setToDate(e.target.value)} />\n <Button onClick={handleApply}>{t(\"common.apply\")}</Button>\n </div>\n <DateRangePresets onSelect={(from, to) => {\n setFromDate(from);\n setToDate(to);\n patchUrl({ from, to });\n }} />\n\n {isLoading ? (\n <p className=\"text-gray-500\">{t(\"common.loading\")}</p>\n ) : !hasData ? (\n <p className=\"py-8 text-center text-gray-400\">{t(\"reports.noData\")}</p>\n ) : (\n <div className=\"space-y-4\">\n <Card>\n <h3 className=\"mb-3 text-base font-semibold text-gray-800\">{t(\"reports.income\")}</h3>\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">{t(\"fields.Account\", { defaultValue: \"Account\" })}</th>\n <th className=\"px-4 py-3 text-right font-medium text-gray-500\">{t(\"fields.Amount\", { defaultValue: \"Amount\" })}</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {(data.income || []).map((row: any, idx: number) => (\n <tr key={idx} className=\"hover:bg-gray-50\">\n <td className=\"px-4 py-2 text-gray-900\">{row.account}</td>\n <td className=\"px-4 py-2 text-right\">{formatCurrency(row.amount)}</td>\n </tr>\n ))}\n </tbody>\n <tfoot className=\"border-t-2 border-gray-300 bg-gray-50 font-semibold\">\n <tr>\n <td className=\"px-4 py-3 text-gray-900\">{t(\"reports.totalIncome\")}</td>\n <td className=\"px-4 py-3 text-right\">{formatCurrency(data.total_income)}</td>\n </tr>\n </tfoot>\n </table>\n </Card>\n\n <Card>\n <h3 className=\"mb-3 text-base font-semibold text-gray-800\">{t(\"reports.expenses\")}</h3>\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">{t(\"fields.Account\", { defaultValue: \"Account\" })}</th>\n <th className=\"px-4 py-3 text-right font-medium text-gray-500\">{t(\"fields.Amount\", { defaultValue: \"Amount\" })}</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {(data.expense || []).map((row: any, idx: number) => (\n <tr key={idx} className=\"hover:bg-gray-50\">\n <td className=\"px-4 py-2 text-gray-900\">{row.account}</td>\n <td className=\"px-4 py-2 text-right\">{formatCurrency(row.amount)}</td>\n </tr>\n ))}\n </tbody>\n <tfoot className=\"border-t-2 border-gray-300 bg-gray-50 font-semibold\">\n <tr>\n <td className=\"px-4 py-3 text-gray-900\">{t(\"reports.totalExpenses\")}</td>\n <td className=\"px-4 py-3 text-right\">{formatCurrency(data.total_expense)}</td>\n </tr>\n </tfoot>\n </table>\n </Card>\n\n <div className=\"text-center\">\n <span className={`inline-flex items-center rounded-full px-5 py-2 text-sm font-semibold ${data.net_profit >= 0 ? \"bg-green-100 text-green-800\" : \"bg-red-100 text-red-800\"}`}>\n {data.net_profit >= 0 ? t(\"reports.netProfit\") : t(\"reports.netLoss\")}: {formatCurrency(Math.abs(data.net_profit))}\n </span>\n </div>\n </div>\n )}\n </div>\n );\n}\n","import { useState, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useBalanceSheet } from \"@/hooks/use-report\";\nimport { useUrlState, useUrlPatch } from \"@/hooks/use-url-state\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { LinkField } from \"@/components/document/link-field\";\nimport { SingleDatePresets } from \"@/components/ui/date-range-presets\";\nimport { formatCurrency as fmtCurrency } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\n\nfunction SectionTable({ title, rows, total, totalLabel, currency }: { title: string; rows: any[]; total: number; totalLabel: string; currency: string }) {\n const { t } = useTranslation();\n const formatCurrency = (v: number | null | undefined) => fmtCurrency(v, currency);\n return (\n <Card>\n <h3 className=\"mb-3 text-base font-semibold text-gray-800\">{title}</h3>\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">{t(\"fields.Account\", { defaultValue: \"Account\" })}</th>\n <th className=\"px-4 py-3 text-right font-medium text-gray-500\">{t(\"fields.Balance\", { defaultValue: \"Balance\" })}</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {rows.map((row: any, idx: number) => (\n <tr key={idx} className=\"hover:bg-gray-50\">\n <td className=\"px-4 py-2 text-gray-900\">{row.account}</td>\n <td className=\"px-4 py-2 text-right\">{formatCurrency(row.balance)}</td>\n </tr>\n ))}\n </tbody>\n <tfoot className=\"border-t-2 border-gray-300 bg-gray-50 font-semibold\">\n <tr>\n <td className=\"px-4 py-3 text-gray-900\">{totalLabel}</td>\n <td className=\"px-4 py-3 text-right\">{formatCurrency(total)}</td>\n </tr>\n </tfoot>\n </table>\n </Card>\n );\n}\n\nexport default function BalanceSheetPage() {\n const { t } = useTranslation();\n const [urlCompany] = useUrlState<string>(\"company\", \"\");\n const [urlAsOfDate] = useUrlState<string>(\"as_of_date\", \"\");\n const patchUrl = useUrlPatch();\n\n const [company, setCompany] = useState(urlCompany);\n const [asOfDate, setAsOfDate] = useState(urlAsOfDate);\n const baseCurrency = useBaseCurrency(company);\n const formatCurrency = (v: number | null | undefined) => fmtCurrency(v, baseCurrency);\n\n const filters = useMemo(() => {\n const f: Record<string, string> = {};\n if (urlCompany) f.company = urlCompany;\n if (urlAsOfDate) f.as_of_date = urlAsOfDate;\n return f;\n }, [urlCompany, urlAsOfDate]);\n\n const { data, isLoading, refetch } = useBalanceSheet(filters);\n\n const handleApply = () => {\n patchUrl({ company: company || null, as_of_date: asOfDate || null });\n refetch();\n };\n\n const hasData = data && ((data.assets?.length > 0) || (data.liabilities?.length > 0) || (data.equity?.length > 0));\n const isBalanced = data ? Math.abs(data.total_assets - data.total_liabilities_and_equity) < 0.01 : false;\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <LinkField label={t(\"fields.Company\", { defaultValue: \"Company\" })} value={company} onChange={setCompany} linkDoctype=\"company\" readOnly={false} />\n <Input label={t(\"fields.As of Date\", { defaultValue: \"As of Date\" })} type=\"date\" value={asOfDate} onChange={(e) => setAsOfDate(e.target.value)} />\n <Button onClick={handleApply}>{t(\"common.apply\")}</Button>\n </div>\n <SingleDatePresets onSelect={(date) => {\n setAsOfDate(date);\n patchUrl({ as_of_date: date });\n }} />\n\n {isLoading ? (\n <p className=\"text-gray-500\">{t(\"common.loading\")}</p>\n ) : !hasData ? (\n <p className=\"py-8 text-center text-gray-400\">{t(\"reports.noData\")}</p>\n ) : (\n <div className=\"space-y-4\">\n <SectionTable title={t(\"reports.assets\")} rows={data.assets || []} total={data.total_assets} totalLabel={t(\"reports.totalAssets\")} currency={baseCurrency} />\n <SectionTable title={t(\"reports.liabilities\")} rows={data.liabilities || []} total={data.total_liabilities} totalLabel={t(\"reports.totalLiabilities\")} currency={baseCurrency} />\n <SectionTable title={t(\"reports.equity\")} rows={data.equity || []} total={data.total_equity} totalLabel={t(\"reports.totalEquity\")} currency={baseCurrency} />\n\n <Card>\n <div className=\"flex items-center justify-between\">\n <div className=\"text-sm\">\n <div className=\"text-gray-500\">{t(\"reports.totalAssets\")}: <span className=\"font-semibold text-gray-900\">{formatCurrency(data.total_assets)}</span></div>\n <div className=\"text-gray-500\">{t(\"reports.totalLiabilitiesEquity\")}: <span className=\"font-semibold text-gray-900\">{formatCurrency(data.total_liabilities_and_equity)}</span></div>\n </div>\n {isBalanced ? (\n <span className=\"inline-flex items-center rounded-full bg-green-100 px-4 py-1.5 text-sm font-semibold text-green-800\">{t(\"reports.balanced\")}</span>\n ) : (\n <span className=\"inline-flex items-center rounded-full bg-red-100 px-4 py-1.5 text-sm font-semibold text-red-800\">{t(\"reports.imbalanced\")}</span>\n )}\n </div>\n </Card>\n </div>\n )}\n </div>\n );\n}\n","import { useState, useMemo } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { useTranslation } from \"react-i18next\";\nimport { useArAging } from \"@/hooks/use-report\";\nimport { useUrlState, useUrlPatch } from \"@/hooks/use-url-state\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { LinkField } from \"@/components/document/link-field\";\nimport { SingleDatePresets } from \"@/components/ui/date-range-presets\";\nimport { formatCurrency as fmtCurrency } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\n\nexport default function ArAgingPage() {\n const { t } = useTranslation();\n const [urlCompany] = useUrlState<string>(\"company\", \"\");\n const [urlAsOfDate] = useUrlState<string>(\"as_of_date\", \"\");\n const patchUrl = useUrlPatch();\n\n const [company, setCompany] = useState(urlCompany);\n const [asOfDate, setAsOfDate] = useState(urlAsOfDate);\n const baseCurrency = useBaseCurrency(company);\n const formatCurrency = (v: number | null | undefined) => fmtCurrency(v, baseCurrency);\n\n const filters = useMemo(() => {\n const f: Record<string, string> = {};\n if (urlCompany) f.company = urlCompany;\n if (urlAsOfDate) f.as_of_date = urlAsOfDate;\n return f;\n }, [urlCompany, urlAsOfDate]);\n\n const { data, isLoading, refetch } = useArAging(filters);\n\n const handleApply = () => {\n patchUrl({ company: company || null, as_of_date: asOfDate || null });\n refetch();\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <LinkField label={t(\"fields.Company\", { defaultValue: \"Company\" })} value={company} onChange={setCompany} linkDoctype=\"company\" readOnly={false} />\n <Input label={t(\"fields.As of Date\", { defaultValue: \"As of Date\" })} type=\"date\" value={asOfDate} onChange={(e) => setAsOfDate(e.target.value)} />\n <Button onClick={handleApply}>{t(\"common.apply\")}</Button>\n </div>\n <SingleDatePresets onSelect={(date) => {\n setAsOfDate(date);\n patchUrl({ as_of_date: date });\n }} />\n\n {isLoading ? (\n <p className=\"text-gray-500\">{t(\"common.loading\")}</p>\n ) : !data || !data.rows || data.rows.length === 0 ? (\n <p className=\"py-8 text-center text-gray-400\">{t(\"reports.noReceivables\")}</p>\n ) : (\n <Card>\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-3 py-3 text-left font-medium text-gray-500\">{t(\"fields.Invoice\", { defaultValue: \"Invoice\" })}</th>\n <th className=\"px-3 py-3 text-left font-medium text-gray-500\">{t(\"fields.Customer\", { defaultValue: \"Customer\" })}</th>\n <th className=\"px-3 py-3 text-left font-medium text-gray-500\">{t(\"fields.Due Date\", { defaultValue: \"Due Date\" })}</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">{t(\"fields.Outstanding\", { defaultValue: \"Outstanding\" })}</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">{t(\"reports.current\")}</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">1-30</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">31-60</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">61-90</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">90+</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {data.rows.map((row: any, idx: number) => (\n <tr key={idx} className=\"hover:bg-gray-50\">\n <td className=\"px-3 py-2\">\n <Link\n to={`/app/sales-invoice/${encodeURIComponent(row.invoice)}`}\n className=\"font-medium text-blue-600 hover:text-blue-800\"\n >\n {row.invoice}\n </Link>\n </td>\n <td className=\"px-3 py-2 text-gray-900\">{row.customer_name}</td>\n <td className=\"px-3 py-2 text-gray-600\">{row.due_date}</td>\n <td className=\"px-3 py-2 text-right font-medium\">{formatCurrency(row.outstanding)}</td>\n <td className=\"px-3 py-2 text-right\">{row.current ? formatCurrency(row.current) : \"\"}</td>\n <td className=\"px-3 py-2 text-right\">{row.b1_30 ? formatCurrency(row.b1_30) : \"\"}</td>\n <td className=\"px-3 py-2 text-right\">{row.b31_60 ? formatCurrency(row.b31_60) : \"\"}</td>\n <td className=\"px-3 py-2 text-right\">{row.b61_90 ? formatCurrency(row.b61_90) : \"\"}</td>\n <td className=\"px-3 py-2 text-right text-red-600\">{row.b90_plus ? formatCurrency(row.b90_plus) : \"\"}</td>\n </tr>\n ))}\n </tbody>\n <tfoot className=\"border-t-2 border-gray-300 bg-gray-50 font-semibold\">\n <tr>\n <td className=\"px-3 py-3\" colSpan={3}>{t(\"common.total\")}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.outstanding)}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.current)}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.b1_30)}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.b31_60)}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.b61_90)}</td>\n <td className=\"px-3 py-3 text-right text-red-600\">{formatCurrency(data.totals.b90_plus)}</td>\n </tr>\n </tfoot>\n </table>\n </div>\n </Card>\n )}\n </div>\n );\n}\n","import { useState, useMemo } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { useTranslation } from \"react-i18next\";\nimport { useApAging } from \"@/hooks/use-report\";\nimport { useUrlState, useUrlPatch } from \"@/hooks/use-url-state\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { LinkField } from \"@/components/document/link-field\";\nimport { SingleDatePresets } from \"@/components/ui/date-range-presets\";\nimport { formatCurrency as fmtCurrency } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\n\nexport default function ApAgingPage() {\n const { t } = useTranslation();\n const [urlCompany] = useUrlState<string>(\"company\", \"\");\n const [urlAsOfDate] = useUrlState<string>(\"as_of_date\", \"\");\n const patchUrl = useUrlPatch();\n\n const [company, setCompany] = useState(urlCompany);\n const [asOfDate, setAsOfDate] = useState(urlAsOfDate);\n const baseCurrency = useBaseCurrency(company);\n const formatCurrency = (v: number | null | undefined) => fmtCurrency(v, baseCurrency);\n\n const filters = useMemo(() => {\n const f: Record<string, string> = {};\n if (urlCompany) f.company = urlCompany;\n if (urlAsOfDate) f.as_of_date = urlAsOfDate;\n return f;\n }, [urlCompany, urlAsOfDate]);\n\n const { data, isLoading, refetch } = useApAging(filters);\n\n const handleApply = () => {\n patchUrl({ company: company || null, as_of_date: asOfDate || null });\n refetch();\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <LinkField label={t(\"fields.Company\", { defaultValue: \"Company\" })} value={company} onChange={setCompany} linkDoctype=\"company\" readOnly={false} />\n <Input label={t(\"fields.As of Date\", { defaultValue: \"As of Date\" })} type=\"date\" value={asOfDate} onChange={(e) => setAsOfDate(e.target.value)} />\n <Button onClick={handleApply}>{t(\"common.apply\")}</Button>\n </div>\n <SingleDatePresets onSelect={(date) => {\n setAsOfDate(date);\n patchUrl({ as_of_date: date });\n }} />\n\n {isLoading ? (\n <p className=\"text-gray-500\">{t(\"common.loading\")}</p>\n ) : !data || !data.rows || data.rows.length === 0 ? (\n <p className=\"py-8 text-center text-gray-400\">{t(\"reports.noPayables\")}</p>\n ) : (\n <Card>\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-3 py-3 text-left font-medium text-gray-500\">{t(\"fields.Invoice\", { defaultValue: \"Invoice\" })}</th>\n <th className=\"px-3 py-3 text-left font-medium text-gray-500\">{t(\"fields.Supplier\", { defaultValue: \"Supplier\" })}</th>\n <th className=\"px-3 py-3 text-left font-medium text-gray-500\">{t(\"fields.Due Date\", { defaultValue: \"Due Date\" })}</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">{t(\"fields.Outstanding\", { defaultValue: \"Outstanding\" })}</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">{t(\"reports.current\")}</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">1-30</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">31-60</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">61-90</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">90+</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {data.rows.map((row: any, idx: number) => (\n <tr key={idx} className=\"hover:bg-gray-50\">\n <td className=\"px-3 py-2\">\n <Link\n to={`/app/purchase-invoice/${encodeURIComponent(row.invoice)}`}\n className=\"font-medium text-blue-600 hover:text-blue-800\"\n >\n {row.invoice}\n </Link>\n </td>\n <td className=\"px-3 py-2 text-gray-900\">{row.supplier_name}</td>\n <td className=\"px-3 py-2 text-gray-600\">{row.due_date}</td>\n <td className=\"px-3 py-2 text-right font-medium\">{formatCurrency(row.outstanding)}</td>\n <td className=\"px-3 py-2 text-right\">{row.current ? formatCurrency(row.current) : \"\"}</td>\n <td className=\"px-3 py-2 text-right\">{row.b1_30 ? formatCurrency(row.b1_30) : \"\"}</td>\n <td className=\"px-3 py-2 text-right\">{row.b31_60 ? formatCurrency(row.b31_60) : \"\"}</td>\n <td className=\"px-3 py-2 text-right\">{row.b61_90 ? formatCurrency(row.b61_90) : \"\"}</td>\n <td className=\"px-3 py-2 text-right text-red-600\">{row.b90_plus ? formatCurrency(row.b90_plus) : \"\"}</td>\n </tr>\n ))}\n </tbody>\n <tfoot className=\"border-t-2 border-gray-300 bg-gray-50 font-semibold\">\n <tr>\n <td className=\"px-3 py-3\" colSpan={3}>{t(\"common.total\")}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.outstanding)}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.current)}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.b1_30)}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.b31_60)}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.b61_90)}</td>\n <td className=\"px-3 py-3 text-right text-red-600\">{formatCurrency(data.totals.b90_plus)}</td>\n </tr>\n </tfoot>\n </table>\n </div>\n </Card>\n )}\n </div>\n );\n}\n","import { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useNavigate } from \"react-router-dom\";\nimport {\n Bar,\n BarChart,\n CartesianGrid,\n Cell,\n Line,\n LineChart,\n Pie,\n PieChart,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport { useUrlState } from \"@/hooks/use-url-state\";\nimport { Card } from \"@/components/ui/card\";\nimport { Button } from \"@/components/ui/button\";\nimport { useChat } from \"@/components/chat/chat-provider\";\n// Inlined (?worker&inline) so the published library bundle carries the worker\n// as an embedded blob rather than an external /assets/*.js reference. A bare\n// `new Worker(new URL(...))` makes Vite emit an absolute /assets URL that a\n// downstream consumer's build resolves against its own public/ dir and fails\n// to find. Inlining keeps the package consumer-buildable.\nimport ReportRuntimeWorker from \"@/workers/report-runtime.worker.ts?worker&inline\";\nimport { flt, formatCurrency, formatDate, formatNumber } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\nimport { api } from \"@/api/client\";\n\ntype RuntimeDatasetResult = {\n name: string;\n dataset: string;\n rows: Array<Record<string, unknown>>;\n fields: Record<string, string>;\n row_count: number;\n truncated: boolean;\n limit: number;\n};\n\ntype RuntimeReportOutput = {\n title?: string;\n summary?: string;\n kpis?: Array<{ label: string; value: number | string; format?: \"currency\" | \"percent\" | \"number\" | \"date\" }>;\n tables?: Array<{\n id?: string;\n title: string;\n columns: Array<{ key: string; label: string; type?: string; format?: string }>;\n rows: Array<Record<string, unknown>>;\n }>;\n charts?: Array<{\n id?: string;\n title: string;\n type: \"bar\" | \"line\" | \"pie\";\n dataTable?: string;\n data?: Array<Record<string, unknown>>;\n x: string;\n y: string;\n }>;\n};\n\ntype RuntimeReportTable = NonNullable<RuntimeReportOutput[\"tables\"]>[number];\n\nfunction buildExampleCustomReport(): string {\n // Rolling 12-month window ending today — no hardcoded company so this works\n // on any tenant's data out of the box.\n const today = new Date();\n const to = today.toISOString().slice(0, 10);\n const start = new Date(today);\n start.setMonth(start.getMonth() - 12);\n const from = start.toISOString().slice(0, 10);\n\n return JSON.stringify(\n {\n title: \"Top Customers by Revenue — Last 12 Months\",\n description: \"Top customers ranked by net sales revenue over the past 12 months.\",\n data_requests: [\n {\n name: \"sales\",\n dataset: \"sales_invoices\",\n fields: [\n \"posting_date\",\n \"customer\",\n \"customer_name\",\n \"net_total\",\n \"is_return\",\n ],\n filters: {\n posting_date: { from, to },\n is_return: 0,\n },\n },\n ],\n transform_js: `const grouped = helpers.group(sales, ['customer', 'customer_name'], {\n revenue: ['sum', 'net_total'],\n invoice_count: ['count', 'net_total'],\n});\nconst sorted = helpers.sortBy(grouped, 'revenue', 'desc');\nconst top = helpers.topN(sorted, 10);\nconst totalRevenue = helpers.sum(grouped, 'revenue');\n\nreturn {\n title: 'Top Customers by Revenue — Last 12 Months',\n kpis: [\n { label: 'Total Revenue', value: totalRevenue, format: 'currency' },\n { label: 'Top 10 Revenue', value: helpers.sum(top, 'revenue'), format: 'currency' },\n { label: 'Customers Shown', value: top.length, format: 'number' },\n ],\n tables: [\n {\n title: 'Top Customers by Revenue',\n columns: [\n { key: 'customer_name', label: 'Customer', type: 'string' },\n { key: 'invoice_count', label: 'Invoices', type: 'number' },\n { key: 'revenue', label: 'Revenue', type: 'currency' },\n ],\n rows: top.map(function(r) { return {\n customer: r.customer,\n customer_name: r.customer_name || r.customer,\n invoice_count: r.invoice_count,\n revenue: r.revenue,\n }; }),\n },\n ],\n charts: [\n {\n title: 'Top Customers by Revenue',\n type: 'bar',\n x: 'customer_name',\n y: 'revenue',\n dataTable: 'Top Customers by Revenue',\n },\n ],\n};`,\n },\n null,\n 2,\n );\n}\n\nconst EXAMPLE_CUSTOM_REPORT = buildExampleCustomReport();\n\nexport default function AnalyticsPage() {\n const navigate = useNavigate();\n const { sessions, createSession } = useChat();\n\n const [reportId] = useUrlState<string>(\"report_id\", \"\");\n const [metric] = useUrlState<string>(\"metric\", \"\");\n const [groupBy] = useUrlState<string>(\"group_by\", \"\");\n const [urlFrom] = useUrlState<string>(\"from\", \"\");\n const [urlTo] = useUrlState<string>(\"to\", \"\");\n const [urlCompany] = useUrlState<string>(\"company\", \"\");\n const [customSpec, setCustomSpec] = useState(EXAMPLE_CUSTOM_REPORT);\n const [runtimeData, setRuntimeData] = useState<RuntimeDatasetResult[]>([]);\n const [runtimeOutput, setRuntimeOutput] = useState<RuntimeReportOutput | null>(null);\n const [runtimeError, setRuntimeError] = useState(\"\");\n const [running, setRunning] = useState(false);\n const [loadingDraft, setLoadingDraft] = useState(false);\n const [sourceChatSessionId, setSourceChatSessionId] = useState(\"\");\n const workerRef = useRef<Worker | null>(null);\n const loadedDraftRef = useRef<string>(\"\");\n const loadedSpecRef = useRef<string>(\"\");\n // Monotonic counter so stale runs (e.g. superseded by a StrictMode\n // double-invoke) can be ignored when their timers or messages fire late.\n const runIdRef = useRef(0);\n\n const legacySpecText = useMemo(() => {\n if (!metric || !groupBy) return \"\";\n return JSON.stringify(buildLegacyRuntimeSpec({\n metric,\n groupBy,\n fromDate: urlFrom || undefined,\n toDate: urlTo || undefined,\n company: urlCompany || undefined,\n }), null, 2);\n }, [metric, groupBy, urlFrom, urlTo, urlCompany]);\n\n const onRunCustom = async (specText?: string) => {\n const runId = ++runIdRef.current;\n const isCurrent = () => runIdRef.current === runId;\n setRuntimeError(\"\");\n setRunning(true);\n try {\n const source = specText ?? customSpec;\n const spec = JSON.parse(source);\n const dataResponse = await api.runtimeData({ requests: spec.data_requests || [] });\n if (!isCurrent()) return;\n setRuntimeData(dataResponse.datasets);\n\n workerRef.current?.terminate();\n const worker = new ReportRuntimeWorker();\n workerRef.current = worker;\n\n const result = await new Promise<RuntimeReportOutput>((resolve, reject) => {\n const timer = window.setTimeout(() => {\n worker.terminate();\n reject(new Error(\"Report runtime exceeded 4 seconds\"));\n }, 4000);\n worker.onmessage = (event) => {\n window.clearTimeout(timer);\n worker.terminate();\n if (workerRef.current === worker) workerRef.current = null;\n if (event.data?.ok) {\n resolve(event.data.output);\n } else {\n reject(new Error(event.data?.error || \"Runtime failed\"));\n }\n };\n worker.postMessage({\n datasets: dataResponse.datasets,\n params: {},\n transformJs: spec.transform_js || \"return {};\",\n });\n });\n\n if (!isCurrent()) return;\n setRuntimeOutput(result);\n } catch (error) {\n if (!isCurrent()) return;\n setRuntimeOutput(null);\n setRuntimeError(error instanceof Error ? error.message : String(error));\n } finally {\n if (isCurrent()) setRunning(false);\n }\n };\n\n useEffect(() => {\n let cancelled = false;\n if (reportId) {\n if (loadedDraftRef.current === reportId) return;\n setLoadingDraft(true);\n setRuntimeError(\"\");\n api.getRuntimeDraft(reportId)\n .then((draft) => {\n if (cancelled) return;\n const nextSpec = JSON.stringify(draft.definition, null, 2);\n loadedDraftRef.current = reportId;\n loadedSpecRef.current = nextSpec;\n setSourceChatSessionId(draft.source_chat_session_id || \"\");\n setCustomSpec(nextSpec);\n return onRunCustom(nextSpec);\n })\n .catch((error) => {\n if (!cancelled) {\n setRuntimeOutput(null);\n setRuntimeError(error instanceof Error ? error.message : String(error));\n }\n })\n .finally(() => {\n if (!cancelled) setLoadingDraft(false);\n });\n return () => {\n cancelled = true;\n };\n }\n\n loadedDraftRef.current = \"\";\n loadedSpecRef.current = \"\";\n setSourceChatSessionId(\"\");\n if (legacySpecText) {\n loadedSpecRef.current = legacySpecText;\n setCustomSpec(legacySpecText);\n void onRunCustom(legacySpecText);\n }\n return () => {\n cancelled = true;\n };\n }, [reportId, legacySpecText]);\n\n const showLegacyBanner = Boolean(!reportId && legacySpecText);\n const renderIssues = useMemo(() => describeRuntimeOutputIssues(runtimeOutput), [runtimeOutput]);\n\n const onFixInChat = async () => {\n const isDirty = customSpec.trim() !== loadedSpecRef.current.trim();\n const reportLabel = reportId || \"unsaved-runtime-report\";\n const preview = runtimeData.map((dataset) => ({\n name: dataset.name,\n dataset: dataset.dataset,\n row_count: dataset.row_count,\n sample_rows: dataset.rows.slice(0, 3),\n }));\n const parts = [\n \"This custom analytics report does not work yet. Please repair the existing report draft instead of creating a new one.\",\n \"\",\n `Report ID: ${reportLabel}`,\n \"\",\n \"Current issue summary:\",\n runtimeError || renderIssues.join(\"\\n\") || \"No runtime error captured; please review and improve the report definition.\",\n ];\n\n if (isDirty) {\n parts.push(\n \"\",\n \"The analytics editor contains unsaved local changes. Use this JSON as the source of truth when repairing the draft:\",\n \"```json\",\n customSpec,\n \"```\",\n );\n } else {\n parts.push(\n \"\",\n \"Load the current saved draft with `get_custom_analytics_report` before making changes.\",\n );\n }\n\n if (preview.length > 0) {\n parts.push(\n \"\",\n \"Fetched dataset preview:\",\n \"```json\",\n JSON.stringify(preview, null, 2),\n \"```\",\n );\n }\n\n const message = parts.join(\"\\n\");\n\n let targetSessionId = sourceChatSessionId;\n if (!targetSessionId) {\n targetSessionId = sessions[0]?.id || \"\";\n }\n if (!targetSessionId) {\n const created = await createSession();\n targetSessionId = created.id;\n }\n navigate(`/chat/${targetSessionId}`, { state: { prefillMessage: message } });\n };\n\n return (\n <div className=\"space-y-4\">\n <Card>\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div>\n <h2 className=\"text-lg font-semibold text-gray-900\">Analytics</h2>\n <p className=\"text-sm text-gray-600\">\n All analytics now run through the custom runtime and semantic datasets.\n </p>\n </div>\n <div className=\"flex items-center gap-3\">\n {reportId ? (\n <div className=\"text-xs text-gray-500\">Loaded draft: {reportId}</div>\n ) : showLegacyBanner ? (\n <div className=\"text-xs text-gray-500\">Loaded runtime report from legacy URL filters.</div>\n ) : null}\n {reportId ? (\n <Button variant=\"secondary\" onClick={() => void onFixInChat()}>\n Fix In Chat\n </Button>\n ) : null}\n <Button onClick={() => void onRunCustom()} disabled={running}>\n {running ? \"Running...\" : \"Run Report\"}\n </Button>\n </div>\n </div>\n </Card>\n\n {loadingDraft ? (\n <Card>\n <p className=\"text-sm text-gray-600\">Loading draft...</p>\n </Card>\n ) : runtimeError ? (\n <Card>\n <p className=\"text-sm text-red-600\">{runtimeError}</p>\n </Card>\n ) : runtimeOutput ? (\n <RuntimeReportRenderer output={runtimeOutput} />\n ) : (\n <Card>\n <p className=\"text-sm text-gray-600\">\n Edit the runtime JSON below or open a draft from chat, then run the report.\n </p>\n </Card>\n )}\n\n {runtimeData.length > 0 && (\n <Card title=\"Fetched Datasets\">\n <div className=\"space-y-4\">\n {runtimeData.map((dataset) => (\n <div key={dataset.name} className=\"rounded-md border border-gray-200 p-4\">\n <div className=\"flex items-baseline justify-between gap-4\">\n <div>\n <div className=\"font-medium text-gray-900\">{dataset.name}</div>\n <div className=\"text-xs text-gray-500\">{dataset.dataset}</div>\n </div>\n <div className=\"text-xs text-gray-500\">\n {dataset.row_count} rows\n {dataset.truncated ? ` (truncated at ${dataset.limit})` : \"\"}\n </div>\n </div>\n <pre className=\"mt-3 overflow-x-auto rounded bg-gray-50 p-3 text-xs text-gray-700\">\n {JSON.stringify(dataset.rows.slice(0, 5), null, 2)}\n </pre>\n </div>\n ))}\n </div>\n </Card>\n )}\n\n <Card>\n <label className=\"mb-2 block text-sm font-medium text-gray-700\">Report Definition JSON</label>\n <textarea\n className=\"min-h-[520px] w-full rounded-md border border-gray-300 p-3 font-mono text-xs text-gray-900 outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500\"\n value={customSpec}\n onChange={(e) => setCustomSpec(e.target.value)}\n spellCheck={false}\n />\n </Card>\n </div>\n );\n}\n\nfunction RuntimeReportRenderer({ output }: { output: RuntimeReportOutput }) {\n // Custom-report currency values are base-currency numbers; format them with\n // the company currency instead of the util's hardcoded USD default.\n const baseCurrency = useBaseCurrency();\n const tables = (output.tables ?? []).map((table, idx) => ({\n ...table,\n id: table.id || `table_${idx + 1}`,\n }));\n const chartTables = buildChartTableIndex(tables);\n return (\n <div className=\"space-y-4\">\n <Card>\n <div className=\"flex items-baseline justify-between gap-4\">\n <div>\n <h3 className=\"text-lg font-semibold text-gray-900\">{output.title || \"Custom Report\"}</h3>\n {output.summary && <p className=\"mt-1 text-sm text-gray-600\">{output.summary}</p>}\n </div>\n </div>\n {output.kpis?.length ? (\n <div className=\"mt-4 grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {output.kpis.map((kpi, idx) => (\n <div key={`${kpi.label}-${idx}`} className=\"rounded-md border border-gray-200 p-4\">\n <div className=\"text-sm text-gray-500\">{kpi.label}</div>\n <div className=\"mt-1 text-2xl font-semibold text-gray-900\">\n {formatRuntimeValue(kpi.value, kpi.format, baseCurrency)}\n </div>\n </div>\n ))}\n </div>\n ) : null}\n </Card>\n\n {output.charts?.map((chart, idx) => {\n const table = chart.dataTable ? chartTables.get(chart.dataTable) : undefined;\n const rows = chart.data ?? table?.rows ?? [];\n if (!rows.length) {\n return (\n <Card key={chart.id || `chart_${idx + 1}`} title={chart.title}>\n <p className=\"text-sm text-red-600\">Chart has no usable data.</p>\n </Card>\n );\n }\n const xLabels = chart.type === \"pie\"\n ? []\n : rows.map((row) => String(row[chart.x] ?? \"\"));\n const layout = computeAxisLayout(xLabels);\n const containerHeight = Math.max(320, 200 + layout.axisHeight);\n return (\n <Card key={chart.id || `chart_${idx + 1}`}>\n <div className=\"pb-3 text-sm font-semibold text-gray-700\">{chart.title}</div>\n <div style={{ height: containerHeight }} className=\"w-full\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n {chart.type === \"line\" ? (\n <LineChart data={rows} margin={{ top: 10, right: 20, left: 0, bottom: 0 }}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"#f3f4f6\" />\n <XAxis\n dataKey={chart.x}\n tick={{ fill: \"#6b7280\", fontSize: 12 }}\n interval={0}\n angle={layout.angle}\n textAnchor={layout.angle === 0 ? \"middle\" : \"end\"}\n height={layout.axisHeight}\n />\n <YAxis tick={{ fill: \"#6b7280\", fontSize: 12 }} tickFormatter={shortNum} />\n <Tooltip formatter={(v) => formatRuntimeValue(v, inferFormat(table, chart.y), baseCurrency)} />\n <Line type=\"monotone\" dataKey={chart.y} stroke=\"#3b82f6\" strokeWidth={2} dot={{ r: 3 }} />\n </LineChart>\n ) : chart.type === \"pie\" ? (\n <PieChart>\n <Tooltip formatter={(v) => formatRuntimeValue(v, inferFormat(table, chart.y), baseCurrency)} />\n <Pie data={rows} dataKey={chart.y} nameKey={chart.x} outerRadius={110}>\n {rows.map((_, rowIdx) => (\n <Cell key={rowIdx} fill={PIE_COLORS[rowIdx % PIE_COLORS.length]} />\n ))}\n </Pie>\n </PieChart>\n ) : (\n <BarChart data={rows} margin={{ top: 10, right: 20, left: 0, bottom: 0 }}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"#f3f4f6\" />\n <XAxis\n dataKey={chart.x}\n tick={{ fill: \"#6b7280\", fontSize: 12 }}\n interval={0}\n angle={layout.angle}\n textAnchor={layout.angle === 0 ? \"middle\" : \"end\"}\n height={layout.axisHeight}\n />\n <YAxis tick={{ fill: \"#6b7280\", fontSize: 12 }} tickFormatter={shortNum} />\n <Tooltip formatter={(v) => formatRuntimeValue(v, inferFormat(table, chart.y), baseCurrency)} />\n <Bar dataKey={chart.y} fill=\"#3b82f6\" radius={[4, 4, 0, 0]} />\n </BarChart>\n )}\n </ResponsiveContainer>\n </div>\n </Card>\n );\n })}\n\n {tables.map((table) => (\n <Card key={table.id} title={table.title}>\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n {table.columns.map((column) => (\n <th key={column.key} className=\"px-4 py-2 text-left font-medium text-gray-500\">\n {column.label}\n </th>\n ))}\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {table.rows.map((row, idx) => (\n <tr key={idx} className=\"hover:bg-gray-50\">\n {table.columns.map((column) => (\n <td key={column.key} className=\"px-4 py-1.5 text-gray-900\">\n {formatRuntimeValue(row[column.key], column.type, baseCurrency)}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </Card>\n ))}\n </div>\n );\n}\n\nfunction labelFor(groupBy: string): string {\n return groupBy\n .replace(/_/g, \" \")\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\nfunction buildChartTableIndex<T extends { id: string; title?: string }>(\n tables: T[],\n): Map<string, T> {\n // Charts can reference a table by either its id or its title. Build a\n // lookup map keyed by both so the specialist model — which naturally\n // reaches for \"<table title>\" — gets a match.\n const map = new Map<string, T>();\n for (const table of tables) {\n map.set(table.id, table);\n if (table.title) map.set(table.title, table);\n }\n return map;\n}\n\nfunction describeRuntimeOutputIssues(output: RuntimeReportOutput | null): string[] {\n if (!output) return [];\n const tables = (output.tables ?? []).map((table, idx) => ({\n ...table,\n id: table.id || `table_${idx + 1}`,\n }));\n const chartTables = buildChartTableIndex(tables);\n const issues: string[] = [];\n\n for (const chart of output.charts ?? []) {\n const table = chart.dataTable ? chartTables.get(chart.dataTable) : undefined;\n const rows = chart.data ?? table?.rows ?? [];\n if (!rows.length) {\n issues.push(`Chart \"${chart.title}\" has no usable data.`);\n continue;\n }\n if (typeof chart.y !== \"string\" || !chart.y) {\n issues.push(`Chart \"${chart.title}\" has an invalid y field; expected a single string field name.`);\n } else if (!rows.some((row) => row[chart.y] != null)) {\n issues.push(`Chart \"${chart.title}\" does not have any values for y=\"${chart.y}\".`);\n }\n if (!chart.x || !rows.some((row) => row[chart.x] != null)) {\n issues.push(`Chart \"${chart.title}\" does not have any values for x=\"${chart.x}\".`);\n }\n if (chart.dataTable && !table) {\n issues.push(`Chart \"${chart.title}\" references missing table \"${chart.dataTable}\".`);\n }\n }\n\n return issues;\n}\n\nfunction buildLegacyRuntimeSpec(args: {\n metric: string;\n groupBy: string;\n fromDate?: string;\n toDate?: string;\n company?: string;\n}) {\n const title = `${legacyMetricLabel(args.metric)} by ${labelFor(args.groupBy)}`;\n const timeBucket = args.groupBy === \"month\" ? \"helpers.monthKey\" : args.groupBy === \"quarter\" ? \"helpers.quarterKey\" : \"helpers.yearKey\";\n\n if (args.metric === \"sales_revenue\") {\n return buildGroupedAmountSpec({\n title,\n dataset: args.groupBy === \"item\" ? \"sales_invoice_lines\" : \"sales_invoices\",\n requestName: \"rows\",\n keyField: args.groupBy === \"item\" ? \"item_code\" : args.groupBy === \"customer\" ? \"customer\" : \"posting_date\",\n valueField: args.groupBy === \"item\" ? \"net_amount\" : \"grand_total\",\n groupBy: args.groupBy,\n timeBucket,\n filters: {\n company: args.company,\n posting_date: args.fromDate || args.toDate ? { from: args.fromDate, to: args.toDate } : undefined,\n is_return: 0,\n },\n fields: args.groupBy === \"item\"\n ? [\"posting_date\", \"item_code\", \"net_amount\"]\n : [\"posting_date\", \"customer\", \"grand_total\"],\n chartType: args.groupBy === \"customer\" || args.groupBy === \"item\" ? \"bar\" : \"line\",\n });\n }\n\n if (args.metric === \"sales_returns\") {\n return buildGroupedAmountSpec({\n title,\n dataset: \"sales_invoices\",\n requestName: \"rows\",\n keyField: args.groupBy === \"customer\" ? \"customer\" : \"posting_date\",\n valueField: \"grand_total\",\n groupBy: args.groupBy,\n timeBucket,\n filters: {\n company: args.company,\n posting_date: args.fromDate || args.toDate ? { from: args.fromDate, to: args.toDate } : undefined,\n is_return: 1,\n },\n fields: [\"posting_date\", \"customer\", \"grand_total\"],\n chartType: args.groupBy === \"customer\" ? \"bar\" : \"line\",\n });\n }\n\n if (args.metric === \"purchases\") {\n return buildGroupedAmountSpec({\n title,\n dataset: args.groupBy === \"item\" ? \"purchase_invoice_lines\" : \"purchase_invoices\",\n requestName: \"rows\",\n keyField: args.groupBy === \"item\" ? \"item_code\" : args.groupBy === \"supplier\" ? \"supplier\" : \"posting_date\",\n valueField: args.groupBy === \"item\" ? \"net_amount\" : \"grand_total\",\n groupBy: args.groupBy,\n timeBucket,\n filters: {\n company: args.company,\n posting_date: args.fromDate || args.toDate ? { from: args.fromDate, to: args.toDate } : undefined,\n is_return: 0,\n },\n fields: args.groupBy === \"item\"\n ? [\"posting_date\", \"item_code\", \"net_amount\"]\n : [\"posting_date\", \"supplier\", \"grand_total\"],\n chartType: args.groupBy === \"supplier\" || args.groupBy === \"item\" ? \"bar\" : \"line\",\n });\n }\n\n if (args.metric === \"payments_received\" || args.metric === \"payments_made\") {\n const isReceived = args.metric === \"payments_received\";\n return buildGroupedAmountSpec({\n title,\n dataset: \"payments\",\n requestName: \"rows\",\n keyField: args.groupBy === (isReceived ? \"customer\" : \"supplier\") ? \"party\" : \"posting_date\",\n valueField: isReceived ? \"received_amount\" : \"paid_amount\",\n groupBy: args.groupBy,\n timeBucket,\n filters: {\n company: args.company,\n posting_date: args.fromDate || args.toDate ? { from: args.fromDate, to: args.toDate } : undefined,\n payment_type: isReceived ? \"Receive\" : \"Pay\",\n party_type: isReceived ? \"Customer\" : \"Supplier\",\n },\n fields: [\"posting_date\", \"party\", isReceived ? \"received_amount\" : \"paid_amount\"],\n chartType: args.groupBy === (isReceived ? \"customer\" : \"supplier\") ? \"bar\" : \"line\",\n });\n }\n\n if (args.metric === \"outstanding_ar\" || args.metric === \"outstanding_ap\") {\n const isAr = args.metric === \"outstanding_ar\";\n const dataset = isAr ? \"ar_open_items\" : \"ap_open_items\";\n const partyField = isAr ? \"customer\" : \"supplier\";\n const amountField = \"outstanding_amount\";\n return buildGroupedAmountSpec({\n title,\n dataset,\n requestName: \"rows\",\n keyField: partyField,\n valueField: amountField,\n groupBy: partyField,\n timeBucket,\n filters: {\n company: args.company,\n posting_date: args.fromDate || args.toDate ? { from: args.fromDate, to: args.toDate } : undefined,\n },\n fields: [\"posting_date\", partyField, amountField],\n chartType: \"bar\",\n });\n }\n\n if (args.metric === \"stock_value\") {\n return buildGroupedAmountSpec({\n title,\n dataset: \"stock_balances\",\n requestName: \"rows\",\n keyField: args.groupBy === \"warehouse\" ? \"warehouse\" : \"item_code\",\n valueField: \"stock_value\",\n groupBy: args.groupBy,\n timeBucket,\n filters: {\n company: args.company,\n },\n fields: [args.groupBy === \"warehouse\" ? \"warehouse\" : \"item_code\", \"stock_value\"],\n chartType: \"bar\",\n });\n }\n\n return JSON.parse(EXAMPLE_CUSTOM_REPORT);\n}\n\nfunction buildGroupedAmountSpec(args: {\n title: string;\n dataset: string;\n requestName: string;\n keyField: string;\n valueField: string;\n groupBy: string;\n timeBucket: string;\n filters: Record<string, unknown>;\n fields: string[];\n chartType: \"bar\" | \"line\";\n}) {\n const filters = Object.fromEntries(Object.entries(args.filters).filter(([, value]) => value !== undefined));\n const bucketExpr = [\"month\", \"quarter\", \"year\"].includes(args.groupBy)\n ? `${args.timeBucket}(row.${args.keyField})`\n : `row.${args.keyField} || \"—\"`;\n return {\n title: args.title,\n data_requests: [\n {\n name: args.requestName,\n dataset: args.dataset,\n fields: args.fields,\n filters,\n limit: 5000,\n },\n ],\n transform_js: `const grouped = helpers.group(\n datasets.${args.requestName}.map((row) => ({\n bucket: ${bucketExpr},\n amount: helpers.flt(row.${args.valueField}),\n })),\n [\"bucket\"],\n { value: [\"sum\", \"amount\"] },\n);\n\nconst ordered = helpers.sortBy(grouped, ${[\"month\", \"quarter\", \"year\"].includes(args.groupBy) ? `\"bucket\", \"asc\"` : `\"value\", \"desc\"`});\n\nreturn {\n title: ${JSON.stringify(args.title)},\n kpis: [\n { label: \"Rows\", value: ordered.length, format: \"number\" },\n { label: \"Total\", value: helpers.sum(ordered, \"value\"), format: \"currency\" }\n ],\n tables: [\n {\n id: \"main\",\n title: ${JSON.stringify(args.title)},\n columns: [\n { key: \"bucket\", label: \"Bucket\", type: \"string\" },\n { key: \"value\", label: \"Value\", type: \"currency\" }\n ],\n rows: ordered\n }\n ],\n charts: [\n {\n id: \"main_chart\",\n title: ${JSON.stringify(args.title)},\n type: ${JSON.stringify(args.chartType)},\n dataTable: \"main\",\n x: \"bucket\",\n y: \"value\"\n }\n ]\n};`,\n };\n}\n\nfunction legacyMetricLabel(metric: string) {\n const labels: Record<string, string> = {\n sales_revenue: \"Sales Revenue\",\n sales_returns: \"Sales Returns\",\n purchases: \"Purchases\",\n payments_received: \"Payments Received\",\n payments_made: \"Payments Made\",\n outstanding_ar: \"Outstanding AR\",\n outstanding_ap: \"Outstanding AP\",\n stock_value: \"Stock Value\",\n };\n return labels[metric] || \"Analytics\";\n}\n\nfunction inferFormat(table: RuntimeReportTable | undefined, key: string) {\n return table?.columns.find((column) => column.key === key)?.type || table?.columns.find((column) => column.key === key)?.format;\n}\n\nfunction formatRuntimeValue(value: unknown, type?: string, currency?: string) {\n if (type === \"currency\") return formatCurrency(flt(value), currency);\n if (type === \"percent\") return `${(flt(value) * 100).toFixed(1)}%`;\n if (type === \"number\") return formatNumber(flt(value));\n if (type === \"date\") return formatDate(String(value ?? \"\"));\n if (typeof value === \"number\") return formatNumber(value);\n return String(value ?? \"\");\n}\n\nfunction shortNum(n: number): string {\n const abs = Math.abs(n);\n if (abs >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (abs >= 1_000) return `${(n / 1_000).toFixed(0)}k`;\n return String(n);\n}\n\nconst PIE_COLORS = [\"#3b82f6\", \"#10b981\", \"#f59e0b\", \"#ef4444\", \"#8b5cf6\", \"#06b6d4\"];\n\n// -----------------------------------------------------------------------------\n// X-axis auto-fit\n//\n// Use Canvas 2d's measureText to get the actual rendered pixel width of each\n// tick label at the same font used by recharts ticks. From there we pick an\n// angle and axis height that accommodates the longest label without the\n// letters getting clipped against the card edge.\n// -----------------------------------------------------------------------------\n\nconst AXIS_TICK_FONT = '12px -apple-system, system-ui, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif';\n\nlet _measureCanvas: HTMLCanvasElement | null = null;\nfunction measureTextWidth(text: string, font: string = AXIS_TICK_FONT): number {\n if (typeof document === \"undefined\") return text.length * 7;\n if (!_measureCanvas) _measureCanvas = document.createElement(\"canvas\");\n const ctx = _measureCanvas.getContext(\"2d\");\n if (!ctx) return text.length * 7;\n ctx.font = font;\n return ctx.measureText(text).width;\n}\n\nfunction computeAxisLayout(labels: string[]): { angle: number; axisHeight: number; maxWidth: number } {\n if (!labels.length) return { angle: 0, axisHeight: 30, maxWidth: 0 };\n const widths = labels.map((label) => measureTextWidth(label));\n const maxWidth = Math.max(1, ...widths);\n let angle = 0;\n if (maxWidth > 55) angle = -30;\n if (maxWidth > 110) angle = -45;\n if (maxWidth > 200) angle = -60;\n if (maxWidth > 300) angle = -90;\n const radians = (Math.abs(angle) * Math.PI) / 180;\n const projected =\n angle === 0 ? 20 : Math.abs(angle) === 90 ? maxWidth : Math.ceil(maxWidth * Math.sin(radians));\n // Pad by ~18px for tick marks, font descenders, and a little breathing room.\n const axisHeight = Math.min(280, Math.max(30, projected + 18));\n return { angle, axisHeight, maxWidth };\n}\n","import { useState } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { api } from \"@/api/client\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Select } from \"@/components/ui/select\";\nimport { Button } from \"@/components/ui/button\";\n\nconst CURRENCY_OPTIONS = [\"USD\", \"EUR\", \"GBP\", \"CHF\", \"JPY\", \"CAD\", \"AUD\", \"CNY\", \"INR\"];\n\ntype SeedMode = \"none\" | \"quick\" | \"history\";\n\nexport default function SetupPage() {\n const queryClient = useQueryClient();\n\n const { data: status, isLoading } = useQuery({\n queryKey: [\"setup-status\"],\n queryFn: () => api.setupStatus(),\n });\n\n const [companyName, setCompanyName] = useState(\"\");\n const [currency, setCurrency] = useState(\"USD\");\n const [details, setDetails] = useState({\n address: \"\",\n city: \"\",\n zip_code: \"\",\n country: \"\",\n email: \"\",\n phone: \"\",\n tax_id: \"\",\n });\n const setDetail = (key: keyof typeof details) => (e: { target: { value: string } }) =>\n setDetails((d) => ({ ...d, [key]: e.target.value }));\n const [seedMode, setSeedMode] = useState<SeedMode>(\"quick\");\n const [success, setSuccess] = useState(false);\n const [historyStats, setHistoryStats] = useState<Record<string, number> | null>(null);\n\n const createCompanyMut = useMutation({\n mutationFn: () => api.createCompany({ name: companyName, currency, ...details }),\n });\n\n const seedDemoMut = useMutation({\n mutationFn: () => api.seedDemo(),\n });\n\n const seedHistoryMut = useMutation({\n mutationFn: () => api.seedHistory(),\n });\n\n const handleSetup = async () => {\n if (!companyName.trim()) return;\n try {\n await createCompanyMut.mutateAsync();\n if (seedMode === \"history\") {\n const res = await seedHistoryMut.mutateAsync();\n setHistoryStats(res.stats);\n } else if (seedMode === \"quick\") {\n await seedDemoMut.mutateAsync();\n }\n // seedMode === \"none\": create the company only, seed nothing.\n queryClient.invalidateQueries({ queryKey: [\"setup-status\"] });\n setSuccess(true);\n } catch {\n // errors handled by mutation state\n }\n };\n\n if (isLoading) {\n return <p className=\"text-gray-500\">Loading...</p>;\n }\n\n // Setup already complete -- show existing companies\n if (status?.setup_complete && !success) {\n return (\n <div className=\"space-y-6\">\n <Card title=\"Companies\">\n {status.companies && status.companies.length > 0 ? (\n <ul className=\"divide-y divide-gray-100\">\n {status.companies.map((company: any, idx: number) => (\n <li key={idx} className=\"py-3\">\n <CompanyRow company={company} />\n </li>\n ))}\n </ul>\n ) : (\n <p className=\"text-gray-400\">No companies found</p>\n )}\n </Card>\n <Link to=\"/\" className=\"text-blue-600 hover:text-blue-800 text-sm font-medium\">\n Go to Dashboard\n </Link>\n </div>\n );\n }\n\n // Success state after setup\n if (success) {\n return (\n <div className=\"space-y-6\">\n <Card>\n <div className=\"py-8 text-center\">\n <p className=\"text-lg font-semibold text-green-700\">\n Setup complete!\n </p>\n <p className=\"mt-2 text-sm text-gray-500\">\n {seedMode === \"history\"\n ? \"Your company has been created and three years of history has been simulated.\"\n : seedMode === \"quick\"\n ? \"Your company has been created and demo data has been seeded.\"\n : \"Your company has been created. No demo data was added.\"}\n </p>\n {historyStats && (\n <div className=\"mx-auto mt-6 max-w-sm text-left\">\n <p className=\"mb-2 text-sm font-medium text-gray-700\">Generated documents:</p>\n <ul className=\"divide-y divide-gray-100 text-sm\">\n {Object.entries(historyStats)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([k, v]) => (\n <li key={k} className=\"flex justify-between py-1\">\n <span className=\"text-gray-600\">{k.replace(/_/g, \" \")}</span>\n <span className=\"font-mono text-gray-900\">{v.toLocaleString()}</span>\n </li>\n ))}\n </ul>\n </div>\n )}\n <div className=\"mt-6\">\n <Link to=\"/\">\n <Button>Go to Dashboard</Button>\n </Link>\n </div>\n </div>\n </Card>\n </div>\n );\n }\n\n // First-run setup form\n const isPending =\n createCompanyMut.isPending || seedDemoMut.isPending || seedHistoryMut.isPending;\n const error = createCompanyMut.error ?? seedDemoMut.error ?? seedHistoryMut.error;\n\n return (\n <div className=\"mx-auto max-w-lg space-y-6\">\n <p className=\"text-sm text-gray-500\">\n Set up your first company to get started.\n </p>\n\n {error && (\n <div className=\"rounded-md bg-red-50 p-4 text-sm text-red-700\">\n {error.message ?? \"An error occurred during setup\"}\n </div>\n )}\n\n <Card>\n <div className=\"space-y-4\">\n <Input\n label=\"Company Name\"\n value={companyName}\n onChange={(e) => setCompanyName(e.target.value)}\n placeholder=\"e.g. My Company Ltd\"\n required\n />\n <Select\n label=\"Currency\"\n options={CURRENCY_OPTIONS}\n value={currency}\n onChange={(e) => setCurrency(e.target.value)}\n />\n\n <fieldset className=\"space-y-3\">\n <legend className=\"mb-1 text-sm font-medium text-gray-700\">\n Company details\n </legend>\n <p className=\"text-xs text-gray-500\">\n These appear on your invoices and other PDFs. Optional now — you can\n fill or change them later under Masters → Company.\n </p>\n <Input label=\"Address\" value={details.address} onChange={setDetail(\"address\")}\n placeholder=\"e.g. 42 Market Street\" />\n <div className=\"grid grid-cols-2 gap-3\">\n <Input label=\"City\" value={details.city} onChange={setDetail(\"city\")} />\n <Input label=\"ZIP / Postal code\" value={details.zip_code} onChange={setDetail(\"zip_code\")} />\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <Input label=\"Country\" value={details.country} onChange={setDetail(\"country\")} />\n <Input label=\"Tax ID / VAT\" value={details.tax_id} onChange={setDetail(\"tax_id\")} />\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <Input label=\"Email\" value={details.email} onChange={setDetail(\"email\")} />\n <Input label=\"Phone\" value={details.phone} onChange={setDetail(\"phone\")} />\n </div>\n </fieldset>\n\n <fieldset className=\"space-y-2\">\n <legend className=\"mb-1 text-sm font-medium text-gray-700\">\n Seed data\n </legend>\n <label className=\"flex cursor-pointer items-start gap-3 rounded-md border border-gray-200 p-3 hover:bg-gray-50\">\n <input\n type=\"radio\"\n name=\"seed-mode\"\n value=\"quick\"\n checked={seedMode === \"quick\"}\n onChange={() => setSeedMode(\"quick\")}\n className=\"mt-1\"\n />\n <div>\n <div className=\"text-sm font-medium text-gray-900\">Quick demo</div>\n <div className=\"text-xs text-gray-500\">\n Customers, suppliers, items, one warehouse. No transactions.\n </div>\n </div>\n </label>\n <label className=\"flex cursor-pointer items-start gap-3 rounded-md border border-gray-200 p-3 hover:bg-gray-50\">\n <input\n type=\"radio\"\n name=\"seed-mode\"\n value=\"history\"\n checked={seedMode === \"history\"}\n onChange={() => setSeedMode(\"history\")}\n className=\"mt-1\"\n />\n <div>\n <div className=\"text-sm font-medium text-gray-900\">\n Simulate 3 years of history\n </div>\n <div className=\"text-xs text-gray-500\">\n Walks business days (skips weekends + US holidays) and generates\n quotations, orders, deliveries, invoices, payments, and\n reorder-driven purchasing. Seasonality + YoY growth baked in.\n Takes ~3 minutes.\n </div>\n </div>\n </label>\n <label className=\"flex cursor-pointer items-start gap-3 rounded-md border border-gray-200 p-3 hover:bg-gray-50\">\n <input\n type=\"radio\"\n name=\"seed-mode\"\n value=\"none\"\n checked={seedMode === \"none\"}\n onChange={() => setSeedMode(\"none\")}\n className=\"mt-1\"\n />\n <div>\n <div className=\"text-sm font-medium text-gray-900\">\n Create empty company, no demo data\n </div>\n <div className=\"text-xs text-gray-500\">\n Just the company and its chart of accounts. Add your own\n customers, suppliers, items, and transactions from scratch.\n </div>\n </div>\n </label>\n </fieldset>\n\n <div className=\"pt-2\">\n <Button\n onClick={handleSetup}\n disabled={isPending || !companyName.trim()}\n >\n {isPending\n ? seedMode === \"history\"\n ? \"Simulating three years...\"\n : \"Setting up...\"\n : seedMode === \"history\"\n ? \"Create Company & Simulate History\"\n : seedMode === \"quick\"\n ? \"Create Company & Seed Demo Data\"\n : \"Create Company\"}\n </Button>\n </div>\n </div>\n </Card>\n </div>\n );\n}\n\nfunction CompanyRow({ company }: { company: Record<string, any> }) {\n const cityCountry = [\n [company.city, company.zip_code].filter(Boolean).join(\" \"),\n company.country,\n ].filter(Boolean).join(\", \");\n return (\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0 space-y-1\">\n <div className=\"font-medium text-gray-900\">\n {company.company_name || company.name}\n </div>\n <dl className=\"grid grid-cols-[auto,1fr] gap-x-3 gap-y-0.5 text-xs text-gray-500\">\n {company.address && (\n <>\n <dt className=\"text-gray-400\">Address</dt>\n <dd className=\"text-gray-700\">{company.address}</dd>\n </>\n )}\n {cityCountry && (\n <>\n <dt className=\"text-gray-400\">Location</dt>\n <dd className=\"text-gray-700\">{cityCountry}</dd>\n </>\n )}\n {company.email && (\n <>\n <dt className=\"text-gray-400\">Email</dt>\n <dd className=\"truncate text-gray-700\">\n <a\n href={`mailto:${company.email}`}\n className=\"text-blue-600 hover:text-blue-800\"\n >\n {company.email}\n </a>\n </dd>\n </>\n )}\n {company.phone && (\n <>\n <dt className=\"text-gray-400\">Phone</dt>\n <dd className=\"text-gray-700\">{company.phone}</dd>\n </>\n )}\n {company.tax_id && (\n <>\n <dt className=\"text-gray-400\">Tax ID</dt>\n <dd className=\"font-mono text-gray-700\">{company.tax_id}</dd>\n </>\n )}\n </dl>\n </div>\n {company.default_currency && (\n <span className=\"shrink-0 rounded-full bg-gray-100 px-2 py-0.5 text-xs font-medium text-gray-600\">\n {company.default_currency}\n </span>\n )}\n </div>\n );\n}\n","import { Link, useNavigate } from \"react-router-dom\";\nimport { useTranslation } from \"react-i18next\";\nimport { Card } from \"@/components/ui/card\";\nimport { useChat } from \"@/components/chat/chat-provider\";\n\ninterface StepLink {\n to: string;\n label: string;\n}\n\ninterface Step {\n number: number;\n title: string;\n description: string;\n tip?: string;\n link?: string;\n linkLabel?: string;\n links?: StepLink[];\n}\n\nconst STEPS: Step[] = [\n {\n number: 1,\n title: \"Set Up Your Company\",\n description:\n \"Create a company with a base currency. This generates your Chart of Accounts (30 standard accounts across Assets, Liabilities, Equity, Income, and Expenses) and a default Cost Center. You can also seed demo data with sample customers, suppliers, and items to get started quickly.\",\n link: \"/setup\",\n linkLabel: \"Go to Setup\",\n },\n {\n number: 2,\n title: \"Create Master Data\",\n description:\n \"Before you can transact, you need master records. Create at least one Customer, one Supplier, one Item (with a standard rate), and one Warehouse. If you seeded demo data in Step 1, these already exist.\",\n tip: \"Items have a standard rate that auto-fills when you add them to documents. You can always override the rate per transaction.\",\n links: [\n { to: \"/masters/customer\", label: \"Customers\" },\n { to: \"/masters/supplier\", label: \"Suppliers\" },\n { to: \"/masters/item\", label: \"Items\" },\n { to: \"/masters/warehouse\", label: \"Warehouses\" },\n ],\n },\n {\n number: 3,\n title: \"Create a Quotation\",\n description:\n \"A Quotation is a non-binding offer to a customer. Select a customer, add line items with quantities and rates, optionally add tax rows, then save. Quotations have no financial impact \\u2014 they don't create accounting or stock entries. Set a validity date so the offer expires automatically.\",\n link: \"/app/quotation/new\",\n linkLabel: \"New Quotation\",\n },\n {\n number: 4,\n title: \"Submit and Convert to Sales Order\",\n description:\n \"Open your saved Quotation and click Submit to confirm it. Then click \\u201cCreate Sales Order\\u201d to convert it. The Sales Order represents a confirmed commitment from the customer. It still has no financial impact, but it reserves stock for planning purposes.\",\n tip: \"Only submitted documents can be converted to the next step. Draft \\u2192 Submit \\u2192 Convert is the standard flow. For quick deals, you can skip the Sales Order and go directly from Quotation to Sales Invoice or Delivery Note.\",\n link: \"/app/quotation\",\n linkLabel: \"View Quotations\",\n },\n {\n number: 5,\n title: \"Check Stock Before Fulfilling\",\n description:\n \"Before you can deliver, check if you actually have the item in stock. Go to the Stock Balance report and look up the item. If your warehouse has zero quantity, you\\u2019ll need to bring stock in first \\u2014 either through a Purchase Order (buying from a supplier) or a Stock Entry (manual receipt).\",\n tip: \"This is a common real-world scenario: you sell something, then realize you need to buy it first. The ERP handles both flows.\",\n link: \"/reports/stock-balance\",\n linkLabel: \"Stock Balance\",\n },\n {\n number: 6,\n title: \"Purchase Cycle: Buy Stock from a Supplier\",\n description:\n \"If you need to buy stock, you have two valid paths. The standard path is Purchase Order -> Purchase Receipt -> Purchase Invoice: use this when goods arrive before or separately from the supplier bill. If the bill and receipt happen together, you can create the Purchase Invoice directly and enable Update Stock so the same document both receives inventory and records Accounts Payable.\",\n tip: \"Use Purchase Receipt first when receiving goods separately. Use Purchase Invoice with Update Stock when one step should both receive stock and book the supplier bill. In that direct path, set a warehouse on each stock item row.\",\n links: [\n { to: \"/app/purchase-order/new\", label: \"New Purchase Order\" },\n { to: \"/app/purchase-receipt\", label: \"Purchase Receipts\" },\n { to: \"/app/purchase-invoice\", label: \"Purchase Invoices\" },\n ],\n },\n {\n number: 7,\n title: \"Create a Delivery Note\",\n description:\n \"Now that you have stock, go back to your submitted Sales Order and click \\u201cCreate Delivery Note.\\u201d Set the warehouse on each item row (where the goods ship from), then submit. This moves inventory out of the warehouse \\u2014 your stock balance decreases.\",\n tip: \"The Delivery Note is the shipping document. It reduces stock but doesn\\u2019t create an invoice. You can deliver and invoice separately.\",\n link: \"/app/delivery-note\",\n linkLabel: \"Delivery Notes\",\n },\n {\n number: 8,\n title: \"Create and Submit the Sales Invoice\",\n description:\n \"From the submitted Sales Order, create a Sales Invoice. When you submit the invoice, GL entries are posted: Accounts Receivable is debited (the customer owes you) and Sales Revenue is credited (income earned). If taxes are configured, Tax Payable is also credited. The outstanding amount shows what the customer still owes.\",\n link: \"/app/sales-invoice\",\n linkLabel: \"Sales Invoices\",\n },\n {\n number: 9,\n title: \"Record Customer Payments\",\n description:\n \"Create a Payment Entry to record money received from the customer. Set the payment type to \\u201cReceive,\\u201d select the customer, specify the amount, and allocate it against the Sales Invoice. You can make partial payments \\u2014 the invoice\\u2019s outstanding amount updates accordingly. Create additional Payment Entries until the invoice is fully paid.\",\n tip: \"Partial payments are common. A 10,000 invoice might be paid as 3,000 now and 7,000 later. Each Payment Entry reduces the outstanding amount.\",\n link: \"/app/payment-entry/new\",\n linkLabel: \"New Payment Entry\",\n },\n {\n number: 10,\n title: \"Stock Entries (Manual Inventory)\",\n description:\n \"Use Stock Entries for inventory movements that aren\\u2019t tied to purchases or sales. Material Receipt adds stock (opening balances, adjustments). Material Issue removes stock (write-offs, internal consumption). Material Transfer moves stock between warehouses. Each entry updates the stock ledger with moving-average valuation.\",\n tip: \"For purchased goods, use Purchase Receipts instead of Stock Entries \\u2014 they link to the Purchase Order and give you a proper audit trail.\",\n link: \"/app/stock-entry/new\",\n linkLabel: \"New Stock Entry\",\n },\n {\n number: 11,\n title: \"Journal Entries\",\n description:\n \"Journal Entries are manual accounting adjustments \\u2014 expense accruals, corrections, reclassifications, opening balances. Each entry must have balanced debits and credits (total debit = total credit). Use these when no other document type fits.\",\n link: \"/app/journal-entry/new\",\n linkLabel: \"New Journal Entry\",\n },\n {\n number: 12,\n title: \"Salary Payments\",\n description:\n \"Lambda ERP handles salaries through the existing accounting tools. First, accrue the salary expense: create a Journal Entry that debits Salary Expense and credits Salary Payable for the total payroll amount. Then pay the employees: create another Journal Entry (or Payment Entry) that debits Salary Payable and credits your bank account. This two-step process keeps your books accurate \\u2014 the expense is recorded in the right period, and the cash outflow is tracked separately.\",\n tip: \"You can ask the AI assistant to do this for you: \\u201cAccrue 15,000 in salaries for April\\u201d followed by \\u201cPay the April salaries from bank.\\u201d It will create the right journal entries automatically.\",\n link: \"/app/journal-entry/new\",\n linkLabel: \"New Journal Entry\",\n },\n {\n number: 13,\n title: \"Returns and Credit Notes\",\n description:\n \"When a customer returns goods or you need to issue a credit, create a return. Returns use the same document type with negative quantities. Open a submitted Sales Invoice and create a Credit Note (Sales Invoice return) \\u2014 this reverses the GL entries and reduces the original invoice\\u2019s outstanding amount. For stock, create a Delivery Note return to bring goods back into the warehouse. On the buying side, create a Debit Note (Purchase Invoice return) to reverse a supplier bill, or a Purchase Receipt return to send goods back.\",\n tip: \"A Credit Note is just a Sales Invoice with is_return=1 and negative quantities. The same GL logic runs \\u2014 negative amounts automatically flip to the correct debit/credit sides. For a full sales return, you need both a Credit Note (financials) and a Delivery Note return (stock).\",\n links: [\n { to: \"/app/sales-invoice\", label: \"Sales Invoices\" },\n { to: \"/app/delivery-note\", label: \"Delivery Notes\" },\n { to: \"/app/purchase-invoice\", label: \"Purchase Invoices\" },\n ],\n },\n {\n number: 14,\n title: \"Run Reports\",\n description:\n \"Check your books. The Profit & Loss shows income vs expenses and net profit for a period. The Balance Sheet shows your financial position (assets = liabilities + equity). AR Aging shows who owes you money and how overdue it is. AP Aging shows what you owe suppliers. The Trial Balance verifies double-entry integrity. The General Ledger shows every individual posting. Stock Balance shows current inventory.\",\n links: [\n { to: \"/reports/profit-and-loss\", label: \"Profit & Loss\" },\n { to: \"/reports/balance-sheet\", label: \"Balance Sheet\" },\n { to: \"/reports/ar-aging\", label: \"AR Aging\" },\n { to: \"/reports/ap-aging\", label: \"AP Aging\" },\n { to: \"/reports/trial-balance\", label: \"Trial Balance\" },\n { to: \"/reports/general-ledger\", label: \"General Ledger\" },\n { to: \"/reports/stock-balance\", label: \"Stock Balance\" },\n ],\n },\n {\n number: 15,\n title: \"Working in Foreign Currencies\",\n description:\n \"Your books are kept in a single base currency (chosen at company setup), but you can transact in any currency. Set a currency on an invoice or bill — or give a customer or supplier a default currency — and the exchange rate for that date is looked up automatically and stored on the document. The document keeps its amounts in its own currency, while the General Ledger always posts in your base currency. When you later collect or pay at a different rate, the realized exchange gain or loss is booked automatically to an Exchange Gain/Loss account. You can even hold a foreign-currency bank balance and convert it later at your bank’s rate — the difference versus its carried value is realized then. At month end you can revalue open foreign balances to the closing rate (an unrealized gain/loss that reverses next period), and you can view any financial statement translated into another currency for display.\",\n tip: \"This is easiest through the AI chat — try “Create a sales invoice for Lumiere Audio in EUR,” “Show me the balance sheet in EUR,” or “What’s our unrealized FX exposure at month end?” The seeded demo already includes a EUR customer (Lumiere Audio SARL) whose invoice was collected at a different rate, plus an open EUR supplier bill — open the General Ledger to see the realized FX postings.\",\n links: [\n { to: \"/chat\", label: \"Open AI Chat\" },\n { to: \"/app/sales-invoice\", label: \"Sales Invoices\" },\n { to: \"/reports/general-ledger\", label: \"General Ledger\" },\n ],\n },\n];\n\n// Launch the chat with a prefilled message (reuses an existing session or\n// creates one), mirroring the analytics \"try in chat\" flow.\nfunction useTryInChat() {\n const navigate = useNavigate();\n const { sessions, createSession } = useChat();\n return async (prefill: string) => {\n let targetSessionId = sessions[0]?.id || \"\";\n if (!targetSessionId) {\n try {\n const created = await createSession();\n targetSessionId = created.id;\n } catch {\n navigate(\"/chat\");\n return;\n }\n }\n navigate(`/chat/${targetSessionId}`, { state: { prefillMessage: prefill } });\n };\n}\n\nfunction CompanySetupHighlight() {\n const { t } = useTranslation();\n const tryInChat = useTryInChat();\n\n return (\n <Card className=\"border-emerald-200 bg-gradient-to-br from-emerald-50 to-white\">\n <div className=\"flex flex-col gap-4 md:flex-row md:items-start\">\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-emerald-100 text-lg font-bold text-emerald-700\">\n ▶\n </div>\n <div className=\"flex-1 space-y-3\">\n <div>\n <p className=\"text-xs uppercase tracking-wider text-emerald-700\">\n {t(\"tutorial.setupBadge\")}\n </p>\n <h3 className=\"mt-0.5 text-lg font-semibold text-gray-900\">\n {t(\"tutorial.setupTitle\")}\n </h3>\n </div>\n <p className=\"text-sm leading-relaxed text-gray-700\">\n {t(\"tutorial.setupBody\")}\n </p>\n <p className=\"text-xs leading-relaxed text-gray-500\">\n {t(\"tutorial.setupSectors\")}\n </p>\n <div className=\"flex flex-wrap items-center gap-4 pt-1\">\n <button\n type=\"button\"\n onClick={() => tryInChat(t(\"tutorial.setupPrompt\"))}\n className=\"inline-flex items-center gap-2 rounded-lg bg-emerald-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-emerald-700\"\n >\n {t(\"tutorial.setupGetStarted\")} →\n </button>\n <span className=\"text-xs text-gray-500\">\n {t(\"tutorial.setupManual\")}{\" \"}\n <Link to=\"/setup\" className=\"font-medium text-emerald-700 hover:text-emerald-900\">\n {t(\"tutorial.setupManualLink\")} →\n </Link>\n </span>\n </div>\n </div>\n </div>\n </Card>\n );\n}\n\nfunction CustomAnalyticsHighlight() {\n const { t } = useTranslation();\n const tryInChat = useTryInChat();\n\n const samplePrompts = [\n t(\"tutorial.caPrompt1\"),\n t(\"tutorial.caPrompt2\"),\n t(\"tutorial.caPrompt3\"),\n t(\"tutorial.caPrompt4\"),\n ];\n\n return (\n <Card className=\"border-indigo-200 bg-gradient-to-br from-indigo-50 to-white\">\n <div className=\"flex flex-col gap-4 md:flex-row md:items-start\">\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-indigo-100 text-lg font-bold text-indigo-700\">\n ★\n </div>\n <div className=\"flex-1 space-y-3\">\n <div>\n <h3 className=\"text-base font-semibold text-gray-900\">\n {t(\"tutorial.caTitle\")}\n </h3>\n <p className=\"mt-1 text-xs uppercase tracking-wider text-indigo-700\">\n {t(\"tutorial.caBadge\")}\n </p>\n </div>\n <p className=\"text-sm leading-relaxed text-gray-700\">\n {t(\"tutorial.caBody\")}\n </p>\n <div className=\"rounded-md border border-indigo-100 bg-white px-3 py-2 text-xs text-gray-600\">\n <div className=\"mb-1 font-medium text-gray-800\">{t(\"tutorial.caTryAsking\")}</div>\n <ul className=\"space-y-0.5\">\n {samplePrompts.map((prompt) => (\n <li key={prompt}>\n <button\n type=\"button\"\n onClick={() => tryInChat(prompt)}\n className=\"text-left text-indigo-700 hover:text-indigo-900 hover:underline\"\n >\n “{prompt}”\n </button>\n </li>\n ))}\n </ul>\n </div>\n <div className=\"flex flex-wrap gap-3 pt-1\">\n <button\n type=\"button\"\n onClick={() => tryInChat(samplePrompts[2])}\n className=\"text-sm font-medium text-indigo-700 hover:text-indigo-900\"\n >\n {t(\"tutorial.caTryInChat\")} →\n </button>\n <Link\n to=\"/reports/analytics\"\n className=\"text-sm font-medium text-indigo-700 hover:text-indigo-900\"\n >\n {t(\"tutorial.caOpenWorkspace\")} →\n </Link>\n </div>\n </div>\n </div>\n </Card>\n );\n}\n\nfunction FlowDiagram() {\n const { t } = useTranslation();\n const chip = (k: string) => t(`tutorial.chips.${k}`, { defaultValue: k });\n return (\n <Card>\n <h3 className=\"text-base font-semibold text-gray-900 mb-3\">\n {t(\"tutorial.flowTitle\")}\n </h3>\n <div className=\"space-y-4 text-sm text-gray-600\">\n <div>\n <div className=\"font-medium text-gray-800 mb-1\">{t(\"tutorial.salesCycle\")}</div>\n <div className=\"flex flex-wrap items-center gap-1 font-mono text-xs\">\n <span className=\"rounded bg-blue-50 px-2 py-0.5 text-blue-700\">{chip(\"Quotation\")}</span>\n <span className=\"text-gray-400\">→</span>\n <span className=\"rounded bg-blue-50 px-2 py-0.5 text-blue-700\">{chip(\"Sales Order\")}</span>\n <span className=\"text-gray-400\">→</span>\n <span className=\"rounded bg-green-50 px-2 py-0.5 text-green-700\">{chip(\"Delivery Note\")}</span>\n <span className=\"text-gray-300\">/</span>\n <span className=\"rounded bg-amber-50 px-2 py-0.5 text-amber-700\">{chip(\"Sales Invoice\")}</span>\n <span className=\"text-gray-400\">→</span>\n <span className=\"rounded bg-purple-50 px-2 py-0.5 text-purple-700\">{chip(\"Payment Entry\")}</span>\n </div>\n <div className=\"mt-1 text-xs text-gray-400 italic\">\n {t(\"tutorial.flowShortcut\")}\n </div>\n </div>\n <div>\n <div className=\"font-medium text-gray-800 mb-1\">{t(\"tutorial.purchaseCycle\")}</div>\n <div className=\"flex flex-wrap items-center gap-1 font-mono text-xs\">\n <span className=\"rounded bg-blue-50 px-2 py-0.5 text-blue-700\">{chip(\"Purchase Order\")}</span>\n <span className=\"text-gray-400\">→</span>\n <span className=\"rounded bg-green-50 px-2 py-0.5 text-green-700\">{chip(\"Purchase Receipt\")}</span>\n <span className=\"text-gray-300\">/</span>\n <span className=\"rounded bg-amber-50 px-2 py-0.5 text-amber-700\">{chip(\"Purchase Invoice\")}</span>\n <span className=\"text-gray-400\">→</span>\n <span className=\"rounded bg-purple-50 px-2 py-0.5 text-purple-700\">{chip(\"Payment Entry\")}</span>\n </div>\n </div>\n <div>\n <div className=\"font-medium text-gray-800 mb-1\">{t(\"tutorial.returns\")}</div>\n <div className=\"flex flex-wrap items-center gap-1 font-mono text-xs\">\n <span className=\"rounded bg-amber-50 px-2 py-0.5 text-amber-700\">{chip(\"Sales Invoice\")}</span>\n <span className=\"text-gray-400\">→</span>\n <span className=\"rounded bg-red-50 px-2 py-0.5 text-red-700\">{chip(\"Credit Note\")}</span>\n <span className=\"mx-2 text-gray-300\">|</span>\n <span className=\"rounded bg-green-50 px-2 py-0.5 text-green-700\">{chip(\"Delivery Note\")}</span>\n <span className=\"text-gray-400\">→</span>\n <span className=\"rounded bg-red-50 px-2 py-0.5 text-red-700\">{chip(\"DN Return\")}</span>\n <span className=\"mx-2 text-gray-300\">|</span>\n <span className=\"rounded bg-amber-50 px-2 py-0.5 text-amber-700\">{chip(\"Purchase Invoice\")}</span>\n <span className=\"text-gray-400\">→</span>\n <span className=\"rounded bg-red-50 px-2 py-0.5 text-red-700\">{chip(\"Debit Note\")}</span>\n </div>\n </div>\n <div className=\"border-t pt-3 text-xs text-gray-500\">\n <span className=\"rounded bg-green-50 px-1.5 py-0.5 text-green-700\">Green</span> = {t(\"tutorial.legendStock\")},{\" \"}\n <span className=\"rounded bg-amber-50 px-1.5 py-0.5 text-amber-700\">Amber</span> = {t(\"tutorial.legendGl\")},{\" \"}\n <span className=\"rounded bg-purple-50 px-1.5 py-0.5 text-purple-700\">Purple</span> = {t(\"tutorial.legendCash\")},{\" \"}\n <span className=\"rounded bg-red-50 px-1.5 py-0.5 text-red-700\">Red</span> = {t(\"tutorial.legendReversal\")}\n </div>\n </div>\n </Card>\n );\n}\n\nfunction LifecycleCard() {\n const { t } = useTranslation();\n const chip = (k: string) => t(`tutorial.chips.${k}`, { defaultValue: k });\n return (\n <Card>\n <h3 className=\"text-base font-semibold text-gray-900 mb-3\">\n {t(\"tutorial.lifecycleTitle\")}\n </h3>\n <div className=\"space-y-2 text-sm text-gray-600\">\n <div className=\"flex flex-wrap items-center gap-2 font-mono text-xs\">\n <span className=\"rounded bg-gray-100 px-2 py-0.5 text-gray-600\">{chip(\"Draft\")}</span>\n <span className=\"text-gray-400\">→ save()</span>\n <span className=\"rounded bg-gray-100 px-2 py-0.5 text-gray-600\">{chip(\"Draft\")}</span>\n <span className=\"text-gray-400\">→ submit()</span>\n <span className=\"rounded bg-blue-100 px-2 py-0.5 text-blue-700\">{chip(\"Submitted\")}</span>\n <span className=\"text-gray-400\">→ cancel()</span>\n <span className=\"rounded bg-red-100 px-2 py-0.5 text-red-700\">{chip(\"Cancelled\")}</span>\n </div>\n <ul className=\"list-disc pl-5 space-y-1 text-xs text-gray-500\">\n <li><strong>{t(\"tutorial.lcDraftLabel\")}</strong> {t(\"tutorial.lcDraftDesc\")}</li>\n <li><strong>{t(\"tutorial.lcSubmittedLabel\")}</strong> {t(\"tutorial.lcSubmittedDesc\")}</li>\n <li><strong>{t(\"tutorial.lcCancelledLabel\")}</strong> {t(\"tutorial.lcCancelledDesc\")}</li>\n <li>{t(\"tutorial.lcNoDelete\")}</li>\n <li>{t(\"tutorial.lcCorrect\")}</li>\n </ul>\n </div>\n </Card>\n );\n}\n\nexport default function TutorialPage() {\n const { t } = useTranslation();\n return (\n <div className=\"mx-auto max-w-3xl space-y-6\">\n <div>\n <h2 className=\"text-xl font-semibold text-gray-900\">\n {t(\"tutorial.pageTitle\")}\n </h2>\n <p className=\"mt-1 text-sm text-gray-500\">\n {t(\"tutorial.intro\")}\n </p>\n <Link\n to=\"/chat\"\n className=\"mt-3 inline-flex items-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-700\"\n >\n {t(\"tutorial.openChat\")} →\n </Link>\n <p className=\"mt-4 rounded-lg border border-blue-200 bg-blue-50 px-4 py-3 text-sm text-blue-800\">\n <strong>{t(\"tutorial.tipLabel\")}</strong> {t(\"tutorial.topTip\")}\n </p>\n <p className=\"mt-4 text-sm text-gray-500\">\n {t(\"tutorial.manualIntro\")}\n </p>\n </div>\n\n <CompanySetupHighlight />\n <CustomAnalyticsHighlight />\n <FlowDiagram />\n <LifecycleCard />\n\n {STEPS.map((step) => (\n <Card key={step.number}>\n <div className=\"flex gap-4\">\n <div className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-blue-100 text-sm font-bold text-blue-700\">\n {step.number}\n </div>\n <div className=\"space-y-2\">\n <h3 className=\"text-base font-semibold text-gray-900\">\n {t(`tutorial.steps.${step.number}.title`, { defaultValue: step.title })}\n </h3>\n <p className=\"text-sm leading-relaxed text-gray-600\">\n {t(`tutorial.steps.${step.number}.description`, { defaultValue: step.description })}\n </p>\n {step.tip && (\n <p className=\"text-xs leading-relaxed text-amber-700 bg-amber-50 rounded px-3 py-2\">\n <strong>{t(\"tutorial.tipLabel\")}</strong> {t(`tutorial.steps.${step.number}.tip`, { defaultValue: step.tip })}\n </p>\n )}\n <div className=\"flex flex-wrap gap-3 pt-1\">\n {step.link && step.linkLabel && (\n <Link\n to={step.link}\n className=\"text-sm font-medium text-blue-600 hover:text-blue-800\"\n >\n {t(`tutorial.links.${step.linkLabel}`, { defaultValue: step.linkLabel })} →\n </Link>\n )}\n {step.links?.map((l) => (\n <Link\n key={l.to}\n to={l.to}\n className=\"text-sm font-medium text-blue-600 hover:text-blue-800\"\n >\n {t(`tutorial.links.${l.label}`, { defaultValue: l.label })} →\n </Link>\n ))}\n </div>\n </div>\n </div>\n </Card>\n ))}\n\n <Card>\n <div className=\"flex gap-4\">\n <div className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-green-100 text-sm font-bold text-green-700\">\n ✓\n </div>\n <div className=\"space-y-2\">\n <h3 className=\"text-base font-semibold text-gray-900\">\n {t(\"tutorial.readyTitle\")}\n </h3>\n <p className=\"text-sm leading-relaxed text-gray-600\">\n {t(\"tutorial.readyBody1\")}\n </p>\n <p className=\"text-sm leading-relaxed text-gray-600\">\n {t(\"tutorial.readyBody2\")}\n </p>\n <Link\n to=\"/chat\"\n className=\"inline-block text-sm font-medium text-blue-600 hover:text-blue-800\"\n >\n {t(\"tutorial.openChat\")} →\n </Link>\n </div>\n </div>\n </Card>\n </div>\n );\n}\n","import { useState, useEffect, useLayoutEffect, useRef, useCallback } from \"react\";\nimport { Link, useParams, useNavigate, useSearchParams, useLocation } from \"react-router-dom\";\nimport { type ChatMessage, type ChatAttachment, useChat, rememberSessionId } from \"@/components/chat/chat-provider\";\nimport { api } from \"@/api/client\";\nimport { useTranslation } from \"react-i18next\";\n\nconst MAX_ATTACHMENTS = 5;\nconst MAX_ATTACHMENT_SIZE = 10 * 1024 * 1024;\nconst ALLOWED_MIMES = new Set([\n \"image/png\", \"image/jpeg\", \"image/gif\", \"image/webp\", \"application/pdf\",\n // Spreadsheets\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\", // xlsx\n \"application/vnd.ms-excel\", // xls\n \"application/vnd.oasis.opendocument.spreadsheet\", // ods\n // Documents\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\", // docx\n \"application/msword\", // doc\n \"application/vnd.oasis.opendocument.text\", // odt\n // Presentations\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\", // pptx\n \"application/vnd.ms-powerpoint\", // ppt\n \"application/vnd.oasis.opendocument.presentation\", // odp\n // Delimited / text\n \"text/csv\", \"text/plain\",\n]);\n\n// Some browsers/OSes hand us an empty or octet-stream type for Office files, so\n// the picker also accepts by extension (mirrors the server's extension fallback).\nconst ALLOWED_EXTS = new Set([\n \"png\", \"jpg\", \"jpeg\", \"gif\", \"webp\", \"pdf\",\n \"xlsx\", \"xls\", \"ods\", \"docx\", \"doc\", \"odt\", \"pptx\", \"ppt\", \"odp\", \"csv\", \"txt\",\n]);\n\ninterface PendingAttachment {\n localId: string;\n file: File;\n previewUrl?: string;\n uploadedId?: string;\n uploading: boolean;\n error?: string;\n}\n\nfunction wait(ms: number): Promise<void> {\n return new Promise((resolve) => window.setTimeout(resolve, ms));\n}\n\n// Strip the `data:<mime>;base64,` prefix a FileReader data URL carries so we\n// send the server the bare base64 payload.\nfunction blobToBase64(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => {\n const result = typeof reader.result === \"string\" ? reader.result : \"\";\n resolve(result.includes(\",\") ? result.slice(result.indexOf(\",\") + 1) : result);\n };\n reader.onerror = () => reject(reader.error ?? new Error(\"Could not read audio.\"));\n reader.readAsDataURL(blob);\n });\n}\n\nfunction formatTime(ts?: string): string {\n if (!ts) return \"\";\n const d = new Date(ts);\n if (isNaN(d.getTime())) return \"\";\n\n const now = new Date();\n const sameDay =\n d.getFullYear() === now.getFullYear() &&\n d.getMonth() === now.getMonth() &&\n d.getDate() === now.getDate();\n\n if (sameDay) {\n return d.toLocaleTimeString([], { hour: \"2-digit\", minute: \"2-digit\" });\n }\n\n const sameYear = d.getFullYear() === now.getFullYear();\n if (sameYear) {\n return d.toLocaleDateString([], { day: \"numeric\", month: \"short\" });\n }\n\n return d.toLocaleDateString([], { day: \"numeric\", month: \"short\", year: \"numeric\" });\n}\n\nfunction formatFullTimestamp(ts?: string): string {\n if (!ts) return \"\";\n const d = new Date(ts);\n if (isNaN(d.getTime())) return \"\";\n return d.toLocaleString([], {\n year: \"numeric\", month: \"short\", day: \"numeric\",\n hour: \"2-digit\", minute: \"2-digit\", second: \"2-digit\",\n timeZoneName: \"short\",\n });\n}\n\nexport default function ChatPage() {\n const { t } = useTranslation();\n const { sessionId } = useParams<{ sessionId: string }>();\n const navigate = useNavigate();\n const location = useLocation();\n const [searchParams] = useSearchParams();\n const demoRequested = searchParams.get(\"demo\") === \"1\";\n const [input, setInput] = useState(\"\");\n const [demoError, setDemoError] = useState(\"\");\n const [attachments, setAttachments] = useState<PendingAttachment[]>([]);\n const [attachmentError, setAttachmentError] = useState(\"\");\n const [isDragOver, setIsDragOver] = useState(false);\n // Voice → text: \"idle\" (mic ready), \"recording\" (capturing), \"transcribing\"\n // (waiting on the server). Click toggles record on/off.\n const [voiceState, setVoiceState] = useState<\"idle\" | \"recording\" | \"transcribing\">(\"idle\");\n const fileInputRef = useRef<HTMLInputElement>(null);\n const mediaRecorderRef = useRef<MediaRecorder | null>(null);\n const audioChunksRef = useRef<Blob[]>([]);\n const {\n connectionStatus,\n connectionVersion,\n createSession,\n startDemo,\n completeDemoTyping,\n loadHistory,\n loadMoreHistory,\n sendMessage,\n transcribeAudio,\n getMessages,\n hasMoreHistory,\n isLoadingOlder,\n isThinking: getIsThinking,\n getDemoStatus,\n getDemoTypingCue,\n } = useChat();\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLTextAreaElement>(null);\n const inputAreaRef = useRef<HTMLDivElement>(null);\n const [inputAreaHeight, setInputAreaHeight] = useState(0);\n const previousThinkingRef = useRef(false);\n const demoRunStartedRef = useRef<string | null>(null);\n const demoTypingRunIdRef = useRef(0);\n const shouldAutoScrollRef = useRef(true);\n const pendingPrependHeightRef = useRef<number | null>(null);\n // True while we're driving the scroll ourselves (smooth-scroll animation\n // or ResizeObserver-driven pin-to-bottom). Scroll events fired by those\n // animations must NOT be interpreted as the user scrolling up, or else\n // shouldAutoScrollRef flips to false mid-animation and every subsequent\n // rescroll gets gated out.\n const programmaticScrollRef = useRef(false);\n const programmaticScrollTimerRef = useRef<number | null>(null);\n const messages = getMessages(sessionId);\n const isConnected = connectionStatus === \"connected\";\n const isThinking = getIsThinking(sessionId);\n const demoStatus = getDemoStatus(sessionId);\n const demoTypingCue = getDemoTypingCue(sessionId);\n const isDemoReplaying = demoRequested || demoStatus === \"running\";\n const canLoadOlder = hasMoreHistory(sessionId);\n const loadingOlder = isLoadingOlder(sessionId);\n\n const lastMessage = messages[messages.length - 1];\n const lastMessageKey = lastMessage\n ? `${lastMessage.type}:${lastMessage.timestamp || \"\"}:${lastMessage.content}`\n : \"empty\";\n\n // Flag programmatic scrolls so the onScroll handler doesn't interpret\n // the browser's mid-animation scroll events as \"user scrolled up\".\n // Refreshes the reset timer each call — a rescroll inside 600ms\n // keeps the flag on for the full animation + reflow window.\n const markProgrammaticScroll = useCallback(() => {\n programmaticScrollRef.current = true;\n if (programmaticScrollTimerRef.current !== null) {\n window.clearTimeout(programmaticScrollTimerRef.current);\n }\n programmaticScrollTimerRef.current = window.setTimeout(() => {\n programmaticScrollRef.current = false;\n programmaticScrollTimerRef.current = null;\n }, 600);\n }, []);\n\n const scrollToBottom = useCallback((behavior: ScrollBehavior = \"smooth\") => {\n const el = scrollContainerRef.current;\n if (!el) return;\n // Drive the container directly instead of relying on\n // scrollIntoView — it's more predictable for tall messages and\n // avoids quirks around the zero-height end-of-list marker.\n markProgrammaticScroll();\n el.scrollTo({ top: el.scrollHeight, behavior });\n // A tall, freshly-mounted assistant bubble (markdown tables, long\n // lists) can still reflow after the effect commits — re-check once\n // a frame later, and once more after ~100ms for stragglers like\n // late-rendered images or resize-observed blocks. If the user has\n // already scrolled up manually, leave them alone.\n const rescroll = () => {\n const current = scrollContainerRef.current;\n if (!current) return;\n if (!shouldAutoScrollRef.current && !isDemoReplaying && !isThinking) return;\n if (current.scrollTop + current.clientHeight >= current.scrollHeight - 2) return;\n markProgrammaticScroll();\n current.scrollTo({ top: current.scrollHeight, behavior: \"auto\" });\n };\n requestAnimationFrame(rescroll);\n window.setTimeout(rescroll, 120);\n }, [isDemoReplaying, isThinking, markProgrammaticScroll]);\n\n useLayoutEffect(() => {\n const el = scrollContainerRef.current;\n const prevHeight = pendingPrependHeightRef.current;\n if (!el || prevHeight === null) return;\n const delta = el.scrollHeight - prevHeight;\n if (delta > 0) {\n el.scrollTop = el.scrollTop + delta;\n }\n pendingPrependHeightRef.current = null;\n }, [messages.length]);\n\n useEffect(() => {\n if (pendingPrependHeightRef.current !== null) return;\n if (!shouldAutoScrollRef.current && !isDemoReplaying && !isThinking) return;\n scrollToBottom(isDemoReplaying ? \"auto\" : \"smooth\");\n }, [lastMessageKey, isDemoReplaying, isThinking, scrollToBottom]);\n\n // Chase any post-commit layout growth (markdown tables, late-rendered\n // links, web-font reflows, images finalising their box). ResizeObserver\n // fires whenever the scroll container's content box changes size; if the\n // user hasn't manually scrolled up, keep pinning the view to the bottom.\n useEffect(() => {\n const el = scrollContainerRef.current;\n if (!el || typeof ResizeObserver === \"undefined\") return;\n let raf = 0;\n const observer = new ResizeObserver(() => {\n if (pendingPrependHeightRef.current !== null) return;\n if (!shouldAutoScrollRef.current && !isDemoReplaying && !isThinking) return;\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(() => {\n const current = scrollContainerRef.current;\n if (!current) return;\n const distanceFromBottom =\n current.scrollHeight - current.scrollTop - current.clientHeight;\n // Only chase when we're already near the bottom — avoids yanking the\n // view when the user is scrolled up reading history.\n if (distanceFromBottom <= 120) {\n markProgrammaticScroll();\n current.scrollTo({ top: current.scrollHeight, behavior: \"auto\" });\n }\n });\n });\n // Observe the content wrapper so tall new bubbles trigger the callback.\n const content = el.firstElementChild;\n if (content) observer.observe(content);\n observer.observe(el);\n return () => {\n observer.disconnect();\n cancelAnimationFrame(raf);\n };\n }, [isDemoReplaying, isThinking, markProgrammaticScroll]);\n\n // Reserve bottom space in the scroll content equal to the floating input's\n // actual height so the tail of a long message never hides behind it. The\n // input height is variable (textarea auto-grows, attachment strip appears),\n // so measure it live instead of hardcoding the padding.\n useLayoutEffect(() => {\n const el = inputAreaRef.current;\n if (!el) return;\n setInputAreaHeight(el.offsetHeight);\n if (typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(() => setInputAreaHeight(el.offsetHeight));\n observer.observe(el);\n return () => observer.disconnect();\n }, []);\n\n const handleLoadOlder = useCallback(() => {\n if (!sessionId) return;\n if (loadingOlder || !canLoadOlder) return;\n const el = scrollContainerRef.current;\n pendingPrependHeightRef.current = el ? el.scrollHeight : null;\n shouldAutoScrollRef.current = false;\n void loadMoreHistory(sessionId).catch(() => {\n pendingPrependHeightRef.current = null;\n });\n }, [sessionId, loadingOlder, canLoadOlder, loadMoreHistory]);\n\n // Tracks the location.state object we've already consumed so the\n // StrictMode synthetic remount (and any later re-render with the same\n // state) doesn't double-apply or clobber the prefill.\n const consumedNavStateRef = useRef<unknown>(null);\n\n useEffect(() => {\n setDemoError(\"\");\n demoRunStartedRef.current = null;\n demoTypingRunIdRef.current += 1;\n // Remember that this browser participated in this chat, so the sidebar\n // keeps showing it even when the server-side filter hides demo-only\n // sessions for the shared public_manager account.\n if (sessionId) rememberSessionId(sessionId);\n\n const navState = location.state as { prefillMessage?: string } | null;\n if (navState?.prefillMessage && consumedNavStateRef.current !== navState) {\n consumedNavStateRef.current = navState;\n setInput(navState.prefillMessage);\n window.setTimeout(() => inputRef.current?.focus(), 50);\n } else if (!navState?.prefillMessage) {\n consumedNavStateRef.current = null;\n setInput(\"\");\n }\n }, [sessionId, demoRequested, location.state]);\n\n // If no sessionId, create one and redirect\n useEffect(() => {\n if (sessionId || !isConnected) return;\n\n let cancelled = false;\n createSession()\n .then((session) => {\n if (!cancelled) {\n navigate(`/chat/${session.id}`, { replace: true });\n }\n })\n .catch(() => {\n // ignore\n });\n\n return () => {\n cancelled = true;\n };\n }, [sessionId, isConnected, navigate]);\n\n const loadHistoryRef = useRef(loadHistory);\n useEffect(() => {\n loadHistoryRef.current = loadHistory;\n }, [loadHistory]);\n\n useEffect(() => {\n if (!sessionId || !isConnected) return;\n if (demoRequested || demoStatus === \"running\") return;\n void loadHistoryRef.current(sessionId).catch(() => {\n // ignore\n });\n }, [sessionId, isConnected, connectionVersion, demoRequested, demoStatus]);\n\n useEffect(() => {\n if (previousThinkingRef.current && !isThinking && isConnected) {\n setTimeout(() => inputRef.current?.focus(), 50);\n }\n previousThinkingRef.current = isThinking;\n }, [isThinking, isConnected]);\n\n function handleMessagesScroll(e: React.UIEvent<HTMLDivElement>) {\n // Ignore scroll events fired by our own programmatic scrolls —\n // mid-animation positions are meaningless for \"is the user reading\n // history?\" and flipping shouldAutoScrollRef mid-animation defeats\n // the whole auto-scroll chain.\n if (programmaticScrollRef.current) return;\n const el = e.currentTarget;\n const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight;\n shouldAutoScrollRef.current = distanceFromBottom < 80;\n }\n\n useEffect(() => {\n if (!sessionId || !isConnected || !demoRequested) return;\n if (demoRunStartedRef.current === sessionId) return;\n\n demoRunStartedRef.current = sessionId;\n setDemoError(\"\");\n void startDemo(sessionId).catch((err) => {\n demoRunStartedRef.current = null;\n setDemoError(err instanceof Error ? err.message : t(\"chat.demoError\"));\n });\n }, [sessionId, isConnected, demoRequested, startDemo]);\n\n useEffect(() => {\n if (!sessionId || !demoRequested || demoStatus !== \"complete\") return;\n setInput(\"\");\n navigate(`/chat/${sessionId}`, { replace: true });\n }, [sessionId, demoRequested, demoStatus, navigate]);\n\n const completeDemoTypingRef = useRef(completeDemoTyping);\n useEffect(() => {\n completeDemoTypingRef.current = completeDemoTyping;\n }, [completeDemoTyping]);\n\n const typedCueSeqRef = useRef<number | null>(null);\n useEffect(() => {\n if (!demoTypingCue || !sessionId) return;\n // Guard against re-runs for the same cue (provider re-renders recreate object refs)\n if (typedCueSeqRef.current === demoTypingCue.seq) return;\n typedCueSeqRef.current = demoTypingCue.seq;\n\n const targetSessionId = sessionId;\n const typingContent = demoTypingCue.content;\n const charDelay = typingContent.length > 0\n ? Math.max(8, demoTypingCue.typingMs / typingContent.length)\n : 0;\n const typingSeq = demoTypingCue.seq;\n\n const runId = ++demoTypingRunIdRef.current;\n\n async function animateTyping() {\n setInput(\"\");\n for (const char of typingContent) {\n if (runId !== demoTypingRunIdRef.current) return;\n setInput((prev) => prev + char);\n await wait(charDelay);\n }\n if (runId !== demoTypingRunIdRef.current) return;\n completeDemoTypingRef.current(targetSessionId, typingSeq);\n }\n\n void animateTyping();\n }, [demoTypingCue, sessionId]);\n\n useEffect(() => {\n if (demoStatus !== \"complete\") return;\n demoTypingRunIdRef.current += 1;\n setInput(\"\");\n }, [demoStatus]);\n\n const addFiles = useCallback((fileList: FileList | File[]) => {\n if (!sessionId) return;\n setAttachmentError(\"\");\n const incoming = Array.from(fileList);\n\n setAttachments((prev) => {\n const result = [...prev];\n for (const file of incoming) {\n if (result.length >= MAX_ATTACHMENTS) {\n setAttachmentError(`Maximum ${MAX_ATTACHMENTS} attachments per message.`);\n break;\n }\n const ext = file.name.includes(\".\") ? file.name.split(\".\").pop()!.toLowerCase() : \"\";\n if (!ALLOWED_MIMES.has(file.type) && !ALLOWED_EXTS.has(ext)) {\n setAttachmentError(`Unsupported file type: ${file.type || file.name}`);\n continue;\n }\n if (file.size > MAX_ATTACHMENT_SIZE) {\n setAttachmentError(`\"${file.name}\" is too large (max 10 MB).`);\n continue;\n }\n\n const localId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n const previewUrl = file.type.startsWith(\"image/\")\n ? URL.createObjectURL(file)\n : undefined;\n const pending: PendingAttachment = { localId, file, previewUrl, uploading: true };\n result.push(pending);\n\n // Fire upload\n api.uploadChatAttachment(sessionId, file)\n .then((res) => {\n setAttachments((current) =>\n current.map((a) =>\n a.localId === localId ? { ...a, uploading: false, uploadedId: res.id } : a,\n ),\n );\n })\n .catch((err) => {\n const msg = err?.message || \"Upload failed\";\n // Surface the server's detail (e.g. demo size cap) in the banner\n // so the user actually sees *why* — the pending tile only has\n // room for \"Failed\".\n setAttachmentError(`\"${file.name}\": ${msg}`);\n setAttachments((current) =>\n current.map((a) =>\n a.localId === localId ? { ...a, uploading: false, error: msg } : a,\n ),\n );\n });\n }\n return result;\n });\n }, [sessionId]);\n\n const removeAttachment = (localId: string) => {\n setAttachments((prev) => {\n const victim = prev.find((a) => a.localId === localId);\n if (victim?.previewUrl) URL.revokeObjectURL(victim.previewUrl);\n return prev.filter((a) => a.localId !== localId);\n });\n };\n\n // Drag-and-drop support on the chat area\n const handleDragOver = (e: React.DragEvent) => {\n if (e.dataTransfer.types.includes(\"Files\")) {\n e.preventDefault();\n setIsDragOver(true);\n }\n };\n const handleDragLeave = (e: React.DragEvent) => {\n // Only clear when the drag actually leaves the outer container, not when\n // moving over children. relatedTarget is null or outside when truly leaving.\n const related = e.relatedTarget as Node | null;\n if (!related || !(e.currentTarget as Node).contains(related)) {\n setIsDragOver(false);\n }\n };\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault();\n setIsDragOver(false);\n if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n addFiles(e.dataTransfer.files);\n }\n };\n\n // Paste image / PDF from clipboard\n const handlePaste = (e: React.ClipboardEvent) => {\n const files: File[] = [];\n for (const item of e.clipboardData.items) {\n if (item.kind === \"file\") {\n const f = item.getAsFile();\n if (f) files.push(f);\n }\n }\n if (files.length > 0) {\n e.preventDefault();\n addFiles(files);\n }\n };\n\n const hasUnfinishedUploads = attachments.some((a) => a.uploading);\n const hasFailedUploads = attachments.some((a) => a.error);\n const readyAttachmentIds = attachments\n .filter((a) => a.uploadedId && !a.error)\n .map((a) => a.uploadedId as string);\n\n function sendCurrentMessage() {\n const text = input.trim();\n if (!sessionId) return;\n if (!text && readyAttachmentIds.length === 0) return;\n if (hasUnfinishedUploads) return;\n if (!sendMessage(sessionId, text, readyAttachmentIds.length > 0 ? readyAttachmentIds : undefined)) return;\n // Clean up previews\n for (const att of attachments) {\n if (att.previewUrl) URL.revokeObjectURL(att.previewUrl);\n }\n setAttachments([]);\n setAttachmentError(\"\");\n setInput(\"\");\n }\n\n function handleKeyDown(e: React.KeyboardEvent) {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n sendCurrentMessage();\n }\n }\n\n // Append the transcript to whatever is already typed so a voice note adds to\n // the draft rather than replacing it. Returns the text trimmed/spaced.\n function appendTranscript(text: string) {\n const clean = text.trim();\n if (!clean) return;\n setInput((prev) => (prev.trim() ? `${prev.trim()} ${clean}` : clean));\n // Defer focus so the textarea has the new value when we resize it.\n window.setTimeout(() => {\n const el = inputRef.current;\n if (!el) return;\n el.focus();\n el.style.height = \"auto\";\n el.style.height = Math.min(Math.max(el.scrollHeight, 48), 120) + \"px\";\n }, 0);\n }\n\n async function startRecording() {\n if (voiceState !== \"idle\") return;\n let stream: MediaStream;\n try {\n stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n } catch {\n setAttachmentError(t(\"chat.micDenied\"));\n return;\n }\n\n setAttachmentError(\"\");\n const recorder = new MediaRecorder(stream);\n mediaRecorderRef.current = recorder;\n audioChunksRef.current = [];\n\n recorder.ondataavailable = (event) => {\n if (event.data.size > 0) audioChunksRef.current.push(event.data);\n };\n\n recorder.onstop = async () => {\n stream.getTracks().forEach((track) => track.stop());\n const chunks = audioChunksRef.current;\n audioChunksRef.current = [];\n mediaRecorderRef.current = null;\n if (chunks.length === 0) {\n setVoiceState(\"idle\");\n return;\n }\n const mimeType = recorder.mimeType || chunks[0]?.type || \"audio/webm\";\n const blob = new Blob(chunks, { type: mimeType });\n // \"audio/webm;codecs=opus\" → \"webm\"; the server only needs the container.\n const format = (mimeType.split(\";\")[0].split(\"/\")[1] || \"webm\").toLowerCase();\n\n setVoiceState(\"transcribing\");\n try {\n const base64 = await blobToBase64(blob);\n const text = await transcribeAudio(base64, format, sessionId);\n appendTranscript(text);\n } catch (error) {\n setAttachmentError(error instanceof Error ? error.message : t(\"chat.transcribeFailed\"));\n } finally {\n setVoiceState(\"idle\");\n }\n };\n\n recorder.start();\n setVoiceState(\"recording\");\n }\n\n function stopRecording() {\n const recorder = mediaRecorderRef.current;\n if (recorder && recorder.state !== \"inactive\") {\n recorder.stop();\n }\n }\n\n function toggleRecording() {\n if (voiceState === \"recording\") {\n stopRecording();\n } else if (voiceState === \"idle\") {\n void startRecording();\n }\n }\n\n if (!sessionId) {\n return (\n <div className=\"flex h-full items-center justify-center text-fg-muted\">\n {t(\"chat.creating\")}\n </div>\n );\n }\n\n return (\n <div\n className=\"relative -m-4 h-[calc(100%+2rem)] overflow-hidden md:-m-6 md:h-[calc(100%+3rem)]\"\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n >\n {isDragOver && (\n <div className=\"pointer-events-none absolute inset-3 z-50 flex items-center justify-center rounded-lg border-2 border-dashed border-brand bg-brand/5 text-sm font-medium text-brand\">\n {t(\"chat.dropToAttach\")}\n </div>\n )}\n {/* Messages — full-height scroll area so the scrollbar reaches the\n bottom edge of the viewport. Inner content reserves bottom padding\n equal to the floating input's measured height (inputAreaHeight) so\n the last message always clears it, even as the input grows. */}\n <div\n ref={scrollContainerRef}\n className=\"absolute inset-0 overflow-y-auto px-4 py-6\"\n onScroll={handleMessagesScroll}\n >\n <div\n className=\"mx-auto max-w-3xl space-y-4\"\n style={{ paddingBottom: (inputAreaHeight || 96) + 16 }}\n >\n {(canLoadOlder || loadingOlder) && messages.length > 0 && (\n <div className=\"flex justify-center\">\n <button\n onClick={handleLoadOlder}\n disabled={loadingOlder || !canLoadOlder}\n className=\"rounded-full bg-surface px-3 py-1 text-xs text-fg-muted ring-1 ring-line transition-colors hover:bg-surface-subtle hover:text-fg disabled:cursor-not-allowed disabled:opacity-60\"\n >\n {loadingOlder ? t(\"common.loading\") : t(\"chat.loadOlder\")}\n </button>\n </div>\n )}\n {demoError && (\n <div className=\"rounded-md bg-rose-50 px-4 py-3 text-sm text-rose-700 ring-1 ring-rose-200\">\n {demoError}\n </div>\n )}\n\n {messages.length === 0 && demoStatus !== \"running\" && !demoRequested && (\n <div className=\"py-20 text-center\">\n <h3 className=\"text-lg font-semibold text-fg-muted\">\n {t(\"chat.title\")}\n </h3>\n <p className=\"mt-2 text-sm text-fg-muted\">\n {t(\"chat.subtitle\")}\n </p>\n <div className=\"mt-6 flex flex-wrap justify-center gap-2\">\n {[\n t(\"chat.s1\"),\n t(\"chat.s2\"),\n t(\"chat.s3\"),\n t(\"chat.s4\"),\n ].map((suggestion) => (\n <button\n key={suggestion}\n onClick={() => {\n setInput(suggestion);\n inputRef.current?.focus();\n }}\n className=\"rounded-full bg-surface px-3 py-1.5 text-xs text-fg-muted ring-1 ring-line transition-all hover:bg-surface-subtle hover:text-fg hover:ring-brand/30\"\n >\n {suggestion}\n </button>\n ))}\n </div>\n </div>\n )}\n\n {messages.map((msg, idx) => (\n <MessageBubble key={idx} message={msg} />\n ))}\n <div ref={messagesEndRef} />\n </div>\n </div>\n\n {/* Input — absolutely positioned over the message scroll area so the\n scrollbar can reach the bottom edge. bg-surface-muted matches the\n page bg so the textarea card visually floats. The right-side gap\n (md:right-6 / md:pl-6 / md:pr-0) only applies on desktop, where\n scrollbars are always visible and ~17–18px wide. On mobile the\n overlay scrollbar auto-hides, so we extend the wrapper edge-to-\n edge (right-0, px-4) to avoid an empty gap on the right. */}\n <div\n ref={inputAreaRef}\n className=\"absolute bottom-0 left-0 right-0 bg-surface-muted px-4 pb-[max(0.75rem,env(safe-area-inset-bottom))] md:right-6 md:pl-6 md:pr-0\"\n >\n <div className=\"mx-auto max-w-3xl\">\n {/* Attachment preview strip */}\n {attachments.length > 0 && (\n <div className=\"mb-2 flex flex-wrap gap-2\">\n {attachments.map((att) => (\n <div\n key={att.localId}\n className=\"relative flex items-center gap-2 rounded-lg bg-surface px-2 py-1.5 text-xs ring-1 ring-line shadow-card\"\n >\n {att.previewUrl ? (\n <img src={att.previewUrl} alt=\"\" className=\"h-10 w-10 rounded object-cover\" />\n ) : (\n <div className=\"flex h-10 w-10 items-center justify-center rounded bg-rose-100 text-[10px] font-bold text-rose-700\">\n PDF\n </div>\n )}\n <div className=\"flex min-w-0 flex-col\">\n <span className=\"max-w-[160px] truncate text-fg\">{att.file.name}</span>\n <span className=\"text-[10px] text-fg-muted\">\n {att.uploading ? t(\"chat.uploading\") : att.error ? t(\"chat.failed\") : `${Math.round(att.file.size / 1024)} KB`}\n </span>\n </div>\n <button\n onClick={() => removeAttachment(att.localId)}\n className=\"ml-1 text-fg-muted transition-colors hover:text-red-500\"\n title={t(\"chat.remove\")}\n >\n <svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" fill=\"currentColor\">\n <path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" />\n </svg>\n </button>\n </div>\n ))}\n </div>\n )}\n {attachmentError && (\n <div className=\"mb-2 rounded-md bg-rose-50 px-3 py-1.5 text-xs text-rose-700 ring-1 ring-rose-200 shadow-card\">{attachmentError}</div>\n )}\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/png,image/jpeg,image/gif,image/webp,application/pdf,.xlsx,.xls,.ods,.docx,.doc,.odt,.pptx,.ppt,.odp,.csv,.txt,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,application/vnd.oasis.opendocument.spreadsheet,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/msword,application/vnd.oasis.opendocument.text,application/vnd.openxmlformats-officedocument.presentationml.presentation,application/vnd.ms-powerpoint,application/vnd.oasis.opendocument.presentation,text/csv,text/plain\"\n multiple\n className=\"hidden\"\n onChange={(e) => {\n if (e.target.files && e.target.files.length > 0) {\n addFiles(e.target.files);\n e.target.value = \"\";\n }\n }}\n />\n {/* Single \"input card\" that contains the textarea and both action\n buttons. The card carries the surface bg + ring + shadow that\n the textarea used to carry on its own; focus-within promotes\n the ring to the brand-tinted halo when the textarea is\n focused. Send button no longer has a filled bg — both action\n buttons are ghost-style with semantic colors (text-fg-muted\n for attach, text-brand for send). */}\n <div className=\"flex items-end gap-1 rounded-xl bg-surface p-1.5 ring-1 ring-line shadow-card transition-all focus-within:ring-2 focus-within:ring-brand/30\">\n <textarea\n ref={inputRef}\n value={input}\n onChange={(e) => setInput(e.target.value)}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n placeholder={\n isDemoReplaying\n ? t(\"chat.placeholderDemo\")\n : isConnected\n ? t(\"chat.placeholderType\")\n : t(\"chat.placeholderConnecting\")\n }\n disabled={!isConnected || !sessionId || isThinking || isDemoReplaying}\n rows={2}\n className=\"block flex-1 resize-none bg-transparent px-2.5 py-1.5 text-sm text-fg outline-none placeholder:text-fg-muted/70 disabled:text-fg-muted\"\n style={{ minHeight: \"3rem\", maxHeight: \"120px\" }}\n onInput={(e) => {\n const target = e.target as HTMLTextAreaElement;\n target.style.height = \"auto\";\n target.style.height = Math.min(Math.max(target.scrollHeight, 48), 120) + \"px\";\n }}\n />\n <button\n onClick={() => fileInputRef.current?.click()}\n disabled={!isConnected || !sessionId || isThinking || isDemoReplaying || attachments.length >= MAX_ATTACHMENTS}\n className=\"flex h-11 w-11 shrink-0 items-center justify-center rounded-lg text-fg-muted transition-all hover:bg-surface-subtle hover:text-fg disabled:cursor-not-allowed disabled:opacity-40 md:h-10 md:w-10\"\n title={t(\"chat.attachTitle\")}\n >\n <svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M21.44 11.05l-9.19 9.19a6 6 0 01-8.49-8.49l9.19-9.19a4 4 0 015.66 5.66l-9.2 9.19a2 2 0 01-2.83-2.83l8.49-8.48\" />\n </svg>\n </button>\n <button\n onClick={toggleRecording}\n disabled={!isConnected || !sessionId || isThinking || isDemoReplaying || voiceState === \"transcribing\"}\n className={`flex h-11 w-11 shrink-0 items-center justify-center rounded-lg transition-all disabled:cursor-not-allowed disabled:opacity-40 md:h-10 md:w-10 ${\n voiceState === \"recording\"\n ? \"bg-rose-500/10 text-rose-600 hover:bg-rose-500/20\"\n : \"text-fg-muted hover:bg-surface-subtle hover:text-fg\"\n }`}\n title={\n voiceState === \"recording\"\n ? t(\"chat.voiceStop\")\n : voiceState === \"transcribing\"\n ? t(\"chat.voiceTranscribing\")\n : t(\"chat.voiceStart\")\n }\n >\n {voiceState === \"transcribing\" ? (\n <svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" className=\"animate-spin\">\n <path d=\"M21 12a9 9 0 11-6.219-8.56\" strokeLinecap=\"round\" />\n </svg>\n ) : voiceState === \"recording\" ? (\n <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"currentColor\" className=\"animate-pulse\">\n <rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"2\" />\n </svg>\n ) : (\n <svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 1a3 3 0 00-3 3v8a3 3 0 006 0V4a3 3 0 00-3-3z\" />\n <path d=\"M19 10v2a7 7 0 01-14 0v-2\" />\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\" />\n <line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\" />\n </svg>\n )}\n </button>\n <button\n onClick={sendCurrentMessage}\n disabled={(!input.trim() && readyAttachmentIds.length === 0) || !isConnected || !sessionId || isThinking || isDemoReplaying || hasUnfinishedUploads || hasFailedUploads}\n className=\"flex h-11 w-11 shrink-0 items-center justify-center rounded-lg text-brand transition-all hover:bg-brand/10 active:translate-y-px disabled:cursor-not-allowed disabled:text-fg-muted disabled:active:translate-y-0 md:h-10 md:w-10\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n width=\"18\"\n height=\"18\"\n fill=\"currentColor\"\n >\n <path d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\" />\n </svg>\n </button>\n </div>\n <div className=\"mt-1.5 flex items-center gap-1.5\">\n <span\n className={`inline-block h-1.5 w-1.5 rounded-full ${isConnected ? \"bg-emerald-500\" : \"bg-rose-500\"} ${isConnected ? \"\" : \"animate-pulse\"}`}\n />\n <span className=\"text-[11px] text-fg-muted\">\n {isConnected ? \"Connected\" : connectionStatus === \"connecting\" ? \"Connecting...\" : \"Disconnected\"}\n </span>\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nfunction AttachmentThumbs({ attachments }: { attachments?: ChatAttachment[] }) {\n if (!attachments || attachments.length === 0) return null;\n return (\n <div className=\"mt-1 flex flex-wrap gap-1.5\">\n {attachments.map((att) => {\n const url = api.getChatAttachmentUrl(att.id);\n const isImage = att.mime_type.startsWith(\"image/\");\n return (\n <a\n key={att.id}\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-1.5 rounded bg-black/10 px-1.5 py-1 text-[11px] hover:bg-black/20\"\n title={att.filename}\n >\n {isImage ? (\n <img src={url} alt={att.filename} className=\"h-8 w-8 rounded object-cover\" />\n ) : (\n <span className=\"flex h-8 w-8 items-center justify-center rounded bg-red-200 text-[9px] font-bold text-red-800\">PDF</span>\n )}\n <span className=\"max-w-[120px] truncate\">{att.filename}</span>\n </a>\n );\n })}\n </div>\n );\n}\n\nfunction MessageBubble({ message }: { message: ChatMessage }) {\n if (message.type === \"user\") {\n return (\n <div className=\"flex justify-end\">\n <div className=\"max-w-[80%] break-words rounded-2xl rounded-br-md bg-gradient-to-b from-brand to-brand/90 px-4 py-2.5 text-sm text-brand-fg ring-1 ring-black/10 shadow-bubble-user\">\n <div className=\"whitespace-pre-wrap\">{message.content}</div>\n <AttachmentThumbs attachments={message.attachments} />\n {message.timestamp && (\n <div className=\"mt-1 text-right text-[10px] text-brand-fg/70\" title={formatFullTimestamp(message.timestamp)}>{formatTime(message.timestamp)}</div>\n )}\n </div>\n </div>\n );\n }\n\n if (message.type === \"assistant\") {\n return (\n <div className=\"flex justify-start\">\n <div className=\"max-w-[80%] break-words rounded-2xl rounded-bl-md bg-surface px-4 py-2.5 text-sm text-fg ring-1 ring-line shadow-card\">\n <MarkdownContent content={message.content} />\n {message.timestamp && (\n <div className=\"mt-1 text-right text-[10px] text-fg-muted\" title={formatFullTimestamp(message.timestamp)}>{formatTime(message.timestamp)}</div>\n )}\n </div>\n </div>\n );\n }\n\n if (message.type === \"thinking\") {\n return (\n <div className=\"flex justify-start\">\n <div className=\"flex items-center gap-2 rounded-full bg-surface px-3 py-1.5 text-xs text-fg-muted ring-1 ring-line shadow-card\">\n <span className=\"inline-block h-1.5 w-1.5 animate-pulse rounded-full bg-brand\" />\n {message.content}\n {message.provider && (\n <span className=\"rounded bg-surface-subtle px-1.5 py-0.5 text-[10px] font-medium text-fg-muted ring-1 ring-line\">\n {message.provider}\n {message.model ? ` · ${message.model}` : \"\"}\n </span>\n )}\n </div>\n </div>\n );\n }\n\n if (message.type === \"tool_call\") {\n return (\n <div className=\"flex justify-start\">\n <div className=\"rounded-lg bg-surface px-3 py-2 text-xs ring-1 ring-line shadow-card\">\n <div className=\"flex items-center gap-1.5 font-medium text-fg-muted\">\n <svg\n viewBox=\"0 0 24 24\"\n width=\"12\"\n height=\"12\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z\" />\n </svg>\n <span className=\"font-mono\">{message.tool}</span>\n </div>\n {message.args && (\n <pre className=\"mt-1 max-h-20 overflow-auto whitespace-pre-wrap font-mono text-[11px] text-fg-muted/80\">\n {JSON.stringify(message.args, null, 2)}\n </pre>\n )}\n </div>\n </div>\n );\n }\n\n if (message.type === \"tool_result\") {\n return (\n <div className=\"flex justify-start\">\n <div\n className={`rounded-lg px-3 py-2 text-xs shadow-card ring-1 ring-inset ${message.success ? \"bg-emerald-50 ring-emerald-200\" : \"bg-rose-50 ring-rose-200\"}`}\n >\n <div className=\"flex items-center gap-1.5\">\n <span className={message.success ? \"text-emerald-600\" : \"text-rose-600\"}>\n {message.success ? \"\\u2713\" : \"\\u2717\"}\n </span>\n <span className=\"font-mono font-medium text-fg\">{message.tool}</span>\n </div>\n <pre className=\"mt-1 max-h-32 overflow-auto whitespace-pre-wrap font-mono text-[11px] text-fg-muted\">\n {message.content}\n </pre>\n </div>\n </div>\n );\n }\n\n if (message.type === \"error\") {\n return (\n <div className=\"flex justify-start\">\n <div className=\"max-w-[80%] rounded-2xl rounded-bl-md bg-rose-50 px-4 py-2.5 text-sm text-rose-700 ring-1 ring-rose-200 shadow-card\">\n {message.content}\n </div>\n </div>\n );\n }\n\n return null;\n}\n\nfunction MarkdownContent({ content }: { content: string }) {\n const lines = content.split(\"\\n\");\n const elements: React.ReactNode[] = [];\n let inCodeBlock = false;\n let codeLines: string[] = [];\n\n lines.forEach((line, i) => {\n if (line.startsWith(\"```\")) {\n if (inCodeBlock) {\n elements.push(\n <pre\n key={`code-${i}`}\n className=\"my-2 overflow-auto rounded bg-gray-800 p-3 text-xs text-green-300\"\n >\n {codeLines.join(\"\\n\")}\n </pre>,\n );\n codeLines = [];\n inCodeBlock = false;\n } else {\n inCodeBlock = true;\n }\n return;\n }\n if (inCodeBlock) {\n codeLines.push(line);\n return;\n }\n\n if (line.startsWith(\"### \")) {\n elements.push(\n <h4 key={i} className=\"mt-3 mb-1 font-semibold\">\n {line.slice(4)}\n </h4>,\n );\n } else if (line.startsWith(\"## \")) {\n elements.push(\n <h3 key={i} className=\"mt-3 mb-1 text-base font-semibold\">\n {line.slice(3)}\n </h3>,\n );\n } else if (/^\\s*[-*•]\\s+/.test(line)) {\n // Require whitespace after the marker so a bold line like `**Heading**`\n // isn't mistaken for a `*` bullet (which stripped one star and mangled\n // the bold). Real list items always have a space: `- item`, `* item`.\n const content = line.replace(/^\\s*[-*•]\\s+/, \"\");\n elements.push(\n <div key={i} className=\"ml-3 flex gap-1\">\n <span className=\"text-fg-muted\">•</span>\n <span>{formatInline(content)}</span>\n </div>,\n );\n } else if (line.trim() === \"\") {\n elements.push(<div key={i} className=\"h-2\" />);\n } else {\n elements.push(\n <p key={i} className=\"leading-relaxed\">\n {formatInline(line)}\n </p>,\n );\n }\n });\n\n return <div>{elements}</div>;\n}\n\nfunction renderLink(href: string, label: React.ReactNode, key: number | string): React.ReactNode {\n // `/api/*` is a backend endpoint (PDFs, file downloads, attachments) —\n // not a React Router route. Route client-side only for real SPA paths.\n const isSpaRoute = href.startsWith(\"/\") && !href.startsWith(\"/api/\");\n const baseClass = \"font-medium text-brand underline decoration-brand/40 underline-offset-2 transition-colors hover:decoration-brand\";\n if (isSpaRoute) {\n return (\n <Link key={key} to={href} className={baseClass}>\n {label}\n </Link>\n );\n }\n return (\n <a\n key={key}\n href={href}\n className={baseClass}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {label}\n </a>\n );\n}\n\n// Bare URLs: http(s)://... or /internal?query paths. We stop at whitespace,\n// closing punctuation like ), ], }, \", ', and end-of-string. Trailing\n// sentence punctuation (. , ; : ! ?) is stripped below so it doesn't get\n// swallowed into the href.\nconst BARE_URL_RE = /(https?:\\/\\/[^\\s)\\]}\"'<>]+|\\/(?:reports|app|masters|admin|chat|setup|tutorial)[^\\s)\\]}\"'<>]*)/g;\n\nfunction formatInline(text: string): React.ReactNode {\n // Split on (in priority order) markdown links, bold, inline code, bare URLs.\n const parts = text.split(/(\\[[^\\]]+\\]\\([^)]+\\)|\\*\\*[^*]+?\\*\\*|`[^`]+`)/g);\n return parts.flatMap((part, i) => {\n const linkMatch = part.match(/^\\[([^\\]]+)\\]\\(([^)]+)\\)$/);\n if (linkMatch) {\n const [, label, href] = linkMatch;\n return renderLink(href, formatInline(label), i);\n }\n if (part.startsWith(\"**\") && part.endsWith(\"**\") && part.length > 4) {\n return (\n <strong key={i} className=\"font-semibold\">\n {formatInline(part.slice(2, -2))}\n </strong>\n );\n }\n if (part.startsWith(\"`\") && part.endsWith(\"`\")) {\n return (\n <code\n key={i}\n className=\"rounded bg-gray-200 px-1 py-0.5 text-xs font-mono\"\n >\n {part.slice(1, -1)}\n </code>\n );\n }\n // Plain text segment: scan for bare URLs and linkify them.\n return linkifyBare(part, `${i}`);\n });\n}\n\nfunction linkifyBare(text: string, keyPrefix: string): React.ReactNode[] {\n const nodes: React.ReactNode[] = [];\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n const re = new RegExp(BARE_URL_RE.source, \"g\");\n let idx = 0;\n while ((match = re.exec(text)) !== null) {\n const start = match.index;\n let matched = match[0];\n // Strip trailing sentence punctuation that shouldn't belong to the URL.\n let trailing = \"\";\n while (matched.length > 0 && /[.,;:!?]$/.test(matched)) {\n trailing = matched.slice(-1) + trailing;\n matched = matched.slice(0, -1);\n }\n if (start > lastIndex) {\n nodes.push(text.slice(lastIndex, start));\n }\n nodes.push(renderLink(matched, matched, `${keyPrefix}-u${idx}`));\n if (trailing) nodes.push(trailing);\n lastIndex = start + match[0].length;\n idx += 1;\n }\n if (lastIndex < text.length) {\n nodes.push(text.slice(lastIndex));\n }\n return nodes.length > 0 ? nodes : [text];\n}\n","import { useState, useEffect } from \"react\";\nimport { useNavigate, useSearchParams } from \"react-router-dom\";\nimport { useTranslation } from \"react-i18next\";\nimport { useAuth } from \"@/contexts/auth-context\";\nimport { api, ApiError } from \"@/api/client\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\n\nexport default function LoginPage() {\n const navigate = useNavigate();\n const [searchParams] = useSearchParams();\n const { user, login, register } = useAuth();\n const { t } = useTranslation();\n const inviteToken = searchParams.get(\"invite\") || \"\";\n\n const [mode, setMode] = useState<\"login\" | \"register\">(inviteToken ? \"register\" : \"login\");\n const [registrationOpen, setRegistrationOpen] = useState(false);\n // first run = no users yet (next registrant becomes admin); distinct from\n // public signup (admin enabled open self-registration as viewer).\n const [firstRun, setFirstRun] = useState(false);\n const [oauthProviders, setOauthProviders] = useState<string[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState(\"\");\n\n const [email, setEmail] = useState(\"\");\n const [fullName, setFullName] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [confirmPassword, setConfirmPassword] = useState(\"\");\n // Keep the login page accessible during demo mode so admins can still sign in.\n useEffect(() => {\n if (user && user.role !== \"public_manager\") {\n navigate(\"/\", { replace: true });\n }\n }, [user, navigate]);\n\n // Check if registration is open (first-run)\n useEffect(() => {\n api.authSetupStatus()\n .then((s) => {\n setRegistrationOpen(s.registration_open);\n setFirstRun(s.first_run);\n setOauthProviders(s.oauth_providers ?? []);\n // Force register only on first run; under public signup keep login the\n // default (existing users sign in) while still allowing registration.\n if (s.first_run) setMode(\"register\");\n })\n .catch(() => {})\n .finally(() => setLoading(false));\n }, []);\n\n // Surface an OAuth failure the backend redirected back with (?oauth_error=…).\n useEffect(() => {\n const code = searchParams.get(\"oauth_error\");\n if (code) setError(t(`login.oauthError.${code}`, { defaultValue: t(\"login.oauthError.generic\") }));\n }, [searchParams, t]);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(\"\");\n\n if (mode === \"register\") {\n if (password !== confirmPassword) {\n setError(t(\"login.passwordsNoMatch\"));\n return;\n }\n if (password.length < 6) {\n setError(t(\"login.passwordTooShort\"));\n return;\n }\n try {\n await register(email, fullName, password, inviteToken || undefined);\n navigate(\"/\", { replace: true });\n } catch (err) {\n setError(err instanceof ApiError ? err.message : t(\"login.registrationFailed\"));\n }\n } else {\n try {\n await login(email, password);\n navigate(\"/\", { replace: true });\n } catch (err) {\n setError(err instanceof ApiError ? err.message : t(\"login.loginFailed\"));\n }\n }\n };\n\n if (loading) {\n return (\n <div className=\"flex h-dvh items-center justify-center bg-surface-muted\">\n <div className=\"text-fg-muted\">{t(\"common.loading\")}</div>\n </div>\n );\n }\n\n return (\n <div className=\"flex min-h-dvh items-center justify-center bg-surface-muted px-4\">\n <div className=\"w-full max-w-sm space-y-6\">\n <div className=\"text-center\">\n <h1 className=\"text-2xl font-bold text-brand\">Lambda ERP</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">\n {firstRun\n ? t(\"login.taglineFirstRun\")\n : mode === \"register\"\n ? t(\"login.taglineRegister\")\n : t(\"login.taglineSignIn\")}\n </p>\n {user?.role === \"public_manager\" && (\n <p className=\"mt-2 text-xs text-amber-700\">\n {t(\"login.demoBanner\")}\n </p>\n )}\n </div>\n\n {error && (\n <div className=\"rounded-lg bg-rose-50 px-4 py-3 text-sm text-rose-700 ring-1 ring-rose-200\">\n {error}\n </div>\n )}\n\n <Card>\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n {mode === \"register\" && (\n <Input\n label={t(\"login.fullName\")}\n value={fullName}\n onChange={(e) => setFullName(e.target.value)}\n required\n />\n )}\n <Input\n label={t(\"login.email\")}\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n required\n />\n <Input\n label={t(\"login.password\")}\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n required\n />\n {mode === \"register\" && (\n <Input\n label={t(\"login.confirmPassword\")}\n type=\"password\"\n value={confirmPassword}\n onChange={(e) => setConfirmPassword(e.target.value)}\n required\n />\n )}\n <Button type=\"submit\" className=\"w-full\">\n {mode === \"register\" ? (firstRun ? t(\"login.createAdmin\") : t(\"login.register\")) : t(\"login.signIn\")}\n </Button>\n </form>\n\n {oauthProviders.length > 0 && (\n <div className=\"mt-4 space-y-3\">\n <div className=\"flex items-center gap-3\">\n <div className=\"h-px flex-1 bg-border\" />\n <span className=\"text-xs uppercase tracking-wide text-fg-muted\">{t(\"login.orContinueWith\")}</span>\n <div className=\"h-px flex-1 bg-border\" />\n </div>\n <div className=\"space-y-2\">\n {oauthProviders.map((p) => (\n <button\n key={p}\n type=\"button\"\n onClick={() => { window.location.href = api.oauthLoginUrl(p, { invite: inviteToken || undefined }); }}\n className=\"flex w-full items-center justify-center gap-2 rounded-lg border border-border bg-surface px-4 py-2 text-sm font-medium text-fg transition-colors hover:bg-surface-muted\"\n >\n <ProviderIcon provider={p} />\n {t(\"login.continueWithProvider\", { provider: providerLabel(p) })}\n </button>\n ))}\n </div>\n </div>\n )}\n </Card>\n\n {user?.role === \"public_manager\" && (\n <Card>\n <div className=\"space-y-3\">\n <div>\n <h2 className=\"text-sm font-semibold text-fg\">{t(\"login.browsingTitle\")}</h2>\n <p className=\"mt-1 text-sm text-fg-muted\">\n {t(\"login.browsingBody\")}\n </p>\n </div>\n <Button\n type=\"button\"\n className=\"w-full\"\n onClick={() => navigate(\"/demo\", { replace: true })}\n >\n {t(\"login.enterDemo\")}\n </Button>\n </div>\n </Card>\n )}\n\n {/* Only offer registration when it's actually open (first-run or public\n signup). When the instance is invite-only, there is no signup screen:\n invited users arrive via the invite link (which forces register mode)\n and can then set a password or continue with Google. */}\n {!firstRun && !inviteToken && registrationOpen && (\n <p className=\"text-center text-sm text-fg-muted\">\n {mode === \"login\" ? (\n <>\n {t(\"login.noAccountPrompt\")}{\" \"}\n <button onClick={() => setMode(\"register\")} className=\"font-medium text-brand transition-colors hover:text-brand/80\">\n {t(\"login.registerLink\")}\n </button>\n </>\n ) : (\n <>\n {t(\"login.alreadyHaveAccount\")}{\" \"}\n <button onClick={() => setMode(\"login\")} className=\"font-medium text-brand transition-colors hover:text-brand/80\">\n {t(\"login.signInLink\")}\n </button>\n </>\n )}\n </p>\n )}\n </div>\n </div>\n );\n}\n\nfunction providerLabel(provider: string): string {\n return provider.charAt(0).toUpperCase() + provider.slice(1);\n}\n\nfunction ProviderIcon({ provider }: { provider: string }) {\n if (provider === \"google\") {\n return (\n <svg className=\"h-4 w-4\" viewBox=\"0 0 48 48\" aria-hidden=\"true\">\n <path fill=\"#EA4335\" d=\"M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z\" />\n <path fill=\"#4285F4\" d=\"M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z\" />\n <path fill=\"#FBBC05\" d=\"M10.53 28.59c-.48-1.45-.76-2.99-.76-4.59s.27-3.14.76-4.59l-7.98-6.19C.92 16.46 0 20.12 0 24c0 3.88.92 7.54 2.56 10.78l7.97-6.19z\" />\n <path fill=\"#34A853\" d=\"M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z\" />\n </svg>\n );\n }\n if (provider === \"apple\") {\n return (\n <svg className=\"h-4 w-4\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M16.365 1.43c0 1.14-.42 2.22-1.14 3.03-.78.9-2.06 1.6-3.12 1.5-.13-1.1.42-2.28 1.08-3.03.78-.9 2.13-1.56 3.18-1.5zM20.7 17.1c-.56 1.3-.83 1.88-1.55 3.03-1 1.6-2.42 3.6-4.18 3.62-1.56.02-1.96-1.02-4.07-1-2.12.01-2.56 1.02-4.12 1.01-1.76-.02-3.1-1.82-4.1-3.42C-.3 16.9-.6 11.16 1.7 8.1c1.16-1.54 3-2.51 4.85-2.51 1.87 0 3.05 1.02 4.6 1.02 1.5 0 2.42-1.02 4.6-1.02 1.62 0 3.34.88 4.56 2.4-4.01 2.2-3.36 7.92 0 9.11z\" />\n </svg>\n );\n }\n return null;\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { useNavigate } from \"react-router-dom\";\nimport { api, ApiError } from \"@/api/client\";\n\n/**\n * Shareable entry point that mirrors the \"Enter Live Demo\" button on /login.\n * Creates a fresh chat session (as the public_manager fallback user if the\n * visitor has no cookie) and redirects to /chat/{id}?demo=1 for replay.\n */\nexport default function DemoPage() {\n const navigate = useNavigate();\n const startedRef = useRef(false);\n const [error, setError] = useState<string>(\"\");\n\n useEffect(() => {\n // StrictMode double-mounts the effect. A `let cancelled` flag flipped in\n // cleanup would still be `true` when the (single) fetch resolves on the\n // second mount — the promise closure captures the first mount's variable.\n // Guard duplicate kickoffs with a ref and drop the cancelled flag entirely.\n if (startedRef.current) return;\n startedRef.current = true;\n\n api.createChatSession()\n .then((session) => {\n navigate(`/chat/${session.id}?demo=1`, { replace: true });\n })\n .catch((err) => {\n setError(err instanceof ApiError ? err.message : \"Could not start demo\");\n });\n }, [navigate]);\n\n return (\n <div className=\"flex min-h-dvh items-center justify-center bg-surface-muted px-4\">\n <div className=\"text-center\">\n {error ? (\n <>\n <p className=\"text-sm text-rose-600\">{error}</p>\n <button\n onClick={() => navigate(\"/login\", { replace: true })}\n className=\"mt-4 text-sm text-brand transition-colors hover:text-brand/80\"\n >\n Back to login\n </button>\n </>\n ) : (\n <div className=\"space-y-3\">\n <div className=\"mx-auto h-2 w-2 animate-pulse rounded-full bg-brand\" />\n <p className=\"text-sm text-fg-muted\">Starting live demo...</p>\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { useNavigate } from \"react-router-dom\";\nimport { api } from \"@/api/client\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Select } from \"@/components/ui/select\";\nimport { Button } from \"@/components/ui/button\";\nimport { LinkField } from \"@/components/document/link-field\";\n\ninterface AccountRow { account: string; debit: string; credit: string; party_type: string; party: string }\ninterface StockRow { item_code: string; qty: string; rate: string }\ninterface InvoiceRow { type: string; party: string; amount: string; due_date: string; remarks: string }\n\nfunction emptyAccountRow(): AccountRow { return { account: \"\", debit: \"\", credit: \"\", party_type: \"\", party: \"\" }; }\nfunction emptyStockRow(): StockRow { return { item_code: \"\", qty: \"\", rate: \"\" }; }\nfunction emptyInvoiceRow(): InvoiceRow { return { type: \"sales\", party: \"\", amount: \"\", due_date: \"\", remarks: \"\" }; }\n\nexport default function OpeningBalancesPage() {\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n const [company, setCompany] = useState(\"\");\n const [postingDate, setPostingDate] = useState(new Date().toISOString().split(\"T\")[0]);\n const [warehouse, setWarehouse] = useState(\"\");\n\n const [accountRows, setAccountRows] = useState<AccountRow[]>([emptyAccountRow()]);\n const [stockRows, setStockRows] = useState<StockRow[]>([emptyStockRow()]);\n const [invoiceRows, setInvoiceRows] = useState<InvoiceRow[]>([emptyInvoiceRow()]);\n\n const [results, setResults] = useState<Record<string, any>>({});\n\n const accountMut = useMutation({\n mutationFn: () => api.importAccountBalances({\n company,\n posting_date: postingDate,\n entries: accountRows.filter(r => r.account && (r.debit || r.credit)).map(r => ({\n account: r.account, debit: parseFloat(r.debit) || 0, credit: parseFloat(r.credit) || 0,\n party_type: r.party_type || undefined, party: r.party || undefined,\n })),\n }),\n onSuccess: (d) => setResults(prev => ({ ...prev, accounts: d })),\n });\n\n const stockMut = useMutation({\n mutationFn: () => api.importStockBalances({\n company,\n posting_date: postingDate,\n warehouse,\n items: stockRows.filter(r => r.item_code && r.qty).map(r => ({\n item_code: r.item_code, qty: parseFloat(r.qty) || 0, rate: parseFloat(r.rate) || 0,\n })),\n }),\n onSuccess: (d) => setResults(prev => ({ ...prev, stock: d })),\n });\n\n const invoiceMut = useMutation({\n mutationFn: () => api.importOutstandingInvoices({\n company,\n invoices: invoiceRows.filter(r => r.party && r.amount).map(r => ({\n type: r.type, party: r.party, amount: parseFloat(r.amount) || 0,\n due_date: r.due_date || undefined, remarks: r.remarks || undefined, posting_date: postingDate,\n })),\n }),\n onSuccess: (d) => setResults(prev => ({ ...prev, invoices: d })),\n });\n\n function updateRow<T>(rows: T[], setRows: (r: T[]) => void, idx: number, field: string, value: string) {\n const updated = [...rows];\n (updated[idx] as any)[field] = value;\n setRows(updated);\n }\n\n return (\n <div className=\"space-y-6\">\n <p className=\"text-sm text-gray-500\">\n Import balances from your previous system. Each section creates the appropriate documents\n (Journal Entry, Stock Entry, or Invoices) and submits them automatically.\n </p>\n\n <Card title=\"Common Settings\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <LinkField label=\"Company\" value={company} onChange={setCompany} linkDoctype=\"company\" readOnly={false} />\n <Input label=\"As-of Date\" type=\"date\" value={postingDate} onChange={e => setPostingDate(e.target.value)} />\n </div>\n </Card>\n\n {/* Account Balances */}\n <Card title=\"1. Account Balances\">\n <p className=\"mb-3 text-xs text-gray-500\">\n Enter your trial balance from the old system. The difference will be automatically balanced against Opening Balance Equity.\n For receivable/payable accounts, also set the party type and party.\n </p>\n <div>\n <table className=\"min-w-full text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-2 py-2 text-left font-medium text-gray-500\">Account</th>\n <th className=\"px-2 py-2 text-left font-medium text-gray-500\">Party Type</th>\n <th className=\"px-2 py-2 text-left font-medium text-gray-500\">Party</th>\n <th className=\"px-2 py-2 text-right font-medium text-gray-500\">Debit</th>\n <th className=\"px-2 py-2 text-right font-medium text-gray-500\">Credit</th>\n </tr>\n </thead>\n <tbody>\n {accountRows.map((row, i) => (\n <tr key={i}>\n <td className=\"px-2 py-1\">\n <LinkField value={row.account} onChange={v => updateRow(accountRows, setAccountRows, i, \"account\", v)} linkDoctype=\"account\" readOnly={false} label=\"\" />\n </td>\n <td className=\"px-2 py-1\">\n <select value={row.party_type} onChange={e => updateRow(accountRows, setAccountRows, i, \"party_type\", e.target.value)} className=\"w-full rounded border border-gray-300 px-2 py-1.5 text-sm\">\n <option value=\"\">—</option>\n <option value=\"Customer\">Customer</option>\n <option value=\"Supplier\">Supplier</option>\n </select>\n </td>\n <td className=\"px-2 py-1\">\n {row.party_type ? (\n <LinkField label=\"\" value={row.party} onChange={v => updateRow(accountRows, setAccountRows, i, \"party\", v)} linkDoctype={row.party_type.toLowerCase()} readOnly={false} />\n ) : <span className=\"text-gray-300 text-xs\">set party type first</span>}\n </td>\n <td className=\"px-2 py-1\"><input type=\"number\" value={row.debit} onChange={e => updateRow(accountRows, setAccountRows, i, \"debit\", e.target.value)} className=\"w-24 rounded border border-gray-300 px-2 py-1.5 text-right text-sm\" placeholder=\"0.00\" /></td>\n <td className=\"px-2 py-1\"><input type=\"number\" value={row.credit} onChange={e => updateRow(accountRows, setAccountRows, i, \"credit\", e.target.value)} className=\"w-24 rounded border border-gray-300 px-2 py-1.5 text-right text-sm\" placeholder=\"0.00\" /></td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <div className=\"mt-2 flex gap-2\">\n <button onClick={() => setAccountRows([...accountRows, emptyAccountRow()])} className=\"text-xs text-blue-600 hover:text-blue-800\">+ Add Row</button>\n </div>\n <div className=\"mt-3 flex items-center gap-3\">\n <Button onClick={() => accountMut.mutate()} disabled={!company || accountMut.isPending}>\n {accountMut.isPending ? \"Importing...\" : \"Import Account Balances\"}\n </Button>\n {accountMut.error && <span className=\"text-xs text-red-600\">{(accountMut.error as Error).message}</span>}\n {results.accounts && <span className=\"text-xs text-green-600\">Created {results.accounts.journal_entry}</span>}\n </div>\n </Card>\n\n {/* Stock Balances */}\n <Card title=\"2. Stock Balances\">\n <p className=\"mb-3 text-xs text-gray-500\">\n Enter your current inventory. Creates a Stock Entry (Opening Stock) — posts Dr Stock In Hand / Cr Opening Balance Equity so the P&L isn't distorted by day-one inventory.\n </p>\n <div className=\"mb-3\">\n <LinkField label=\"Warehouse\" value={warehouse} onChange={setWarehouse} linkDoctype=\"warehouse\" readOnly={false} />\n </div>\n <div>\n <table className=\"min-w-full text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-2 py-2 text-left font-medium text-gray-500\">Item</th>\n <th className=\"px-2 py-2 text-right font-medium text-gray-500\">Qty</th>\n <th className=\"px-2 py-2 text-right font-medium text-gray-500\">Rate</th>\n </tr>\n </thead>\n <tbody>\n {stockRows.map((row, i) => (\n <tr key={i}>\n <td className=\"px-2 py-1\"><LinkField label=\"\" value={row.item_code} onChange={v => updateRow(stockRows, setStockRows, i, \"item_code\", v)} linkDoctype=\"item\" readOnly={false} /></td>\n <td className=\"px-2 py-1\"><input type=\"number\" value={row.qty} onChange={e => updateRow(stockRows, setStockRows, i, \"qty\", e.target.value)} className=\"w-24 rounded border border-gray-300 px-2 py-1.5 text-right text-sm\" placeholder=\"0\" /></td>\n <td className=\"px-2 py-1\"><input type=\"number\" value={row.rate} onChange={e => updateRow(stockRows, setStockRows, i, \"rate\", e.target.value)} className=\"w-24 rounded border border-gray-300 px-2 py-1.5 text-right text-sm\" placeholder=\"0.00\" /></td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <div className=\"mt-2\">\n <button onClick={() => setStockRows([...stockRows, emptyStockRow()])} className=\"text-xs text-blue-600 hover:text-blue-800\">+ Add Row</button>\n </div>\n <div className=\"mt-3 flex items-center gap-3\">\n <Button onClick={() => stockMut.mutate()} disabled={!company || !warehouse || stockMut.isPending}>\n {stockMut.isPending ? \"Importing...\" : \"Import Stock Balances\"}\n </Button>\n {stockMut.error && <span className=\"text-xs text-red-600\">{(stockMut.error as Error).message}</span>}\n {results.stock && <span className=\"text-xs text-green-600\">Created {results.stock.stock_entry} ({results.stock.items_count} items)</span>}\n </div>\n </Card>\n\n {/* Outstanding Invoices */}\n <Card title=\"3. Outstanding Invoices\">\n <p className=\"mb-3 text-xs text-gray-500\">\n Enter unpaid invoices from your old system. Creates submitted Sales or Purchase Invoices with the correct outstanding amounts for AR/AP aging.\n </p>\n <div>\n <table className=\"min-w-full text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-2 py-2 text-left font-medium text-gray-500\">Type</th>\n <th className=\"px-2 py-2 text-left font-medium text-gray-500\">Customer / Supplier</th>\n <th className=\"px-2 py-2 text-right font-medium text-gray-500\">Amount</th>\n <th className=\"px-2 py-2 text-left font-medium text-gray-500\">Due Date</th>\n <th className=\"px-2 py-2 text-left font-medium text-gray-500\">Ref / Remarks</th>\n </tr>\n </thead>\n <tbody>\n {invoiceRows.map((row, i) => (\n <tr key={i}>\n <td className=\"px-2 py-1\">\n <select value={row.type} onChange={e => updateRow(invoiceRows, setInvoiceRows, i, \"type\", e.target.value)} className=\"rounded border border-gray-300 px-2 py-1.5 text-sm\">\n <option value=\"sales\">Sales (AR)</option>\n <option value=\"purchase\">Purchase (AP)</option>\n </select>\n </td>\n <td className=\"px-2 py-1\">\n <LinkField\n label=\"\"\n value={row.party}\n onChange={v => updateRow(invoiceRows, setInvoiceRows, i, \"party\", v)}\n linkDoctype={row.type === \"sales\" ? \"customer\" : \"supplier\"}\n readOnly={false}\n />\n </td>\n <td className=\"px-2 py-1\"><input type=\"number\" value={row.amount} onChange={e => updateRow(invoiceRows, setInvoiceRows, i, \"amount\", e.target.value)} className=\"w-28 rounded border border-gray-300 px-2 py-1.5 text-right text-sm\" placeholder=\"0.00\" /></td>\n <td className=\"px-2 py-1\"><input type=\"date\" value={row.due_date} onChange={e => updateRow(invoiceRows, setInvoiceRows, i, \"due_date\", e.target.value)} className=\"rounded border border-gray-300 px-2 py-1.5 text-sm\" /></td>\n <td className=\"px-2 py-1\"><input type=\"text\" value={row.remarks} onChange={e => updateRow(invoiceRows, setInvoiceRows, i, \"remarks\", e.target.value)} className=\"w-full rounded border border-gray-300 px-2 py-1.5 text-sm\" placeholder=\"Old invoice ref\" /></td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <div className=\"mt-2\">\n <button onClick={() => setInvoiceRows([...invoiceRows, emptyInvoiceRow()])} className=\"text-xs text-blue-600 hover:text-blue-800\">+ Add Row</button>\n </div>\n <div className=\"mt-3 flex items-center gap-3\">\n <Button onClick={() => invoiceMut.mutate()} disabled={!company || invoiceMut.isPending}>\n {invoiceMut.isPending ? \"Importing...\" : \"Import Outstanding Invoices\"}\n </Button>\n {invoiceMut.error && <span className=\"text-xs text-red-600\">{(invoiceMut.error as Error).message}</span>}\n {results.invoices && <span className=\"text-xs text-green-600\">Created {results.invoices.invoices_created} invoices</span>}\n </div>\n </Card>\n\n {/* Finish */}\n <div className=\"rounded-lg border border-gray-200 bg-gray-50 p-6 text-center\">\n <p className=\"text-sm text-gray-600\">\n Done importing? You can disable this page and re-enable it later under Settings > General.\n </p>\n <button\n onClick={async () => {\n await api.updateSettings({ opening_balances_enabled: \"0\" });\n queryClient.invalidateQueries({ queryKey: [\"settings\"] });\n navigate(\"/\");\n }}\n className=\"mt-3 rounded-lg bg-gray-900 px-5 py-2 text-sm font-medium text-white hover:bg-gray-800\"\n >\n Finish and Disable Opening Balances\n </button>\n </div>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { api } from \"@/api/client\";\nimport { useAuth } from \"@/contexts/auth-context\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Select } from \"@/components/ui/select\";\nimport { Button } from \"@/components/ui/button\";\nimport { usePrompt } from \"@/components/ui/dialog\";\n\nexport default function UsersPage() {\n const { user: currentUser } = useAuth();\n const queryClient = useQueryClient();\n\n const { data: users, isLoading } = useQuery({\n queryKey: [\"auth-users\"],\n queryFn: () => api.authListUsers(),\n });\n\n const { data: invites } = useQuery({\n queryKey: [\"auth-invites\"],\n queryFn: () => api.authListInvites(),\n });\n\n const [inviteEmail, setInviteEmail] = useState(\"\");\n const [inviteRole, setInviteRole] = useState(\"viewer\");\n const [inviteResult, setInviteResult] = useState<{ link: string } | null>(null);\n\n const inviteMut = useMutation({\n mutationFn: () => api.authInvite(inviteEmail, inviteRole),\n onSuccess: (result) => {\n setInviteResult(result);\n setInviteEmail(\"\");\n queryClient.invalidateQueries({ queryKey: [\"auth-invites\"] });\n },\n });\n\n const changeRoleMut = useMutation({\n mutationFn: ({ name, role }: { name: string; role: string }) => api.authChangeRole(name, role),\n onSuccess: () => queryClient.invalidateQueries({ queryKey: [\"auth-users\"] }),\n });\n\n const disableMut = useMutation({\n mutationFn: (name: string) => api.authDisableUser(name),\n onSuccess: () => queryClient.invalidateQueries({ queryKey: [\"auth-users\"] }),\n });\n\n const revokeMut = useMutation({\n mutationFn: (token: string) => api.authRevokeInvite(token),\n onSuccess: () => queryClient.invalidateQueries({ queryKey: [\"auth-invites\"] }),\n });\n\n const [copiedToken, setCopiedToken] = useState<string | null>(null);\n const prompt = usePrompt();\n const inviteLink = (token: string) => `${window.location.origin}/login?invite=${token}`;\n const copyInviteLink = async (token: string) => {\n try {\n await navigator.clipboard.writeText(inviteLink(token));\n setCopiedToken(token);\n setTimeout(() => setCopiedToken((t) => (t === token ? null : t)), 2000);\n } catch {\n // Clipboard API unavailable (e.g. non-HTTPS): show the link in a dialog\n // (a selectable field) so the admin can still copy it manually.\n void prompt({ title: \"Invite link\", body: \"Copy this link:\", defaultValue: inviteLink(token) });\n }\n };\n\n if (currentUser?.role !== \"admin\") {\n return <p className=\"py-8 text-center text-gray-400\">Admin access required</p>;\n }\n\n return (\n <div className=\"space-y-6\">\n {/* Role explanation */}\n <Card title=\"Roles\">\n <div className=\"grid gap-3 text-sm sm:grid-cols-3\">\n <div className=\"rounded-lg border border-blue-200 bg-blue-50 p-3\">\n <div className=\"font-semibold text-blue-900\">Admin</div>\n <p className=\"mt-1 text-blue-700\">\n Full access. Can create and manage documents, masters, company setup, and users. Can invite team members and change roles.\n </p>\n </div>\n <div className=\"rounded-lg border border-amber-200 bg-amber-50 p-3\">\n <div className=\"font-semibold text-amber-900\">Manager</div>\n <p className=\"mt-1 text-amber-700\">\n Can create, edit, submit, and cancel documents. Can create and edit master data. Can run reports and use the AI chat. Cannot manage users or company setup.\n </p>\n </div>\n <div className=\"rounded-lg border border-gray-200 bg-gray-50 p-3\">\n <div className=\"font-semibold text-gray-900\">Viewer</div>\n <p className=\"mt-1 text-gray-600\">\n Read-only access to all documents, masters, and reports. Can use the AI chat. Cannot create or modify any data.\n </p>\n </div>\n </div>\n </Card>\n\n {/* Invite form */}\n <Card title=\"Invite User\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <Input\n label=\"Email\"\n type=\"email\"\n value={inviteEmail}\n onChange={(e) => setInviteEmail(e.target.value)}\n placeholder=\"colleague@company.com\"\n />\n <Select\n label=\"Role\"\n options={[\"viewer\", \"manager\", \"admin\"]}\n value={inviteRole}\n onChange={(e) => setInviteRole(e.target.value)}\n />\n <Button\n onClick={() => inviteMut.mutate()}\n disabled={!inviteEmail.trim() || inviteMut.isPending}\n >\n {inviteMut.isPending ? \"Sending...\" : \"Create Invite\"}\n </Button>\n </div>\n {inviteMut.error && (\n <p className=\"mt-2 text-sm text-red-600\">{(inviteMut.error as Error).message}</p>\n )}\n {inviteResult && (\n <div className=\"mt-3 rounded-md bg-green-50 px-4 py-3 text-sm\">\n <p className=\"font-medium text-green-800\">Invite created!</p>\n <p className=\"mt-1 text-green-700\">\n Share this link:{\" \"}\n <code className=\"rounded bg-green-100 px-2 py-0.5 text-xs font-mono\">\n {window.location.origin}{inviteResult.link}\n </code>\n </p>\n </div>\n )}\n </Card>\n\n {/* Pending invites */}\n {invites && invites.filter((i: any) => !i.used).length > 0 && (\n <Card title=\"Pending Invites\">\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-4 py-2 text-left font-medium text-gray-500\">Email</th>\n <th className=\"px-4 py-2 text-left font-medium text-gray-500\">Role</th>\n <th className=\"px-4 py-2 text-left font-medium text-gray-500\">Created</th>\n <th className=\"px-4 py-2 text-right font-medium text-gray-500\">Actions</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {invites.filter((i: any) => !i.used).map((invite: any) => (\n <tr key={invite.token}>\n <td className=\"px-4 py-2\">{invite.email}</td>\n <td className=\"px-4 py-2\">\n <span className=\"rounded bg-gray-100 px-2 py-0.5 text-xs font-medium\">{invite.role}</span>\n </td>\n <td className=\"px-4 py-2 text-gray-500\">{invite.creation?.split(\"T\")[0]}</td>\n <td className=\"px-4 py-2 text-right\">\n <div className=\"flex items-center justify-end gap-2\">\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => copyInviteLink(invite.token)}\n >\n {copiedToken === invite.token ? \"Copied!\" : \"Copy link\"}\n </Button>\n <Button\n variant=\"danger\"\n size=\"sm\"\n onClick={() => revokeMut.mutate(invite.token)}\n disabled={revokeMut.isPending}\n >\n Revoke\n </Button>\n </div>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </Card>\n )}\n\n {/* User list */}\n <Card title=\"Team Members\">\n {isLoading ? (\n <p className=\"text-gray-500\">Loading...</p>\n ) : (\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-4 py-2 text-left font-medium text-gray-500\">Name</th>\n <th className=\"px-4 py-2 text-left font-medium text-gray-500\">Email</th>\n <th className=\"px-4 py-2 text-left font-medium text-gray-500\">Role</th>\n <th className=\"px-4 py-2 text-left font-medium text-gray-500\">Status</th>\n <th className=\"px-4 py-2 text-right font-medium text-gray-500\">Actions</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {(users || []).map((u: any) => (\n <tr key={u.name} className=\"hover:bg-gray-50\">\n <td className=\"px-4 py-2 font-medium text-gray-900\">{u.full_name}</td>\n <td className=\"px-4 py-2 text-gray-600\">{u.email}</td>\n <td className=\"px-4 py-2\">\n {u.role === \"public_manager\" ? (\n <span className=\"rounded bg-amber-100 px-2 py-0.5 text-xs font-medium text-amber-800\">\n public_manager (system)\n </span>\n ) : (\n <select\n value={u.role}\n onChange={(e) => changeRoleMut.mutate({ name: u.name, role: e.target.value })}\n disabled={u.name === currentUser?.name}\n className={`rounded border px-2 py-1 text-xs ${u.name === currentUser?.name ? \"border-gray-200 bg-gray-50 text-gray-400\" : \"border-gray-300 bg-white text-gray-900\"}`}\n >\n <option value=\"viewer\">viewer</option>\n <option value=\"manager\">manager</option>\n <option value=\"admin\">admin</option>\n </select>\n )}\n </td>\n <td className=\"px-4 py-2\">\n <span className={`rounded px-2 py-0.5 text-xs font-medium ${u.enabled ? \"bg-green-100 text-green-800\" : \"bg-red-100 text-red-800\"}`}>\n {u.enabled ? \"Active\" : \"Disabled\"}\n </span>\n </td>\n <td className=\"px-4 py-2 text-right\">\n {u.name !== currentUser?.name && u.enabled ? (\n <button\n onClick={() => disableMut.mutate(u.name)}\n className=\"text-xs text-red-500 hover:text-red-700\"\n >\n Disable\n </button>\n ) : null}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n )}\n </Card>\n\n </div>\n );\n}\n","import i18n from \"i18next\";\nimport { initReactI18next } from \"react-i18next\";\n\nimport en from \"./locales/en.json\";\nimport de from \"./locales/de.json\";\nimport fr from \"./locales/fr.json\";\n\n/** The languages the UI offers. `code` is what we persist + pass to i18next. */\nexport const SUPPORTED_LANGUAGES = [\n { code: \"en\", label: \"English\" },\n { code: \"de\", label: \"Deutsch\" },\n { code: \"fr\", label: \"Français\" },\n] as const;\n\nexport type LanguageCode = (typeof SUPPORTED_LANGUAGES)[number][\"code\"];\n\n// Namespaced like the app's other localStorage prefs (sidebar-collapsed,\n// lambda-erp:known-chat-sessions). Read/written with try/catch so quota or\n// private-mode errors never break rendering.\nconst STORAGE_KEY = \"lambda-erp:language\";\n\nfunction isSupported(code: string | null): code is LanguageCode {\n return !!code && SUPPORTED_LANGUAGES.some((l) => l.code === code);\n}\n\nexport function getStoredLanguage(): LanguageCode {\n try {\n const v = localStorage.getItem(STORAGE_KEY);\n if (isSupported(v)) return v;\n } catch {\n // ignore (private mode / unavailable storage)\n }\n return \"en\";\n}\n\nfunction storeLanguage(code: string) {\n try {\n localStorage.setItem(STORAGE_KEY, code);\n } catch {\n // ignore storage errors (quota / private mode)\n }\n}\n\ni18n.use(initReactI18next).init({\n resources: {\n en: { translation: en },\n de: { translation: de },\n fr: { translation: fr },\n },\n lng: getStoredLanguage(),\n fallbackLng: \"en\", // any key missing in de/fr falls back to the English value\n interpolation: { escapeValue: false }, // React already escapes\n react: { useSuspense: false }, // resources are bundled synchronously — no Suspense needed\n});\n\n// Persist on every change, including programmatic changeLanguage() calls.\ni18n.on(\"languageChanged\", storeLanguage);\n\nexport default i18n;\n","import { useTranslation } from \"react-i18next\";\nimport { Select } from \"@/components/ui/select\";\nimport { SUPPORTED_LANGUAGES } from \"@/i18n\";\n\n/**\n * Language dropdown. Reads the active language from i18next and switches it on\n * change; the i18n layer persists the choice to localStorage. `label` defaults\n * to the translated \"Language\" string but can be suppressed (e.g. in a header).\n */\nexport function LanguageSelect({ label }: { label?: string | null }) {\n const { t, i18n } = useTranslation();\n // i18n.language can carry a region suffix (e.g. \"en-US\"); match on the base.\n const current = i18n.language?.split(\"-\")[0] ?? \"en\";\n\n return (\n <Select\n label={label === null ? undefined : label ?? t(\"language.label\")}\n options={SUPPORTED_LANGUAGES.map((l) => ({ value: l.code, label: l.label }))}\n value={current}\n onChange={(e) => i18n.changeLanguage(e.target.value)}\n />\n );\n}\n","import { useState, useMemo } from \"react\";\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { useTranslation } from \"react-i18next\";\nimport { api, ApiError } from \"@/api/client\";\nimport { useAuth } from \"@/contexts/auth-context\";\nimport { Card } from \"@/components/ui/card\";\nimport { Select } from \"@/components/ui/select\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { LanguageSelect } from \"@/components/ui/language-select\";\n\n// Map window keys (as returned by /admin/demo-spend) to seconds so we can\n// normalize spend to $/hour for cross-window comparison.\nconst DEMO_SPEND_WINDOWS: Array<{ value: string; label: string; hours: number }> = [\n { value: \"1h\", label: \"Last 1 hour\", hours: 1 },\n { value: \"2h\", label: \"Last 2 hours\", hours: 2 },\n { value: \"4h\", label: \"Last 4 hours\", hours: 4 },\n { value: \"12h\", label: \"Last 12 hours\", hours: 12 },\n { value: \"24h\", label: \"Last 24 hours\", hours: 24 },\n { value: \"7d\", label: \"Last 7 days\", hours: 24 * 7 },\n];\n\nfunction fmtUsd(v: number): string {\n if (v === 0) return \"$0.00\";\n if (v < 0.01) return `$${v.toFixed(4)}`;\n return `$${v.toFixed(2)}`;\n}\n\nfunction TokenSpendCard({ demoActive }: { demoActive: boolean }) {\n const { t } = useTranslation();\n const [windowKey, setWindowKey] = useState<string>(\"1h\");\n const { data, isLoading, isFetching, error, refetch, dataUpdatedAt } = useQuery({\n queryKey: [\"demo-spend\"],\n queryFn: () => api.getDemoSpend(),\n // Refresh once a minute — demo spend changes slowly; no need to poll harder.\n refetchInterval: 60_000,\n });\n\n const windowSpec = DEMO_SPEND_WINDOWS.find((w) => w.value === windowKey)!;\n const window = data?.windows?.[windowKey];\n const demoCap = data?.caps?.global_hourly_usd ?? 0;\n // Average hourly demo spend over the selected range. This is the number that\n // matters for the cap (which is defined as $/hr), so normalizing by window\n // length lets the admin compare any range against the same threshold.\n const demoUsdPerHour = window ? window.demo_usd / windowSpec.hours : 0;\n const totalUsdPerHour = window ? window.total_usd / windowSpec.hours : 0;\n const capPct = demoCap > 0 ? Math.min(100, (demoUsdPerHour / demoCap) * 100) : 0;\n const capColor =\n capPct >= 90 ? \"bg-red-500\" : capPct >= 60 ? \"bg-amber-500\" : \"bg-emerald-500\";\n\n return (\n <Card title={t(\"settings.tokenSpendTitle\")}>\n <div className=\"flex flex-wrap items-end justify-between gap-4\">\n <div className=\"max-w-lg text-sm text-gray-600\">\n Cost and token usage from AI / LLM calls in this deployment, across\n all providers.\n {demoActive && (\n <>\n {\" \"}Only{\" \"}\n <span className=\"font-medium text-gray-900\">public_manager</span>{\" \"}\n (demo) traffic counts against the demo cap; admin/manager sessions\n are included in the total.\n </>\n )}\n </div>\n <div className=\"flex items-end gap-2\">\n <div className=\"w-48\">\n <Select\n label=\"Time range\"\n options={DEMO_SPEND_WINDOWS.map((w) => ({ value: w.value, label: w.label }))}\n value={windowKey}\n onChange={(e) => setWindowKey(e.target.value)}\n />\n </div>\n <button\n type=\"button\"\n onClick={() => refetch()}\n disabled={isFetching}\n title={\n dataUpdatedAt\n ? `Last updated ${new Date(dataUpdatedAt).toLocaleTimeString()}`\n : \"Refresh now\"\n }\n className=\"inline-flex h-[38px] items-center gap-1.5 rounded-md border border-gray-300 bg-white px-3 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-60\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n className={`h-4 w-4 ${isFetching ? \"animate-spin\" : \"\"}`}\n >\n <path\n fillRule=\"evenodd\"\n d=\"M15.312 11.424a5.5 5.5 0 01-9.201 2.466l-.312-.311h2.433a.75.75 0 000-1.5H3.989a.75.75 0 00-.75.75v4.242a.75.75 0 001.5 0v-2.43l.31.31a7 7 0 0011.712-3.138.75.75 0 00-1.449-.39zm1.23-3.723a.75.75 0 00.219-.53V2.929a.75.75 0 00-1.5 0V5.36l-.31-.31A7 7 0 003.239 8.188a.75.75 0 101.448.389A5.5 5.5 0 0113.89 6.11l.311.31h-2.432a.75.75 0 000 1.5h4.243a.75.75 0 00.53-.219z\"\n clipRule=\"evenodd\"\n />\n </svg>\n {isFetching ? t(\"common.refreshing\") : t(\"common.refresh\")}\n </button>\n </div>\n </div>\n\n {isLoading && <p className=\"mt-4 text-sm text-gray-500\">Loading spend data...</p>}\n {error && (\n <p className=\"mt-4 text-sm text-red-600\">\n Failed to load spend data: {(error as Error).message}\n </p>\n )}\n\n {window && (\n <div className=\"mt-5 space-y-5\">\n {demoActive ? (\n /* Demo deployments: spend-against-cap is the number that matters. */\n <div>\n <div className=\"flex items-baseline justify-between\">\n <div>\n <div className=\"text-xs font-medium uppercase tracking-wide text-gray-500\">\n Demo spend (avg/hr over {windowSpec.label.toLowerCase()})\n </div>\n <div className=\"mt-1 text-2xl font-semibold text-gray-900\">\n {fmtUsd(demoUsdPerHour)}\n <span className=\"ml-2 text-sm font-normal text-gray-500\">\n / {fmtUsd(demoCap)} hourly cap\n </span>\n </div>\n </div>\n <div className=\"text-right\">\n <div className=\"text-xs font-medium uppercase tracking-wide text-gray-500\">\n Total (all roles)\n </div>\n <div className=\"mt-1 text-lg font-semibold text-gray-700\">\n {fmtUsd(window.total_usd)}\n <span className=\"ml-1 text-xs font-normal text-gray-500\">\n ({fmtUsd(totalUsdPerHour)}/hr)\n </span>\n </div>\n </div>\n </div>\n <div className=\"mt-2 h-2 w-full overflow-hidden rounded-full bg-gray-100\">\n <div className={`h-full ${capColor} transition-all`} style={{ width: `${capPct}%` }} />\n </div>\n <div className=\"mt-1 text-xs text-gray-400\">\n {capPct.toFixed(0)}% of the hourly cap\n {capPct >= 100 && \" — demo visitors are currently blocked\"}\n </div>\n </div>\n ) : (\n /* Normal deployments: total LLM spend is the useful headline. */\n <div>\n <div className=\"text-xs font-medium uppercase tracking-wide text-gray-500\">\n Total spend (avg/hr over {windowSpec.label.toLowerCase()})\n </div>\n <div className=\"mt-1 text-2xl font-semibold text-gray-900\">\n {fmtUsd(totalUsdPerHour)}\n <span className=\"ml-2 text-sm font-normal text-gray-500\">\n ({fmtUsd(window.total_usd)} over {windowSpec.label.toLowerCase()})\n </span>\n </div>\n </div>\n )}\n\n {/* Stats grid */}\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n {demoActive ? (\n <Stat label=\"Demo spend\" value={fmtUsd(window.demo_usd)} />\n ) : (\n <Stat label=\"Cost\" value={fmtUsd(window.total_usd)} />\n )}\n <Stat label=\"Calls\" value={window.call_count.toLocaleString()} />\n <Stat label=\"Unique IPs\" value={window.unique_ips.toLocaleString()} />\n <Stat\n label=\"Tokens (in/out)\"\n value={`${window.prompt_tokens.toLocaleString()} / ${window.completion_tokens.toLocaleString()}`}\n />\n </div>\n\n {/* Provider breakdown */}\n {Object.keys(window.by_provider).length > 0 && (\n <div>\n <div className=\"mb-2 text-xs font-medium uppercase tracking-wide text-gray-500\">\n By provider\n </div>\n <div className=\"overflow-hidden rounded-md border border-gray-200\">\n <table className=\"w-full text-sm\">\n <thead className=\"bg-gray-50 text-xs uppercase tracking-wide text-gray-500\">\n <tr>\n <th className=\"px-3 py-2 text-left font-medium\">Provider</th>\n <th className=\"px-3 py-2 text-right font-medium\">Cost</th>\n <th className=\"px-3 py-2 text-right font-medium\">Calls</th>\n <th className=\"px-3 py-2 text-right font-medium\">Prompt tok</th>\n <th className=\"px-3 py-2 text-right font-medium\">Completion tok</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {Object.entries(window.by_provider).map(([provider, row]) => (\n <tr key={provider}>\n <td className=\"px-3 py-2 font-medium text-gray-900\">{provider}</td>\n <td className=\"px-3 py-2 text-right tabular-nums\">{fmtUsd(row.cost_usd)}</td>\n <td className=\"px-3 py-2 text-right tabular-nums\">{row.call_count.toLocaleString()}</td>\n <td className=\"px-3 py-2 text-right tabular-nums\">{row.prompt_tokens.toLocaleString()}</td>\n <td className=\"px-3 py-2 text-right tabular-nums\">{row.completion_tokens.toLocaleString()}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n )}\n\n {/* Top IPs — fixed at 24h window regardless of selector, since that's\n what the backend returns and it's the most useful abuse-detection lens */}\n {data && data.top_ips_24h.length > 0 && (\n <div>\n <div className=\"mb-2 text-xs font-medium uppercase tracking-wide text-gray-500\">\n Top 10 IPs (last 24 hours)\n </div>\n <div className=\"overflow-hidden rounded-md border border-gray-200\">\n <table className=\"w-full text-sm\">\n <thead className=\"bg-gray-50 text-xs uppercase tracking-wide text-gray-500\">\n <tr>\n <th className=\"px-3 py-2 text-left font-medium\">IP</th>\n <th className=\"px-3 py-2 text-left font-medium\">Role</th>\n <th className=\"px-3 py-2 text-right font-medium\">Cost</th>\n <th className=\"px-3 py-2 text-right font-medium\">Calls</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {data.top_ips_24h.map((row, i) => (\n <tr key={`${row.ip}-${row.role ?? \"\"}-${i}`}>\n <td className=\"px-3 py-2 font-mono text-xs text-gray-900\">{row.ip}</td>\n <td className=\"px-3 py-2 text-gray-600\">{row.role ?? \"—\"}</td>\n <td className=\"px-3 py-2 text-right tabular-nums\">{fmtUsd(row.cost_usd)}</td>\n <td className=\"px-3 py-2 text-right tabular-nums\">{row.call_count.toLocaleString()}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n )}\n </div>\n )}\n </Card>\n );\n}\n\nfunction Stat({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"rounded-md bg-gray-50 px-3 py-2\">\n <div className=\"text-xs font-medium uppercase tracking-wide text-gray-500\">{label}</div>\n <div className=\"mt-0.5 text-sm font-semibold tabular-nums text-gray-900\">{value}</div>\n </div>\n );\n}\n\nfunction ChangePasswordCard() {\n const { t } = useTranslation();\n const { user } = useAuth();\n const [current, setCurrent] = useState(\"\");\n const [next, setNext] = useState(\"\");\n const [confirm, setConfirm] = useState(\"\");\n const [error, setError] = useState(\"\");\n const [done, setDone] = useState(false);\n\n const mut = useMutation({\n mutationFn: () => api.authChangePassword(current, next),\n onSuccess: () => {\n setDone(true);\n setError(\"\");\n setCurrent(\"\");\n setNext(\"\");\n setConfirm(\"\");\n setTimeout(() => setDone(false), 4000);\n },\n onError: (e) => setError(e instanceof ApiError ? e.message : t(\"login.registrationFailed\")),\n });\n\n const submit = (e: React.FormEvent) => {\n e.preventDefault();\n setError(\"\");\n setDone(false);\n if (next !== confirm) {\n setError(t(\"login.passwordsNoMatch\"));\n return;\n }\n if (next.length < 6) {\n setError(t(\"login.passwordTooShort\"));\n return;\n }\n mut.mutate();\n };\n\n return (\n <Card title={t(\"settings.passwordTitle\")}>\n <form onSubmit={submit} className=\"max-w-sm space-y-3\">\n {/* Hidden username anchor: lets password managers (1Password, etc.)\n associate the saved login so they fill/save against the right\n account. 1Password recommends a real text input hidden with\n display:none rather than the `hidden` attribute. */}\n <input\n type=\"text\"\n name=\"username\"\n id=\"username\"\n autoComplete=\"username\"\n value={user?.email || \"\"}\n readOnly\n tabIndex={-1}\n aria-hidden=\"true\"\n style={{ display: \"none\" }}\n />\n <Input\n label={t(\"settings.currentPassword\")}\n id=\"current-password\"\n name=\"current-password\"\n type=\"password\"\n autoComplete=\"current-password\"\n value={current}\n onChange={(e) => setCurrent(e.target.value)}\n required\n />\n <Input\n label={t(\"settings.newPassword\")}\n id=\"new-password\"\n name=\"new-password\"\n type=\"password\"\n autoComplete=\"new-password\"\n value={next}\n onChange={(e) => setNext(e.target.value)}\n required\n />\n <Input\n label={t(\"settings.confirmNewPassword\")}\n id=\"confirm-password\"\n name=\"confirm-password\"\n type=\"password\"\n autoComplete=\"new-password\"\n value={confirm}\n onChange={(e) => setConfirm(e.target.value)}\n required\n />\n {error && <p className=\"text-sm text-red-600\">{error}</p>}\n {done && <p className=\"text-sm text-green-700\">{t(\"settings.passwordChanged\")}</p>}\n <Button type=\"submit\" disabled={mut.isPending || !current || !next || !confirm}>\n {mut.isPending ? t(\"settings.changingPassword\") : t(\"settings.changePassword\")}\n </Button>\n </form>\n </Card>\n );\n}\n\nfunction SetPasswordCard() {\n const { t } = useTranslation();\n const { user, refreshUser } = useAuth();\n const [next, setNext] = useState(\"\");\n const [confirm, setConfirm] = useState(\"\");\n const [error, setError] = useState(\"\");\n const [done, setDone] = useState(false);\n\n const mut = useMutation({\n mutationFn: () => api.authSetPassword(next),\n onSuccess: async () => {\n setDone(true);\n setError(\"\");\n setNext(\"\");\n setConfirm(\"\");\n // Flip the card to \"Change Password\" now that a password exists.\n await refreshUser();\n },\n onError: (e) => setError(e instanceof ApiError ? e.message : t(\"login.registrationFailed\")),\n });\n\n const submit = (e: React.FormEvent) => {\n e.preventDefault();\n setError(\"\");\n setDone(false);\n if (next !== confirm) {\n setError(t(\"login.passwordsNoMatch\"));\n return;\n }\n if (next.length < 6) {\n setError(t(\"login.passwordTooShort\"));\n return;\n }\n mut.mutate();\n };\n\n return (\n <Card title={t(\"settings.setPasswordTitle\")}>\n <p className=\"mb-3 max-w-lg text-sm text-gray-600\">{t(\"settings.setPasswordBody\")}</p>\n <form onSubmit={submit} className=\"max-w-sm space-y-3\">\n {/* Hidden username anchor so password managers save against the account. */}\n <input\n type=\"text\"\n name=\"username\"\n autoComplete=\"username\"\n value={user?.email || \"\"}\n readOnly\n tabIndex={-1}\n aria-hidden=\"true\"\n style={{ display: \"none\" }}\n />\n <Input\n label={t(\"settings.newPassword\")}\n id=\"new-password\"\n name=\"new-password\"\n type=\"password\"\n autoComplete=\"new-password\"\n value={next}\n onChange={(e) => setNext(e.target.value)}\n required\n />\n <Input\n label={t(\"settings.confirmNewPassword\")}\n id=\"confirm-password\"\n name=\"confirm-password\"\n type=\"password\"\n autoComplete=\"new-password\"\n value={confirm}\n onChange={(e) => setConfirm(e.target.value)}\n required\n />\n {error && <p className=\"text-sm text-red-600\">{error}</p>}\n {done && <p className=\"text-sm text-green-700\">{t(\"settings.passwordSet\")}</p>}\n <Button type=\"submit\" disabled={mut.isPending || !next || !confirm}>\n {mut.isPending ? t(\"settings.changingPassword\") : t(\"settings.setPassword\")}\n </Button>\n </form>\n </Card>\n );\n}\n\nfunction LinkedAccountsCard() {\n const { t } = useTranslation();\n\n const { data: setup } = useQuery({\n queryKey: [\"auth-setup-status\"],\n queryFn: () => api.authSetupStatus(),\n });\n const { data: identities } = useQuery({\n queryKey: [\"oauth-identities\"],\n queryFn: () => api.oauthListIdentities(),\n });\n\n const providers = setup?.oauth_providers ?? [];\n if (providers.length === 0) return null; // no social login configured on this deployment\n\n const linked = new Set((identities ?? []).map((i) => i.provider));\n\n return (\n <Card title={t(\"settings.linkedAccountsTitle\")}>\n <p className=\"text-sm text-gray-600\">{t(\"settings.linkedAccountsBody\")}</p>\n <div className=\"mt-3 space-y-2\">\n {providers.map((p) => {\n const label = p.charAt(0).toUpperCase() + p.slice(1);\n const isLinked = linked.has(p);\n return (\n <div key={p} className=\"flex items-center justify-between rounded-md border border-gray-200 px-3 py-2\">\n <span className=\"text-sm font-medium text-gray-900\">{label}</span>\n {isLinked ? (\n <span className=\"inline-flex items-center gap-1.5 text-sm text-green-700\">\n <span className=\"inline-block h-2 w-2 rounded-full bg-green-500\" />\n {t(\"settings.linked\")}\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={() => { window.location.href = api.oauthLoginUrl(p, { link: true }); }}\n className=\"rounded-md border border-gray-300 bg-white px-3 py-1 text-sm font-medium text-gray-700 hover:bg-gray-50\"\n >\n {t(\"settings.linkProvider\", { provider: label })}\n </button>\n )}\n </div>\n );\n })}\n </div>\n </Card>\n );\n}\n\nconst ROLE_RANK: Record<string, number> = { viewer: 1, manager: 2, admin: 3 };\n\n// Self-service API keys: every key belongs to its creator and can never act\n// above the owner's live role (the picked role is only a CAP). Non-admins see\n// and manage their own keys; admins see everyone's.\nfunction ApiKeysSection({ ownRole }: { ownRole: string }) {\n const { t } = useTranslation();\n const { user: me } = useAuth();\n const queryClient = useQueryClient();\n const [name, setName] = useState(\"\");\n const [role, setRole] = useState(ownRole in ROLE_RANK ? ownRole : \"viewer\");\n const [newToken, setNewToken] = useState<string | null>(null);\n const [confirm, setConfirm] = useState<\n null | { id: string; action: \"revoke\" | \"delete\"; owner: string; keyName: string }\n >(null);\n\n const roleOptions = [\"viewer\", \"manager\", \"admin\"].filter(\n (r) => ROLE_RANK[r] <= (ROLE_RANK[ownRole] ?? 1),\n );\n\n // The same key doubles as MCP auth (POST <origin>/api/mcp). Show ready-to-paste\n // config for the common agents right after the token, while it's still visible.\n const mcpUrl = `${window.location.origin}/api/mcp`;\n const claudeSnippet = newToken\n ? `claude mcp add --transport http --scope user lambda-erp ${mcpUrl} \\\\\\n --header \"Authorization: Bearer ${newToken}\"`\n : \"\";\n const codexSnippet = newToken\n ? `# ~/.codex/config.toml\\n[mcp_servers.lambda-erp]\\nurl = \"${mcpUrl}\"\\nhttp_headers = { Authorization = \"Bearer ${newToken}\" }`\n : \"\";\n\n const { data: keys } = useQuery({\n queryKey: [\"api-keys\"],\n queryFn: () => api.getApiKeys(),\n });\n\n const createMut = useMutation({\n mutationFn: () => api.createApiKey(name.trim(), role),\n onSuccess: (res) => {\n setNewToken(res.token);\n setName(\"\");\n queryClient.invalidateQueries({ queryKey: [\"api-keys\"] });\n },\n });\n\n const revokeMut = useMutation({\n mutationFn: (id: string) => api.revokeApiKey(id),\n onSuccess: () => queryClient.invalidateQueries({ queryKey: [\"api-keys\"] }),\n });\n\n const deleteMut = useMutation({\n mutationFn: (id: string) => api.deleteApiKey(id),\n onSuccess: () => queryClient.invalidateQueries({ queryKey: [\"api-keys\"] }),\n });\n\n type Key = NonNullable<typeof keys>[number];\n const isMine = (k: Key) => k.is_mine ?? (k.user === me?.name);\n const ownerLabel = (k: Key) =>\n k.owner_full_name || k.owner_email || k.user || t(\"settings.chatApiUnknownUser\");\n\n // Group keys by owner: your own first, then each other user alphabetically.\n const groups = useMemo(() => {\n const byOwner = new Map<\n string,\n { label: string; sublabel?: string; isMine: boolean; keys: Key[] }\n >();\n for (const k of keys ?? []) {\n const mine = k.is_mine ?? (k.user === me?.name);\n const gid = mine ? \"__me__\" : k.user ?? \"__unknown__\";\n if (!byOwner.has(gid)) {\n byOwner.set(gid, {\n label: mine\n ? t(\"settings.chatApiYourKeys\")\n : k.owner_full_name || k.owner_email || k.user || t(\"settings.chatApiUnknownUser\"),\n sublabel: mine ? undefined : k.owner_email ?? undefined,\n isMine: mine,\n keys: [],\n });\n }\n byOwner.get(gid)!.keys.push(k);\n }\n return Array.from(byOwner.values()).sort((a, b) =>\n a.isMine ? -1 : b.isMine ? 1 : a.label.localeCompare(b.label),\n );\n }, [keys, me, t]);\n\n const runAction = (id: string, action: \"revoke\" | \"delete\") => {\n if (action === \"revoke\") revokeMut.mutate(id);\n else deleteMut.mutate(id);\n };\n\n // A destructive action on someone else's key must be confirmed first.\n const act = (k: Key, action: \"revoke\" | \"delete\") => {\n if (isMine(k)) {\n runAction(k.id, action);\n } else {\n setConfirm({ id: k.id, action, owner: ownerLabel(k), keyName: k.name });\n }\n };\n\n return (\n <div>\n {newToken && (\n <div className=\"mb-3 rounded-lg bg-amber-50 p-3 ring-1 ring-inset ring-amber-200\">\n <p className=\"text-xs text-amber-800\">{t(\"settings.chatApiTokenOnce\")}</p>\n <code className=\"mt-1 block break-all rounded bg-surface px-2 py-1 font-mono text-xs text-fg\">\n {newToken}\n </code>\n <button\n className=\"mt-2 text-xs font-medium text-brand hover:underline\"\n onClick={() => navigator.clipboard?.writeText(newToken)}\n >\n {t(\"settings.chatApiCopy\")}\n </button>\n <button\n className=\"ml-3 mt-2 text-xs text-fg-muted hover:underline\"\n onClick={() => setNewToken(null)}\n >\n {t(\"settings.chatApiDismiss\")}\n </button>\n\n {/* The same key is also an MCP endpoint — reuses this key's role. */}\n <div className=\"mt-3 border-t border-amber-200 pt-3\">\n <p className=\"text-xs text-amber-800\">\n {t(\"settings.mcpNote\", {\n defaultValue:\n \"This key is also an MCP endpoint — connect an AI agent (Claude, Codex) to it. It reuses this key's role (a viewer key = read-only).\",\n })}\n </p>\n <code className=\"mt-1 block break-all rounded bg-surface px-2 py-1 font-mono text-xs text-fg\">\n {mcpUrl}\n </code>\n <details className=\"mt-2 text-xs text-amber-900\">\n <summary className=\"cursor-pointer font-medium\">Claude</summary>\n <pre className=\"mt-1 overflow-x-auto rounded bg-surface p-2 font-mono text-[11px] leading-relaxed text-fg\">{claudeSnippet}</pre>\n </details>\n <details className=\"mt-1 text-xs text-amber-900\">\n <summary className=\"cursor-pointer font-medium\">Codex</summary>\n <pre className=\"mt-1 overflow-x-auto rounded bg-surface p-2 font-mono text-[11px] leading-relaxed text-fg\">{codexSnippet}</pre>\n </details>\n </div>\n </div>\n )}\n\n {ownRole === \"admin\" && (\n <p className=\"mb-3 text-xs text-fg-muted\">{t(\"settings.chatApiAdminAllNote\")}</p>\n )}\n\n {groups.length > 0 ? (\n <div className=\"mb-4 space-y-4\">\n {groups.map((g) => (\n <div key={g.label}>\n <div className=\"mb-1.5 flex items-baseline gap-2\">\n <span className=\"text-xs font-semibold text-fg\">{g.label}</span>\n {g.isMine ? (\n <Badge variant=\"default\">{t(\"settings.chatApiYouBadge\")}</Badge>\n ) : (\n g.sublabel && <span className=\"text-xs text-fg-muted\">{g.sublabel}</span>\n )}\n </div>\n <ul className=\"divide-y divide-line rounded-lg ring-1 ring-line\">\n {g.keys.map((k) => (\n <li\n key={k.id}\n className=\"flex items-center justify-between gap-3 px-3 py-2 text-sm\"\n >\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"truncate font-medium text-fg\">{k.name}</span>\n <Badge variant=\"secondary\">{k.role}</Badge>\n {k.revoked && (\n <Badge variant=\"danger\">{t(\"settings.chatApiRevoked\")}</Badge>\n )}\n </div>\n <span className=\"font-mono text-xs text-fg-muted\">{k.key_prefix}…</span>\n </div>\n <button\n className=\"shrink-0 text-xs font-medium text-red-600 hover:underline disabled:opacity-50\"\n onClick={() => act(k, k.revoked ? \"delete\" : \"revoke\")}\n disabled={revokeMut.isPending || deleteMut.isPending}\n >\n {k.revoked ? t(\"settings.chatApiDelete\") : t(\"settings.chatApiRevoke\")}\n </button>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"mb-4 text-xs text-fg-muted\">{t(\"settings.chatApiNoKeys\")}</p>\n )}\n\n <div className=\"flex flex-wrap items-end gap-3\">\n <div className=\"w-48\">\n <Input\n label={t(\"settings.chatApiName\")}\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"lambda-web\"\n />\n </div>\n <Select\n label={t(\"settings.chatApiRole\")}\n options={roleOptions}\n value={role}\n onChange={(e) => setRole(e.target.value)}\n />\n <Button onClick={() => createMut.mutate()} disabled={!name.trim() || createMut.isPending}>\n {t(\"settings.chatApiCreate\")}\n </Button>\n </div>\n <p className=\"mt-2 text-xs text-fg-muted\">{t(\"settings.chatApiWarn\")}</p>\n\n {confirm && (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4\"\n onClick={() => setConfirm(null)}\n >\n <div\n className=\"w-full max-w-sm rounded-xl border border-line bg-surface p-5 shadow-xl\"\n role=\"dialog\"\n aria-modal=\"true\"\n onClick={(e) => e.stopPropagation()}\n >\n <h3 className=\"text-sm font-semibold text-fg\">{t(\"settings.chatApiConfirmTitle\")}</h3>\n <p className=\"mt-2 text-xs text-fg-muted\">\n {t(\n confirm.action === \"revoke\"\n ? \"settings.chatApiConfirmRevokeBody\"\n : \"settings.chatApiConfirmDeleteBody\",\n { name: confirm.owner, key: confirm.keyName },\n )}\n </p>\n <div className=\"mt-4 flex justify-end gap-2\">\n <Button variant=\"secondary\" size=\"sm\" onClick={() => setConfirm(null)}>\n {t(\"common.cancel\")}\n </Button>\n <Button\n variant=\"danger\"\n size=\"sm\"\n onClick={() => {\n runAction(confirm.id, confirm.action);\n setConfirm(null);\n }}\n >\n {confirm.action === \"revoke\"\n ? t(\"settings.chatApiRevoke\")\n : t(\"settings.chatApiDelete\")}\n </Button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction ApiToggleRow({\n enabled,\n onToggle,\n body,\n statusOn,\n statusOff,\n}: {\n enabled: boolean;\n onToggle: () => void;\n body: string;\n statusOn: string;\n statusOff: string;\n}) {\n const { t } = useTranslation();\n return (\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"text-sm text-gray-700\">{body}</p>\n <p className=\"mt-1 text-xs text-gray-400\">{enabled ? statusOn : statusOff}</p>\n </div>\n <button\n onClick={onToggle}\n className={`ml-4 shrink-0 rounded-full px-4 py-1.5 text-sm font-medium ${\n enabled\n ? \"bg-red-50 text-red-700 hover:bg-red-100\"\n : \"bg-green-50 text-green-700 hover:bg-green-100\"\n }`}\n >\n {enabled ? t(\"common.disable\") : t(\"common.enable\")}\n </button>\n </div>\n );\n}\n\n// The Chat API (POST /api/v1/chat) and the REST API (/api/documents, /api/masters, …)\n// are two surfaces authenticated by the SAME per-user Bearer keys, toggled\n// independently. The shared keys section shows once EITHER surface is enabled.\nfunction ApiAccessCard({\n chatEnabled,\n restEnabled,\n onToggleChat,\n onToggleRest,\n ownRole,\n}: {\n chatEnabled: boolean;\n restEnabled: boolean;\n onToggleChat: () => void;\n onToggleRest: () => void;\n ownRole: string;\n}) {\n const { t } = useTranslation();\n // Which surface a pending \"turn off\" confirm applies to. Enabling is harmless\n // (go straight through); disabling cuts off live callers, so confirm first —\n // keys are preserved either way, requests just start failing.\n const [confirmOff, setConfirmOff] = useState<null | \"chat\" | \"rest\">(null);\n\n return (\n <Card title={t(\"settings.apiTitle\")}>\n <div className=\"space-y-4\">\n <ApiToggleRow\n enabled={chatEnabled}\n onToggle={() => (chatEnabled ? setConfirmOff(\"chat\") : onToggleChat())}\n body={t(\"settings.chatApiBody\")}\n statusOn={t(\"settings.chatApiEnabled\")}\n statusOff={t(\"settings.chatApiDisabled\")}\n />\n <div className=\"border-t border-gray-100\" />\n <ApiToggleRow\n enabled={restEnabled}\n onToggle={() => (restEnabled ? setConfirmOff(\"rest\") : onToggleRest())}\n body={t(\"settings.restApiBody\")}\n statusOn={t(\"settings.restApiEnabled\")}\n statusOff={t(\"settings.restApiDisabled\")}\n />\n </div>\n\n {(chatEnabled || restEnabled) && (\n <div className=\"mt-4 border-t border-gray-100 pt-4\">\n <div className=\"mb-2 text-xs font-medium text-gray-500\">{t(\"settings.chatApiKeysTitle\")}</div>\n <ApiKeysSection ownRole={ownRole} />\n </div>\n )}\n\n {confirmOff && (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4\"\n onClick={() => setConfirmOff(null)}\n >\n <div\n className=\"w-full max-w-md rounded-xl border border-line bg-surface p-6 shadow-xl\"\n role=\"dialog\"\n aria-modal=\"true\"\n onClick={(e) => e.stopPropagation()}\n >\n <h3 className=\"text-base font-semibold text-fg\">\n {confirmOff === \"chat\"\n ? t(\"settings.chatApiDeactivateTitle\")\n : t(\"settings.restApiDeactivateTitle\")}\n </h3>\n <p className=\"mt-3 text-sm text-fg-muted\">\n {confirmOff === \"chat\"\n ? t(\"settings.chatApiDeactivateBody\")\n : t(\"settings.restApiDeactivateBody\")}\n </p>\n <div className=\"mt-6 flex justify-end gap-2\">\n <Button variant=\"secondary\" size=\"sm\" onClick={() => setConfirmOff(null)}>\n {t(\"common.cancel\")}\n </Button>\n <Button\n variant=\"danger\"\n size=\"sm\"\n onClick={() => {\n if (confirmOff === \"chat\") onToggleChat();\n else onToggleRest();\n setConfirmOff(null);\n }}\n >\n {t(\"settings.chatApiDeactivateConfirm\")}\n </Button>\n </div>\n </div>\n </div>\n )}\n </Card>\n );\n}\n\nexport default function SettingsPage() {\n const { user } = useAuth();\n const { t } = useTranslation();\n const queryClient = useQueryClient();\n const isAdmin = user?.role === \"admin\";\n\n const { data: settings, isLoading } = useQuery({\n queryKey: [\"settings\"],\n queryFn: () => api.getSettings(),\n });\n\n const settingsMut = useMutation({\n mutationFn: (data: Record<string, string>) => api.updateSettings(data),\n onSuccess: () => queryClient.invalidateQueries({ queryKey: [\"settings\"] }),\n });\n\n const { data: pubStatus } = useQuery({\n queryKey: [\"public-manager\"],\n queryFn: () => api.getPublicManagerStatus(),\n });\n\n const { data: health } = useQuery({\n queryKey: [\"health\"],\n queryFn: () => api.getHealth(),\n staleTime: Infinity, // version only changes on deploy\n });\n\n const [showConfirm, setShowConfirm] = useState(false);\n\n const createPubMut = useMutation({\n mutationFn: () => api.createPublicManager(),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [\"public-manager\"] });\n setShowConfirm(false);\n },\n });\n\n const removePubMut = useMutation({\n mutationFn: () => api.removePublicManager(),\n onSuccess: () => queryClient.invalidateQueries({ queryKey: [\"public-manager\"] }),\n });\n\n if (isLoading) return <p className=\"text-gray-500\">{t(\"common.loading\")}</p>;\n\n return (\n <div className=\"space-y-6\">\n <Card title={t(\"language.title\")}>\n <div className=\"flex flex-wrap items-end gap-4\">\n <div className=\"w-64\">\n <LanguageSelect />\n </div>\n </div>\n <p className=\"mt-2 text-xs text-gray-400\">{t(\"language.help\")}</p>\n </Card>\n\n {/* Personal account — every signed-in user can change their own password\n (the shared public_manager demo account has none). */}\n {/* Password-less (social-login-only) users get \"Set a password\"; everyone\n else keeps \"Change Password\". has_password === false is the only case\n that hides Change Password, so an unknown value stays safe. */}\n {user?.role !== \"public_manager\" &&\n (user?.has_password === false ? <SetPasswordCard /> : <ChangePasswordCard />)}\n {user?.role !== \"public_manager\" && <LinkedAccountsCard />}\n\n <Card title={t(\"settings.pdfTitle\")}>\n <div className=\"flex flex-wrap items-end gap-4\">\n {isAdmin ? (\n <Select\n label={t(\"settings.pageSize\")}\n options={[\"A4\", \"letter\"]}\n value={settings?.pdf_page_size || \"A4\"}\n onChange={(e) => settingsMut.mutate({ pdf_page_size: e.target.value })}\n />\n ) : (\n <div>\n <div className=\"text-xs font-medium text-gray-500 mb-1\">{t(\"settings.pageSize\")}</div>\n <div className=\"text-sm text-gray-900\">{settings?.pdf_page_size || \"A4\"}</div>\n </div>\n )}\n </div>\n <p className=\"mt-2 text-xs text-gray-400\">\n {t(\"settings.pdfHelp\")}\n </p>\n </Card>\n\n <Card title={t(\"settings.openingTitle\")}>\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"text-sm text-gray-700\">\n {t(\"settings.openingBody\")}\n </p>\n <p className=\"mt-1 text-xs text-gray-400\">\n {settings?.opening_balances_enabled === \"1\"\n ? t(\"settings.openingEnabled\")\n : t(\"settings.openingDisabled\")}\n </p>\n </div>\n {isAdmin && (\n <button\n onClick={() => settingsMut.mutate({\n opening_balances_enabled: settings?.opening_balances_enabled === \"1\" ? \"0\" : \"1\",\n })}\n className={`ml-4 shrink-0 rounded-full px-4 py-1.5 text-sm font-medium ${\n settings?.opening_balances_enabled === \"1\"\n ? \"bg-red-50 text-red-700 hover:bg-red-100\"\n : \"bg-green-50 text-green-700 hover:bg-green-100\"\n }`}\n >\n {settings?.opening_balances_enabled === \"1\" ? t(\"common.disable\") : t(\"common.enable\")}\n </button>\n )}\n </div>\n </Card>\n\n <Card title={t(\"settings.signupTitle\")}>\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"text-sm text-gray-700\">\n {t(\"settings.signupBody\")}\n </p>\n <p className=\"mt-1 text-xs text-gray-400\">\n {settings?.allow_public_signup === \"1\"\n ? t(\"settings.signupEnabled\")\n : t(\"settings.signupDisabled\")}\n </p>\n </div>\n {isAdmin && (\n <button\n onClick={() => settingsMut.mutate({\n allow_public_signup: settings?.allow_public_signup === \"1\" ? \"0\" : \"1\",\n })}\n className={`ml-4 shrink-0 rounded-full px-4 py-1.5 text-sm font-medium ${\n settings?.allow_public_signup === \"1\"\n ? \"bg-red-50 text-red-700 hover:bg-red-100\"\n : \"bg-green-50 text-green-700 hover:bg-green-100\"\n }`}\n >\n {settings?.allow_public_signup === \"1\" ? t(\"common.disable\") : t(\"common.enable\")}\n </button>\n )}\n </div>\n </Card>\n\n {isAdmin && (\n <ApiAccessCard\n chatEnabled={settings?.chat_api_enabled === \"1\"}\n restEnabled={settings?.rest_api_enabled === \"1\"}\n ownRole={user?.role ?? \"viewer\"}\n onToggleChat={() =>\n settingsMut.mutate({\n chat_api_enabled: settings?.chat_api_enabled === \"1\" ? \"0\" : \"1\",\n })\n }\n onToggleRest={() =>\n settingsMut.mutate({\n rest_api_enabled: settings?.rest_api_enabled === \"1\" ? \"0\" : \"1\",\n })\n }\n />\n )}\n\n {/* Self-service API keys for non-admins: keys are personal (bound to the\n creator, capped at their role), so every real user manages their own\n here. Admins get the same section inside the Chat API card above. */}\n {!isAdmin && user?.role !== \"public_manager\" && (\n <Card title={t(\"settings.chatApiKeysTitle\")}>\n <p className=\"mb-3 text-sm text-gray-700\">{t(\"settings.chatApiPersonal\")}</p>\n <ApiKeysSection ownRole={user?.role ?? \"viewer\"} />\n </Card>\n )}\n\n {isAdmin && <TokenSpendCard demoActive={!!pubStatus?.active} />}\n\n {/* Public Manager / Demo Mode — kept last: it's the most consequential\n toggle (opens the whole app to anonymous demo access). */}\n {isAdmin && (\n <Card title={t(\"settings.publicTitle\")}>\n {pubStatus?.active ? (\n <div>\n <div className=\"flex items-center gap-2\">\n <span className=\"inline-block h-2 w-2 rounded-full bg-green-500\" />\n <span className=\"text-sm font-medium text-green-800\">{t(\"settings.publicActive\")}</span>\n </div>\n <p className=\"mt-2 text-sm text-gray-600\">\n {t(\"settings.publicActiveBody\")}\n </p>\n <button\n onClick={() => removePubMut.mutate()}\n disabled={removePubMut.isPending}\n className=\"mt-3 rounded-lg bg-gray-100 px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-200\"\n >\n {removePubMut.isPending ? t(\"settings.disabling\") : t(\"settings.disablePublic\")}\n </button>\n </div>\n ) : (\n <div>\n <p className=\"text-sm text-gray-600\">\n {t(\"settings.publicInactiveBody\")}\n </p>\n {!showConfirm ? (\n <button\n onClick={() => setShowConfirm(true)}\n className=\"mt-3 rounded-lg bg-red-600 px-4 py-2 text-sm font-medium text-white hover:bg-red-700\"\n >\n {t(\"settings.enablePublic\")}\n </button>\n ) : (\n <div className=\"mt-3 rounded-lg border border-red-200 bg-red-50 p-4\">\n <p className=\"text-sm font-medium text-red-800\">{t(\"common.areYouSure\")}</p>\n <p className=\"mt-1 text-xs text-red-600\">\n {t(\"settings.enableWarning\")}\n </p>\n <div className=\"mt-3 flex gap-2\">\n <button\n onClick={() => createPubMut.mutate()}\n disabled={createPubMut.isPending}\n className=\"rounded-lg bg-red-600 px-4 py-1.5 text-sm font-medium text-white hover:bg-red-700\"\n >\n {createPubMut.isPending ? t(\"settings.enabling\") : t(\"settings.yesEnable\")}\n </button>\n <button\n onClick={() => setShowConfirm(false)}\n className=\"rounded-lg bg-white px-4 py-1.5 text-sm font-medium text-gray-700 hover:bg-gray-50 border border-gray-300\"\n >\n {t(\"common.cancel\")}\n </button>\n </div>\n </div>\n )}\n </div>\n )}\n </Card>\n )}\n\n {health?.version && (\n <p className=\"pt-2 text-center text-xs text-gray-400\">\n {t(\"settings.version\", { version: health.version })}\n </p>\n )}\n </div>\n );\n}\n","/**\n * Component override registry.\n *\n * Lets a customer deployment swap a specific UI component for its own without\n * forking the core. Core render sites that want to be overridable resolve\n * their component through `getComponent(name, CoreDefault)` instead of\n * referencing the concrete component directly; the customer calls\n * `registerComponent(name, MyComponent)` at startup.\n *\n * This is the fine-grained seam. For whole pages, prefer the route registry\n * (registerRoute) — it replaces the routed element directly.\n */\nimport type { ComponentType } from \"react\";\n\nconst COMPONENTS: Record<string, ComponentType<any>> = {};\n\nexport function registerComponent(name: string, component: ComponentType<any>) {\n COMPONENTS[name] = component;\n}\n\n/** Resolve a registered override, falling back to the core default. */\nexport function getComponent<P>(\n name: string,\n fallback: ComponentType<P>,\n): ComponentType<P> {\n return (COMPONENTS[name] as ComponentType<P>) ?? fallback;\n}\n","import { type RouteObject } from \"react-router-dom\";\nimport { AppShell } from \"@/components/layout/app-shell\";\nimport { ProtectedRoute } from \"@/components/auth/protected-route\";\nimport Dashboard from \"@/pages/dashboard\";\nimport DocumentList from \"@/pages/documents/document-list\";\nimport DocumentForm from \"@/pages/documents/document-form\";\nimport ProposalForm from \"@/pages/proposals/proposal-form\";\nimport MasterList from \"@/pages/masters/master-list\";\nimport MasterForm from \"@/pages/masters/master-form\";\nimport TrialBalance from \"@/pages/reports/trial-balance\";\nimport ChartOfAccounts from \"@/pages/reports/chart-of-accounts\";\nimport GeneralLedger from \"@/pages/reports/general-ledger\";\nimport StockBalance from \"@/pages/reports/stock-balance\";\nimport ProfitLoss from \"@/pages/reports/profit-loss\";\nimport BalanceSheet from \"@/pages/reports/balance-sheet\";\nimport ArAging from \"@/pages/reports/ar-aging\";\nimport ApAging from \"@/pages/reports/ap-aging\";\nimport Analytics from \"@/pages/reports/analytics\";\nimport Setup from \"@/pages/setup\";\nimport Tutorial from \"@/pages/tutorial\";\nimport Chat from \"@/pages/chat\";\nimport Login from \"@/pages/login\";\nimport Demo from \"@/pages/demo\";\nimport OpeningBalances from \"@/pages/opening-balances\";\nimport Users from \"@/pages/admin/users\";\nimport GeneralSettings from \"@/pages/admin/settings\";\nimport { getComponent } from \"@/lib/component-registry\";\n\n// The dashboard (the index route) is resolved through the component registry\n// so a customer deployment can swap it via registerComponent(\"Dashboard\", …).\nfunction DashboardRoute() {\n const C = getComponent(\"Dashboard\", Dashboard);\n return <C />;\n}\n\nconst baseTopRoutes: RouteObject[] = [\n { path: \"/login\", element: <Login /> },\n { path: \"/demo\", element: <Demo /> },\n];\n\nconst baseChildRoutes: RouteObject[] = [\n { index: true, element: <DashboardRoute /> },\n { path: \"setup\", element: <Setup /> },\n { path: \"setup/opening-balances\", element: <OpeningBalances /> },\n { path: \"tutorial\", element: <Tutorial /> },\n { path: \"chat\", element: <Chat /> },\n { path: \"chat/:sessionId\", element: <Chat /> },\n\n // Proposal (Sammelofferte) — a custom builder; the list reuses the generic\n // DocumentList via the `proposal` doctype config. The static \"proposal\"\n // segment outranks the \":doctype\" wildcard below in react-router's matcher.\n { path: \"app/proposal/new\", element: <ProposalForm /> },\n { path: \"app/proposal/:name\", element: <ProposalForm /> },\n\n // Documents\n { path: \"app/:doctype\", element: <DocumentList /> },\n { path: \"app/:doctype/new\", element: <DocumentForm /> },\n { path: \"app/:doctype/:name\", element: <DocumentForm /> },\n\n // Masters (reuse same routes - the components detect whether it's a doctype or master)\n { path: \"masters/:type\", element: <MasterList /> },\n { path: \"masters/:type/new\", element: <MasterForm /> },\n { path: \"masters/:type/:name\", element: <MasterForm /> },\n\n // Reports\n { path: \"reports/chart-of-accounts\", element: <ChartOfAccounts /> },\n { path: \"reports/trial-balance\", element: <TrialBalance /> },\n { path: \"reports/general-ledger\", element: <GeneralLedger /> },\n { path: \"reports/stock-balance\", element: <StockBalance /> },\n { path: \"reports/profit-and-loss\", element: <ProfitLoss /> },\n { path: \"reports/balance-sheet\", element: <BalanceSheet /> },\n { path: \"reports/ar-aging\", element: <ArAging /> },\n { path: \"reports/ap-aging\", element: <ApAging /> },\n { path: \"reports/analytics\", element: <Analytics /> },\n\n // Admin\n { path: \"admin/users\", element: <Users /> },\n { path: \"admin/settings\", element: <GeneralSettings /> },\n];\n\nconst extraTopRoutes: RouteObject[] = [];\nconst extraChildRoutes: RouteObject[] = [];\n\n/**\n * Register a route from a customer deployment.\n * - area \"app\" (default): added under the protected app shell (sidebar +\n * header), so it's an authenticated page like the core ones.\n * - area \"top\": added at the root (e.g. a public/unauthenticated page).\n *\n * A registered route whose `path` (or index) matches a core route replaces\n * it — that's how you override a core page wholesale.\n */\nexport function registerRoute(route: RouteObject, opts?: { area?: \"app\" | \"top\" }) {\n if (opts?.area === \"top\") {\n extraTopRoutes.push(route);\n } else {\n extraChildRoutes.push(route);\n }\n}\n\nconst routeKey = (r: RouteObject) => (r.index ? \"__index__\" : r.path ?? \"\");\n\nfunction mergeRoutes(base: RouteObject[], extra: RouteObject[]): RouteObject[] {\n const out = [...base];\n for (const r of extra) {\n const k = routeKey(r);\n const i = out.findIndex((m) => routeKey(m) === k);\n if (i >= 0) out[i] = r;\n else out.push(r);\n }\n return out;\n}\n\n/**\n * Build the full route table, merging any customer-registered routes over the\n * core ones. Call this when constructing the router (the demo does so via\n * bootstrap) — after plugins have registered, so overrides take effect.\n */\nexport function buildRoutes(): RouteObject[] {\n return [\n ...mergeRoutes(baseTopRoutes, extraTopRoutes),\n {\n path: \"/\",\n element: <ProtectedRoute><AppShell /></ProtectedRoute>,\n children: mergeRoutes(baseChildRoutes, extraChildRoutes),\n },\n ];\n}\n","// Auto-registered redirects for page-less chat-doctypes.\n//\n// A doctype registered via register_chat_doctype(..., page=\"<link_field>\") has\n// no standalone page — it's shown inside a parent (e.g. a contact inside its\n// lead). The AI chat may still emit `/app/{slug}/{name}` links for it. This\n// fetches /api/chat-doctypes at bootstrap and, for each such doctype, registers\n// a route that looks up the record's parent and redirects to the parent's page,\n// so those links resolve. Best-effort: if the fetch fails the app still renders\n// (the chat's prompt page-rules already point it at the right link).\nimport { useEffect } from \"react\";\nimport { useParams, useNavigate } from \"react-router-dom\";\nimport { api, request } from \"@/api/client\";\nimport { registerRoute } from \"@/routes\";\n\ntype PageInfo =\n | { kind: \"self\"; slug: string }\n | { kind: \"via\"; link_field: string; parent_slug: string }\n | { kind: \"none\" };\n\nfunction ChatDoctypeRedirect({ slug, parentSlug, linkField }: {\n slug: string; parentSlug: string; linkField: string;\n}) {\n const { name = \"\" } = useParams();\n const navigate = useNavigate();\n useEffect(() => {\n let alive = true;\n api\n .getDocument(slug, name)\n .then((doc: any) => {\n if (!alive) return;\n const parent = doc?.[linkField];\n navigate(parent ? `/app/${parentSlug}/${parent}` : `/app/${slug}`, { replace: true });\n })\n .catch(() => { if (alive) navigate(\"/app\", { replace: true }); });\n return () => { alive = false; };\n }, [slug, name, parentSlug, linkField, navigate]);\n return <div className=\"p-6 text-sm text-fg-muted\">…</div>;\n}\n\nexport async function registerChatDoctypeRedirects(): Promise<void> {\n try {\n const res = await request<{ doctypes: { slug: string; page: PageInfo | null }[] }>(\n \"/chat-doctypes\",\n { signal: AbortSignal.timeout(1500) },\n );\n for (const d of res.doctypes || []) {\n const page = d.page;\n if (page && page.kind === \"via\") {\n registerRoute({\n path: `app/${d.slug}/:name`,\n element: (\n <ChatDoctypeRedirect slug={d.slug} parentSlug={page.parent_slug} linkField={page.link_field} />\n ),\n });\n }\n }\n } catch {\n // best-effort — the app renders fine without these fallback redirects.\n }\n}\n","import { StrictMode } from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { createBrowserRouter, RouterProvider } from \"react-router-dom\";\nimport { AuthProvider } from \"./contexts/auth-context\";\nimport { buildRoutes } from \"./routes\";\nimport { registerChatDoctypeRedirects } from \"./lib/chat-doctype-redirects\";\nimport \"./i18n\"; // initialize i18next (reads saved language from localStorage)\n\nexport function createAppQueryClient() {\n return new QueryClient({\n defaultOptions: {\n queries: { retry: 1, refetchOnWindowFocus: false },\n },\n });\n}\n\nexport interface BootstrapOptions {\n /** Mount target. Defaults to the element with id \"root\". */\n rootElement?: HTMLElement;\n /** Provide a custom QueryClient (e.g. to tune caching). */\n queryClient?: QueryClient;\n}\n\n/**\n * Render the full app (providers + router) into the DOM. The demo app and a\n * customer deployment both call this from their entry module — the customer\n * imports its plugin (which registers overrides/routes/doctypes) and the\n * stylesheet first, then calls bootstrap(). Routes are built here, after\n * registration, so overrides take effect.\n */\nexport async function bootstrap(opts: BootstrapOptions = {}) {\n const root = opts.rootElement ?? document.getElementById(\"root\");\n if (!root) {\n throw new Error('bootstrap: no mount element (pass rootElement or add <div id=\"root\">)');\n }\n const queryClient = opts.queryClient ?? createAppQueryClient();\n // Auto-register redirects for page-less chat-doctypes (best-effort, bounded)\n // BEFORE routes are built, so their /app/{slug}/{name} links resolve.\n await registerChatDoctypeRedirects();\n const router = createBrowserRouter(buildRoutes());\n\n createRoot(root).render(\n <StrictMode>\n <QueryClientProvider client={queryClient}>\n <AuthProvider>\n <RouterProvider router={router} />\n </AuthProvider>\n </QueryClientProvider>\n </StrictMode>,\n );\n}\n","// Inline arm-to-confirm button for low-stakes, in-row actions (e.g. removing a\n// row from a list). On first click it splits in place into \"Cancel | Confirm\",\n// with **Cancel occupying the trigger's original position** — so an accidental\n// double-click's second click lands on Cancel and nothing happens. It\n// auto-collapses after `timeout` ms or on pointer-leave.\n//\n// For heavier or destructive actions (deleting a whole record), prefer the\n// modal useConfirm() from dialog.tsx instead — a transient inline split in a\n// busy toolbar is more clutter than a focused dialog.\nimport { useEffect, useRef, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { cn } from \"@/lib/utils\";\n\ninterface ConfirmButtonProps {\n onConfirm: () => void;\n /** Resting trigger content (icon or text). */\n children: React.ReactNode;\n confirmLabel?: React.ReactNode;\n cancelLabel?: React.ReactNode;\n title?: string; // tooltip on the resting trigger\n danger?: boolean; // red confirm (default true)\n disabled?: boolean;\n className?: string; // applied to the resting trigger\n timeout?: number; // auto-collapse ms (default 4000)\n /** Armed-button size: \"sm\" (compact, for icon triggers — default) or \"md\"\n * (normal button height, to match a full-size labelled trigger). */\n size?: \"sm\" | \"md\";\n /** Which side the Cancel button sits on when armed. It should land where the\n * trigger was so a double-click cancels: \"left\" for a left-aligned trigger\n * (default), \"right\" for a right-aligned one (e.g. a toolbar delete button). */\n cancelSide?: \"left\" | \"right\";\n}\n\nexport function ConfirmButton({\n onConfirm,\n children,\n confirmLabel,\n cancelLabel,\n title,\n danger = true,\n disabled,\n className,\n timeout = 4000,\n size = \"sm\",\n cancelSide = \"left\",\n}: ConfirmButtonProps) {\n const { t } = useTranslation();\n const [armed, setArmed] = useState(false);\n const timer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n useEffect(() => {\n if (!armed) return;\n timer.current = setTimeout(() => setArmed(false), timeout);\n return () => clearTimeout(timer.current);\n }, [armed, timeout]);\n\n if (!armed) {\n return (\n <button\n type=\"button\"\n disabled={disabled}\n title={title}\n onClick={() => setArmed(true)}\n className={className}\n >\n {children}\n </button>\n );\n }\n\n const md = size === \"md\";\n const confirmBtn = (\n <button\n key=\"confirm\"\n type=\"button\"\n onClick={() => {\n setArmed(false);\n onConfirm();\n }}\n className={cn(\n \"rounded-md font-medium text-white\",\n md ? \"px-3 py-1.5 text-sm\" : \"px-2 py-1 text-xs\",\n danger ? \"bg-red-600 hover:bg-red-700\" : \"bg-brand hover:bg-brand/90\",\n )}\n >\n {confirmLabel ?? t(\"common.delete\", { defaultValue: \"Delete\" })}\n </button>\n );\n const cancelBtn = (\n <button\n key=\"cancel\"\n type=\"button\"\n onClick={() => setArmed(false)}\n className={cn(\n \"rounded-md\",\n md\n ? \"px-3 py-1.5 text-sm font-medium text-fg ring-1 ring-line hover:bg-surface-subtle\"\n : \"px-2 py-1 text-xs text-fg-muted hover:text-fg\",\n )}\n >\n {cancelLabel ?? t(\"common.cancel\", { defaultValue: \"Cancel\" })}\n </button>\n );\n\n return (\n <span\n className={cn(\"inline-flex items-center\", md ? \"gap-2\" : \"gap-1\")}\n onMouseLeave={() => setArmed(false)}\n >\n {/* Cancel sits at the trigger's original position (cancelSide), so a\n double-click lands on Cancel and nothing happens. */}\n {cancelSide === \"right\" ? [confirmBtn, cancelBtn] : [cancelBtn, confirmBtn]}\n </span>\n );\n}\n"],"names":["BASE","configureApiBase","base","apiUrl","path","ApiError","status","message","formatErrorDetail","detail","item","rec","loc","msg","request","options","res","body","qs","params","clean","v","s","api","sessionId","file","form","id","doctype","name","masterType","data","targetDoctype","company","customer","type","q","results","provider","opts","suffix","email","password","current_password","new_password","role","userName","token","AuthContext","createContext","AuthProvider","children","user","setUser","useState","loading","setLoading","useEffect","u","login","useCallback","register","fullName","inviteToken","logout","refreshUser","jsx","useAuth","ctx","useContext","ChatContext","NAV_FLASH_MAP","MASTER_FLASH_MAP","normalizeDoctype","value","getNavigationFlashFromTool","tool","args","mapPersistedMessage","KNOWN_SESSIONS_KEY","getKnownSessionIds","raw","parsed","writeKnownSessionIds","ids","rememberSessionId","forgetSessionId","makeRequestId","toSortTime","timestamp","ChatProvider","queryClient","useQueryClient","sessions","setSessions","messagesBySession","setMessagesBySession","hasMoreBySession","setHasMoreBySession","oldestIdBySession","setOldestIdBySession","loadingOlderBySession","setLoadingOlderBySession","thinkingBySession","setThinkingBySession","demoStatusBySession","setDemoStatusBySession","demoTypingCueBySession","setDemoTypingCueBySession","navigationFlash","setNavigationFlash","connectionStatus","setConnectionStatus","connectionVersion","setConnectionVersion","wsRef","useRef","reconnectTimerRef","pendingRequestsRef","pendingCreateSessionRef","lastMessageAtRef","pendingToolCallsRef","navFlashTimeoutRef","rejectPendingRequests","pending","updateSessionMessages","updater","prev","setSessionThinking","setSessionDemoStatus","setSessionDemoTypingCue","triggerNavigationFlash","group","sortSessionsByMessageActivity","sessionList","left","right","leftTime","updateSessionList","recordSessionMessage","nextTimestamp","currentTimestamp","hydrateLastMessageTimes","next","session","sendRaw","payload","ws","sendRequest","expectedType","resolve","reject","requestId","error","disposed","connect","wsUrl","event","eventType","nextSessions","serverIds","missing","row","fetched","resolved","p","entry","nextLastMessageAt","persisted","isPrepend","hasMore","oldestId","existing","existingIds","filtered","title","lastPersistedMessage","prior","m","model","content","pendingToolCall","backendReportId","argReportId","_a","flashTarget","createSession","promise","startDemo","completeDemoTyping","seq","deleteSession","loadHistory","loadMoreHistory","clearHistory","sendMessage","attachmentIds","trimmed","hasAttachments","transcribeAudio","audioBase64","audioFormat","getMessages","isThinking","hasMoreHistory","isLoadingOlder","getDemoStatus","getDemoTypingCue","useChat","context","cn","classes","formatCurrency","currency","formatNumber","decimals","dateLocale","setDateLocale","locale","formatDate","flt","precision","n","variantClasses","sizeClasses","Button","variant","size","disabled","onClick","className","Input","label","hint","props","inputId","DialogContext","DialogProvider","t","useTranslation","state","setState","setValue","confirm","prompt","useMemo","settle","result","onConfirm","onCancel","jsxs","e","useDialog","useConfirm","usePrompt","NAV_GROUPS","BookOpen","ShoppingCart","CreditCard","FileText","Package","BarChart3","Database","Settings","getNavGroups","registerNavGroup","g","registerNavItem","groupLabel","branding","configureBranding","root","key","getBranding","STORAGE_KEY","getCollapsed","setCollapsed","collapsed","useSidebarToggle","open","setOpen","toggle","expand","FLASH_STYLES","ChatGroup","location","useLocation","navigate","useNavigate","handleNewChat","handleDelete","MessageCircle","ChevronDown","ChevronRight","Plus","active","NavLink","ActiveAccent","Trash2","CustomAnalyticsGroup","isGroupFlashing","flashStyle","useQuery","drafts","deleteMutation","useMutation","_result","handleNew","prefill","targetSessionId","LineChart","draft","isItemFlashing","SidebarGroup","end","other","isActive","Fragment","HIDDEN_PATHS","Sidebar","isMobileOpen","onClose","settings","setupStatus","firstCompany","companyName","groups","settingKey","titleCase","slug","c","deriveTitle","pathname","parts","cap","one","deriveBackPath","AppShell","AppShellContent","pageTitle","backPath","handleBack","mobileOpen","setMobileOpen","ArrowLeft","Outlet","ProtectedRoute","Navigate","Card","interactive","Badge","dot","STATUS_VARIANT_MAP","StatusBadge","useBaseCurrency","companies","match","MetricCard","Icon","tone","toneClass","baseCurrency","fmtCurrency","MetricCardSkeleton","DOCTYPE_ICON","Receipt","Wallet","RecentDocumentRow","doc","date","href","Link","RecentDocumentRowSkeleton","DashboardPage","isLoading","TrendingUp","ArrowDownRight","ArrowUpRight","idx","KEY","readAll","setListContext","all","getListContext","useDocumentList","filters","refetch","useUrlPatch","setParams","useSearchParams","patch","useUrlState","defaultValue","ITEM_FIELDS","QUOTATION_ITEM_FIELDS","CURRENCY_FIELD","TAX_FIELDS","CONFIGS","getDoctypeConfig","registerDoctype","config","getAllDoctypeConfigs","DocPager","onSave","kind","isMaster","goPrev","goNext","back","onKey","el","btn","ChevronLeft","normalizeOption","opt","Select","onChange","required","selectId","l","HintTooltip","text","visible","setVisible","NotesMarkupHelp","rows","Info","syntax","desc","useCurrencies","enabled","LINKABLE_MASTERS","linkRefHref","linkDoctype","FieldLabel","extra","LinkField","field","hideLabel","query","setQuery","wrapRef","menuRect","setMenuRect","update","r","createPortal","FieldRenderer","readOnly","rowData","isDisabled","Label","needsCurrencyOptions","currencyOptions","resolvedLinkDoctype","display","pClass","resolvedField","showMarkupHelp","inputType","ChildTableEditor","tableDef","updateRow","fieldName","updated","i","addRow","blank","f","removeRow","_","DocumentActions","isNew","docstatus","discarded","saving","onSubmit","onConvert","onDiscard","confirmingCancel","setConfirmingCancel","confirmingDiscard","setConfirmingDiscard","pdfUrl","showCancel","conv","recalculate","formData","ct","sum","tax","totalTax","DocumentFormPage","useParams","setFormData","currencyTouched","setCurrencyTouched","existingDoc","hasCurrencyField","partyType","partyName","companyCurrency","partyMaster","suggested","defaults","createMut","updateMut","submitMut","cancelMut","discardMut","convertMut","targetSlug","setField","setChildTable","handleSave","handleSubmit","handleCancel","handleConvert","handleDiscard","docCurrency","docRate","editableFields","gridFields","noteFields","totalsFields","iso","d","startOfWeek","day","diff","endOfWeek","startOfMonth","endOfMonth","startOfQuarter","endOfQuarter","startOfYear","endOfYear","PRESETS","now","lastMonth","lastQuarter","lastYear","DateRangePresets","onSelect","from","to","SingleDatePresets","STATUS_OPTIONS","CURRENCY_FIELDS","DATE_FIELDS","MASTER_REF_FIELDS","partyMasterType","PAGE_SIZE_OPTIONS","ListPager","page","totalPages","pageSize","total","rangeStart","rangeEnd","setPage","setPageSize","pageInput","setPageInput","commit","DocumentListPage","configFilters","filterValues","out","fromDate","toDate","showDiscarded","searchFields","urlQ","searchInput","setSearchInput","urlPage","patchUrl","setStatus","setFromDate","setToDate","setShowDiscarded","on","limit","offset","ctxFilters","columns","helper","createColumnHelper","headerLabel","titleCased","w","col","info","table","useReactTable","getCoreRowModel","o","headerGroup","header","flexRender","cell","setResults","dropdownStyle","setDropdownStyle","debounceRef","containerRef","dropdownRef","inputRef","selectingRef","updateDropdownPosition","rect","search","handleInputChange","handleSelect","handleBlur","handler","target","_b","blankRow","LETTERS","ProposalForm","qc","tr","k","dflt","setForm","setRows","appendix","setAppendix","appendixBusy","setAppendixBusy","setError","fileRef","set","loadCoverDefault","cover_letter","saveMut","rs","j","moveRow","dir","onPickAppendix","err","removeAppendix","MasterListPage","notice","val","MASTER_FIELDS","TYPE_LABELS","AUTO_NAME_TYPES","MasterFormPage","labelTr","fields","fieldLabel","current","deleteMut","missingRequiredFields","isReadOnly","isRequired","useTrialBalance","useChartOfAccounts","useGeneralLedger","useStockBalance","useProfitAndLoss","useBalanceSheet","useArAging","useApAging","TrialBalancePage","urlCompany","urlFromDate","urlToDate","setCompany","handleApply","isBalanced","ROOT_ORDER","ChartOfAccountsPage","currentYear","year","setYear","yearOptions","fmt","accounts","childrenOf","rootsByType","byName","a","acc","list","glLink","renderRow","depth","kids","isCollapsed","dim","kid","rt","rootType","toSlug","voucherType","GeneralLedgerPage","urlAccount","urlParty","account","setAccount","party","setParty","StockBalancePage","urlItemCode","urlWarehouse","itemCode","setItemCode","warehouse","setWarehouse","ProfitLossPage","hasData","SectionTable","totalLabel","BalanceSheetPage","urlAsOfDate","asOfDate","setAsOfDate","_c","ArAgingPage","ApAgingPage","buildExampleCustomReport","today","start","EXAMPLE_CUSTOM_REPORT","AnalyticsPage","reportId","metric","groupBy","urlFrom","urlTo","customSpec","setCustomSpec","runtimeData","setRuntimeData","runtimeOutput","setRuntimeOutput","runtimeError","setRuntimeError","running","setRunning","loadingDraft","setLoadingDraft","sourceChatSessionId","setSourceChatSessionId","workerRef","loadedDraftRef","loadedSpecRef","runIdRef","legacySpecText","buildLegacyRuntimeSpec","onRunCustom","specText","runId","isCurrent","spec","dataResponse","worker","ReportRuntimeWorker","timer","cancelled","nextSpec","showLegacyBanner","renderIssues","describeRuntimeOutputIssues","onFixInChat","isDirty","reportLabel","preview","dataset","RuntimeReportRenderer","output","tables","chartTables","buildChartTableIndex","kpi","formatRuntimeValue","chart","xLabels","layout","computeAxisLayout","containerHeight","ResponsiveContainer","CartesianGrid","XAxis","YAxis","shortNum","Tooltip","inferFormat","Line","PieChart","Pie","rowIdx","Cell","PIE_COLORS","BarChart","Bar","column","labelFor","map","issues","legacyMetricLabel","timeBucket","buildGroupedAmountSpec","isReceived","isAr","partyField","amountField","bucketExpr","abs","AXIS_TICK_FONT","_measureCanvas","measureTextWidth","font","labels","widths","maxWidth","angle","radians","projected","axisHeight","CURRENCY_OPTIONS","SetupPage","setCompanyName","setCurrency","details","setDetails","setDetail","seedMode","setSeedMode","success","setSuccess","historyStats","setHistoryStats","createCompanyMut","seedDemoMut","seedHistoryMut","handleSetup","CompanyRow","b","isPending","cityCountry","STEPS","useTryInChat","CompanySetupHighlight","tryInChat","CustomAnalyticsHighlight","samplePrompts","FlowDiagram","chip","LifecycleCard","TutorialPage","step","MAX_ATTACHMENTS","MAX_ATTACHMENT_SIZE","ALLOWED_MIMES","ALLOWED_EXTS","wait","ms","blobToBase64","blob","reader","formatTime","ts","formatFullTimestamp","ChatPage","searchParams","demoRequested","input","setInput","demoError","setDemoError","attachments","setAttachments","attachmentError","setAttachmentError","isDragOver","setIsDragOver","voiceState","setVoiceState","fileInputRef","mediaRecorderRef","audioChunksRef","getIsThinking","scrollContainerRef","messagesEndRef","inputAreaRef","inputAreaHeight","setInputAreaHeight","previousThinkingRef","demoRunStartedRef","demoTypingRunIdRef","shouldAutoScrollRef","pendingPrependHeightRef","programmaticScrollRef","programmaticScrollTimerRef","messages","isConnected","demoStatus","demoTypingCue","isDemoReplaying","canLoadOlder","loadingOlder","lastMessage","lastMessageKey","markProgrammaticScroll","scrollToBottom","behavior","rescroll","useLayoutEffect","prevHeight","delta","raf","observer","handleLoadOlder","consumedNavStateRef","navState","loadHistoryRef","handleMessagesScroll","distanceFromBottom","completeDemoTypingRef","typedCueSeqRef","typingContent","charDelay","typingSeq","animateTyping","char","addFiles","fileList","incoming","ext","localId","previewUrl","removeAttachment","victim","handleDragOver","handleDragLeave","related","handleDrop","handlePaste","files","hasUnfinishedUploads","hasFailedUploads","readyAttachmentIds","sendCurrentMessage","att","handleKeyDown","appendTranscript","startRecording","stream","recorder","track","chunks","mimeType","format","base64","stopRecording","toggleRecording","suggestion","MessageBubble","AttachmentThumbs","url","isImage","MarkdownContent","lines","elements","inCodeBlock","codeLines","line","formatInline","renderLink","isSpaRoute","baseClass","BARE_URL_RE","part","linkMatch","linkifyBare","keyPrefix","nodes","lastIndex","re","matched","trailing","LoginPage","mode","setMode","registrationOpen","setRegistrationOpen","firstRun","setFirstRun","oauthProviders","setOauthProviders","setEmail","setFullName","setPassword","confirmPassword","setConfirmPassword","code","ProviderIcon","providerLabel","DemoPage","startedRef","emptyAccountRow","emptyStockRow","emptyInvoiceRow","OpeningBalancesPage","postingDate","setPostingDate","accountRows","setAccountRows","stockRows","setStockRows","invoiceRows","setInvoiceRows","accountMut","stockMut","invoiceMut","UsersPage","currentUser","users","invites","inviteEmail","setInviteEmail","inviteRole","setInviteRole","inviteResult","setInviteResult","inviteMut","changeRoleMut","disableMut","revokeMut","copiedToken","setCopiedToken","inviteLink","copyInviteLink","invite","SUPPORTED_LANGUAGES","isSupported","getStoredLanguage","storeLanguage","i18n","initReactI18next","en","de","fr","LanguageSelect","DEMO_SPEND_WINDOWS","fmtUsd","TokenSpendCard","demoActive","windowKey","setWindowKey","isFetching","dataUpdatedAt","windowSpec","window","demoCap","demoUsdPerHour","totalUsdPerHour","capPct","capColor","Stat","ChangePasswordCard","setCurrent","setNext","setConfirm","done","setDone","mut","submit","SetPasswordCard","LinkedAccountsCard","setup","identities","providers","linked","isLinked","ROLE_RANK","ApiKeysSection","ownRole","me","setName","setRole","newToken","setNewToken","roleOptions","mcpUrl","claudeSnippet","codexSnippet","keys","isMine","ownerLabel","byOwner","mine","gid","runAction","action","act","ApiToggleRow","onToggle","statusOn","statusOff","ApiAccessCard","chatEnabled","restEnabled","onToggleChat","onToggleRest","confirmOff","setConfirmOff","SettingsPage","isAdmin","settingsMut","pubStatus","health","showConfirm","setShowConfirm","createPubMut","removePubMut","COMPONENTS","registerComponent","component","getComponent","fallback","DashboardRoute","C","Dashboard","baseTopRoutes","Login","Demo","baseChildRoutes","Setup","OpeningBalances","Tutorial","Chat","DocumentList","DocumentForm","MasterList","MasterForm","ChartOfAccounts","TrialBalance","GeneralLedger","StockBalance","ProfitLoss","BalanceSheet","ArAging","ApAging","Analytics","Users","GeneralSettings","extraTopRoutes","extraChildRoutes","registerRoute","route","routeKey","mergeRoutes","buildRoutes","ChatDoctypeRedirect","parentSlug","linkField","alive","parent","registerChatDoctypeRedirects","createAppQueryClient","QueryClient","bootstrap","router","createBrowserRouter","createRoot","StrictMode","QueryClientProvider","RouterProvider","ConfirmButton","confirmLabel","cancelLabel","danger","timeout","cancelSide","armed","setArmed","md","confirmBtn","cancelBtn"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/api/client.ts","../src/contexts/auth-context.tsx","../src/components/chat/chat-provider.tsx","../src/lib/utils.ts","../src/components/ui/button.tsx","../src/components/ui/input.tsx","../src/components/ui/dialog.tsx","../src/lib/nav.tsx","../src/lib/branding.ts","../src/components/layout/sidebar.tsx","../src/components/layout/app-shell.tsx","../src/components/auth/protected-route.tsx","../src/components/ui/card.tsx","../src/components/ui/badge.tsx","../src/components/document/status-badge.tsx","../src/hooks/use-base-currency.ts","../src/pages/dashboard.tsx","../src/lib/doc-list-context.ts","../src/hooks/use-document-list.ts","../src/hooks/use-url-state.ts","../src/lib/doctypes.ts","../src/components/document/doc-pager.tsx","../src/components/ui/select.tsx","../src/components/ui/hint-tooltip.tsx","../src/components/ui/notes-markup-help.tsx","../src/hooks/use-currencies.ts","../src/pages/documents/document-form.tsx","../src/components/ui/date-range-presets.tsx","../src/pages/documents/document-list.tsx","../src/components/document/link-field.tsx","../src/pages/proposals/proposal-form.tsx","../src/pages/masters/master-list.tsx","../src/pages/masters/master-form.tsx","../src/hooks/use-report.ts","../src/pages/reports/trial-balance.tsx","../src/pages/reports/chart-of-accounts.tsx","../src/pages/reports/general-ledger.tsx","../src/pages/reports/stock-balance.tsx","../src/pages/reports/profit-loss.tsx","../src/pages/reports/balance-sheet.tsx","../src/pages/reports/ar-aging.tsx","../src/pages/reports/ap-aging.tsx","../src/pages/reports/analytics.tsx","../src/pages/setup.tsx","../src/pages/tutorial.tsx","../src/pages/chat.tsx","../src/pages/login.tsx","../src/pages/demo.tsx","../src/pages/opening-balances.tsx","../src/pages/admin/users.tsx","../src/i18n/index.ts","../src/components/ui/language-select.tsx","../src/pages/admin/settings.tsx","../src/lib/component-registry.tsx","../src/routes.tsx","../src/lib/chat-doctype-redirects.tsx","../src/bootstrap.tsx","../src/components/ui/confirm-button.tsx"],"sourcesContent":["// API base URL. Defaults to the relative \"/api\" (the demo app and most\n// deployments serve the frontend and backend from the same origin). A\n// customer deployment can point the published library at a different backend\n// either at build time (VITE_API_BASE) or at runtime before any request is\n// made (configureApiBase).\nlet BASE = (import.meta.env.VITE_API_BASE as string | undefined) ?? \"/api\";\n\nexport function configureApiBase(base: string) {\n BASE = base.replace(/\\/+$/, \"\");\n}\n\n// The API origin as a browser-navigable URL. Social login is a full-page\n// redirect (not a fetch), so the button must point the browser straight at the\n// backend endpoint — resolving BASE (which may be relative like \"/api\") against\n// the current origin.\nexport function apiUrl(path: string): string {\n return new URL(`${BASE}${path}`, window.location.origin).toString();\n}\n\nexport class ApiError extends Error {\n constructor(public status: number, message: string) {\n super(message);\n }\n}\n\nfunction formatErrorDetail(detail: unknown): string {\n if (!detail) return \"Request failed\";\n if (typeof detail === \"string\") return detail;\n if (Array.isArray(detail)) {\n const parts = detail.map((item) => {\n if (!item || typeof item !== \"object\") return String(item);\n const rec = item as Record<string, unknown>;\n const loc = Array.isArray(rec.loc) ? rec.loc.join(\".\") : \"\";\n const msg = typeof rec.msg === \"string\" ? rec.msg : JSON.stringify(rec);\n return loc ? `${loc}: ${msg}` : msg;\n });\n return parts.join(\"; \");\n }\n if (typeof detail === \"object\") {\n const rec = detail as Record<string, unknown>;\n if (typeof rec.msg === \"string\") return rec.msg;\n return JSON.stringify(detail);\n }\n return String(detail);\n}\n\nexport async function request<T>(path: string, options?: RequestInit): Promise<T> {\n const res = await fetch(`${BASE}${path}`, {\n headers: { \"Content-Type\": \"application/json\" },\n credentials: \"include\",\n ...options,\n });\n if (!res.ok) {\n if (res.status === 401 && !path.startsWith(\"/auth/\")) {\n window.location.href = \"/login\";\n throw new ApiError(401, \"Session expired\");\n }\n const body = await res.json().catch(() => ({ detail: res.statusText }));\n throw new ApiError(res.status, formatErrorDetail(body.detail));\n }\n return res.json();\n}\n\nfunction qs(params?: Record<string, string | number | undefined>) {\n if (!params) return \"\";\n const clean = Object.fromEntries(\n Object.entries(params).filter(([, v]) => v !== undefined && v !== \"\"),\n );\n const s = new URLSearchParams(clean as Record<string, string>).toString();\n return s ? `?${s}` : \"\";\n}\n\nexport const api = {\n // Generic request (used by sidebar for chat sessions)\n request,\n\n // Chat attachments\n uploadChatAttachment: async (sessionId: string, file: File) => {\n const form = new FormData();\n form.append(\"file\", file);\n form.append(\"session_id\", sessionId);\n const res = await fetch(`${BASE}/chat/attachments`, {\n method: \"POST\",\n credentials: \"include\",\n body: form,\n });\n if (!res.ok) {\n if (res.status === 401) {\n window.location.href = \"/login\";\n throw new ApiError(401, \"Session expired\");\n }\n const body = await res.json().catch(() => ({ detail: res.statusText }));\n throw new ApiError(res.status, body.detail || \"Upload failed\");\n }\n return res.json() as Promise<{\n id: string;\n filename: string;\n mime_type: string;\n size_bytes: number;\n created_at: string;\n warning?: string;\n }>;\n },\n getChatAttachmentUrl: (id: string) => `${BASE}/chat/attachments/${encodeURIComponent(id)}`,\n\n // Chat\n createChatSession: () =>\n request<{ id: string; title: string; created_at: string; updated_at: string; last_message_at?: string | null }>(\n \"/chat/sessions\",\n { method: \"POST\" },\n ),\n\n getChatSession: (id: string) =>\n request<{ id: string; title: string; created_at: string; updated_at: string; last_message_at?: string | null; detail?: string }>(\n `/chat/sessions/${encodeURIComponent(id)}`,\n ),\n\n // Documents\n listDocuments: (doctype: string, params?: Record<string, string | number | undefined>) =>\n request<{ rows: any[]; total: number; limit: number; offset: number }>(\n `/documents/${doctype}${qs(params)}`,\n ),\n\n getDocument: (doctype: string, name: string) =>\n request<any>(`/documents/${doctype}/${encodeURIComponent(name)}`),\n\n // Prev/next record around `name` in the same order+filters the list uses.\n adjacentDocument: (doctype: string, name: string, params?: Record<string, string | number | undefined>) =>\n request<{ prev: string | null; next: string | null }>(\n `/documents/${doctype}/${encodeURIComponent(name)}/adjacent${qs(params)}`,\n ),\n\n // Prev/next master record around `name` in the master list's order (name ASC).\n adjacentMaster: (masterType: string, name: string) =>\n request<{ prev: string | null; next: string | null }>(\n `/masters/${masterType}/${encodeURIComponent(name)}/adjacent`,\n ),\n\n createDocument: (doctype: string, data: any) =>\n request<any>(`/documents/${doctype}`, { method: \"POST\", body: JSON.stringify(data) }),\n\n updateDocument: (doctype: string, name: string, data: any) =>\n request<any>(`/documents/${doctype}/${encodeURIComponent(name)}`, {\n method: \"PUT\",\n body: JSON.stringify(data),\n }),\n\n submitDocument: (doctype: string, name: string) =>\n request<any>(`/documents/${doctype}/${encodeURIComponent(name)}/submit`, { method: \"POST\" }),\n\n cancelDocument: (doctype: string, name: string) =>\n request<any>(`/documents/${doctype}/${encodeURIComponent(name)}/cancel`, { method: \"POST\" }),\n\n discardDocument: (doctype: string, name: string) =>\n request<any>(`/documents/${doctype}/${encodeURIComponent(name)}/discard`, { method: \"POST\" }),\n\n convertDocument: (doctype: string, name: string, targetDoctype: string) =>\n request<any>(`/documents/${doctype}/${encodeURIComponent(name)}/convert`, {\n method: \"POST\",\n body: JSON.stringify({ target_doctype: targetDoctype }),\n }),\n\n // Proposal (Sammelofferte) extras — CRUD goes through the document methods\n // above (doctype \"proposal\"); these cover the appendix blob + cover default.\n getProposalCoverDefault: (company?: string, customer?: string) =>\n request<{ cover_letter: string }>(\n `/proposals/cover-default${qs({ company, customer })}`,\n ),\n\n uploadProposalAppendix: async (name: string, file: File) => {\n const form = new FormData();\n form.append(\"file\", file);\n const res = await fetch(`${BASE}/proposals/${encodeURIComponent(name)}/appendix`, {\n method: \"POST\",\n credentials: \"include\",\n body: form,\n });\n if (!res.ok) {\n if (res.status === 401) {\n window.location.href = \"/login\";\n throw new ApiError(401, \"Session expired\");\n }\n const body = await res.json().catch(() => ({ detail: res.statusText }));\n throw new ApiError(res.status, body.detail || \"Upload failed\");\n }\n return res.json() as Promise<{ appendix_filename: string; size: number }>;\n },\n\n deleteProposalAppendix: (name: string) =>\n request<{ ok: boolean }>(`/proposals/${encodeURIComponent(name)}/appendix`, { method: \"DELETE\" }),\n\n proposalPdfUrl: (name: string) => `${BASE}/documents/proposal/${encodeURIComponent(name)}/pdf`,\n\n // Masters\n listMasters: (type: string, params?: Record<string, string | number | undefined>) =>\n request<{ rows: any[]; total: number; limit: number; offset: number }>(\n `/masters/${type}${qs(params)}`,\n ),\n\n searchMasters: (type: string, q: string) =>\n request<any[]>(`/masters/${type}/search?q=${encodeURIComponent(q)}`),\n\n searchDocuments: (doctype: string, q: string) =>\n request<any[]>(`/documents/${doctype}/search?q=${encodeURIComponent(q)}`),\n\n searchLink: async (type: string, q: string): Promise<any[]> => {\n try {\n const results = await request<any[]>(`/masters/${type}/search?q=${encodeURIComponent(q)}`);\n if (results.length > 0) return results;\n } catch {\n // masters endpoint failed, try documents\n }\n return request<any[]>(`/documents/${type}/search?q=${encodeURIComponent(q)}`);\n },\n\n getMaster: (type: string, name: string) =>\n request<any>(`/masters/${type}/${encodeURIComponent(name)}`),\n\n currencies: (company?: string) =>\n request<{ base_currency: string; currencies: string[] }>(\n `/accounting/currencies${qs({ company })}`,\n ),\n\n createMaster: (type: string, data: any) =>\n request<any>(`/masters/${type}`, { method: \"POST\", body: JSON.stringify(data) }),\n\n updateMaster: (type: string, name: string, data: any) =>\n request<any>(`/masters/${type}/${encodeURIComponent(name)}`, {\n method: \"PUT\",\n body: JSON.stringify(data),\n }),\n\n deleteMaster: (type: string, name: string) =>\n request<any>(`/masters/${type}/${encodeURIComponent(name)}`, { method: \"DELETE\" }),\n\n // Reports\n trialBalance: (params?: Record<string, string>) =>\n request<{ rows: any[]; total_debit: number; total_credit: number; difference: number }>(\n `/reports/trial-balance${qs(params)}`,\n ),\n\n chartOfAccounts: (params?: Record<string, string>) =>\n request<{ accounts: any[]; from_date: string | null; to_date: string | null }>(\n `/reports/chart-of-accounts${qs(params)}`,\n ),\n\n generalLedger: (params?: Record<string, string>) =>\n request<{\n rows: any[];\n total: number;\n limit: number;\n offset: number;\n opening_balance: number;\n }>(`/reports/general-ledger${qs(params)}`),\n\n stockBalance: (params?: Record<string, string>) =>\n request<{ rows: any[] }>(`/reports/stock-balance${qs(params)}`),\n\n dashboardSummary: (company?: string) =>\n request<any>(`/reports/dashboard-summary${qs({ company })}`),\n\n profitAndLoss: (params?: Record<string, string>) =>\n request<any>(`/reports/profit-and-loss${qs(params)}`),\n\n balanceSheet: (params?: Record<string, string>) =>\n request<any>(`/reports/balance-sheet${qs(params)}`),\n\n arAging: (params?: Record<string, string>) =>\n request<any>(`/reports/ar-aging${qs(params)}`),\n\n apAging: (params?: Record<string, string>) =>\n request<any>(`/reports/ap-aging${qs(params)}`),\n\n analyticsMetrics: () =>\n request<{\n metrics: Array<{\n metric: string;\n label: string;\n group_by: string[];\n time_based: boolean;\n }>;\n }>(\"/reports/analytics/metrics\"),\n\n analytics: (params: Record<string, string>) =>\n request<{\n metric: string;\n metric_label: string;\n group_by: string;\n chart_type: \"bar\" | \"line\";\n time_based: boolean;\n from_date: string | null;\n to_date: string | null;\n company: string | null;\n rows: Array<{ label: string; value: number }>;\n total: number;\n }>(`/reports/analytics${qs(params)}`),\n\n runtimeDatasets: () =>\n request<{\n datasets: Array<{\n dataset: string;\n label: string;\n description: string;\n fields: Record<string, string>;\n filter_fields: string[];\n default_limit: number;\n max_limit: number;\n }>;\n }>(\"/reports/runtime/datasets\"),\n\n runtimeData: (data: {\n requests: Array<{\n name?: string;\n dataset: string;\n fields?: string[];\n filters?: Record<string, unknown>;\n limit?: number;\n }>;\n }) =>\n request<{\n datasets: Array<{\n name: string;\n dataset: string;\n rows: Array<Record<string, unknown>>;\n fields: Record<string, string>;\n row_count: number;\n truncated: boolean;\n limit: number;\n }>;\n }>(\"/reports/runtime/data\", { method: \"POST\", body: JSON.stringify(data) }),\n\n createRuntimeDraft: (data: {\n title: string;\n description?: string;\n data_requests: Array<{\n name?: string;\n dataset: string;\n fields?: string[];\n filters?: Record<string, unknown>;\n limit?: number;\n }>;\n transform_js: string;\n }) =>\n request<{\n id: string;\n title: string;\n description?: string;\n definition: Record<string, unknown>;\n url: string;\n created_by?: string;\n }>(\"/reports/runtime/drafts\", { method: \"POST\", body: JSON.stringify(data) }),\n\n getRuntimeDraft: (id: string) =>\n request<{\n id: string;\n title: string;\n description?: string;\n definition: Record<string, unknown>;\n url: string;\n created_by?: string;\n source_chat_session_id?: string;\n created_at?: string;\n updated_at?: string;\n }>(`/reports/runtime/drafts/${encodeURIComponent(id)}`),\n\n listRuntimeDrafts: () =>\n request<{\n drafts: Array<{\n id: string;\n title: string;\n description?: string;\n created_by?: string;\n source_chat_session_id?: string;\n created_at?: string;\n updated_at?: string;\n url: string;\n }>;\n }>(\"/reports/runtime/drafts\"),\n\n deleteRuntimeDraft: (id: string) =>\n request<{ deleted: string }>(`/reports/runtime/drafts/${encodeURIComponent(id)}`, {\n method: \"DELETE\",\n }),\n\n // Setup\n setupStatus: () => request<{ setup_complete: boolean; companies: any[] }>(\"/setup/status\"),\n\n createCompany: (data: {\n name: string;\n currency?: string;\n email?: string;\n phone?: string;\n address?: string;\n city?: string;\n zip_code?: string;\n country?: string;\n tax_id?: string;\n }) => request<any>(\"/setup/company\", { method: \"POST\", body: JSON.stringify(data) }),\n\n seedDemo: () => request<any>(\"/setup/seed-demo\", { method: \"POST\" }),\n\n seedHistory: (data?: { start_date?: string; end_date?: string; seed?: number; intensity?: number }) =>\n request<{ ok: boolean; company: string; start_date: string; end_date: string; stats: Record<string, number> }>(\n \"/setup/seed-history\",\n { method: \"POST\", body: JSON.stringify(data ?? {}) },\n ),\n\n importAccountBalances: (data: any) =>\n request<any>(\"/setup/opening-balances/accounts\", { method: \"POST\", body: JSON.stringify(data) }),\n importStockBalances: (data: any) =>\n request<any>(\"/setup/opening-balances/stock\", { method: \"POST\", body: JSON.stringify(data) }),\n importOutstandingInvoices: (data: any) =>\n request<any>(\"/setup/opening-balances/invoices\", { method: \"POST\", body: JSON.stringify(data) }),\n\n // Auth\n authSetupStatus: () =>\n request<{\n has_users: boolean;\n first_run: boolean;\n public_signup: boolean;\n registration_open: boolean;\n oauth_providers: string[];\n }>(\"/auth/setup-status\"),\n // Social login is a full-page navigation, not a fetch — build the URL the\n // browser should be sent to. `link` starts a \"link to my account\" flow.\n oauthLoginUrl: (provider: string, opts?: { link?: boolean; invite?: string }) => {\n const qs = new URLSearchParams();\n if (opts?.link) qs.set(\"link\", \"1\");\n if (opts?.invite) qs.set(\"invite\", opts.invite);\n const suffix = qs.toString() ? `?${qs.toString()}` : \"\";\n return apiUrl(`/auth/${encodeURIComponent(provider)}/login${suffix}`);\n },\n oauthListIdentities: () => request<{ provider: string; email: string | null; creation: string }[]>(\"/auth/oauth/identities\"),\n authRegister: (data: { email: string; full_name: string; password: string; invite_token?: string }) =>\n request<any>(\"/auth/register\", { method: \"POST\", body: JSON.stringify(data) }),\n authLogin: (email: string, password: string) =>\n request<any>(\"/auth/login\", { method: \"POST\", body: JSON.stringify({ email, password }) }),\n authLogout: () => request<any>(\"/auth/logout\", { method: \"POST\" }),\n authMe: () => request<any>(\"/auth/me\"),\n authChangePassword: (current_password: string, new_password: string) =>\n request<any>(\"/auth/change-password\", {\n method: \"POST\",\n body: JSON.stringify({ current_password, new_password }),\n }),\n authSetPassword: (new_password: string) =>\n request<any>(\"/auth/set-password\", {\n method: \"POST\",\n body: JSON.stringify({ new_password }),\n }),\n authInvite: (email: string, role: string) =>\n request<any>(\"/auth/invite\", { method: \"POST\", body: JSON.stringify({ email, role }) }),\n authListUsers: () => request<any[]>(\"/auth/users\"),\n authChangeRole: (userName: string, role: string) =>\n request<any>(`/auth/users/${encodeURIComponent(userName)}/role`, { method: \"PUT\", body: JSON.stringify({ role }) }),\n authDisableUser: (userName: string) =>\n request<any>(`/auth/users/${encodeURIComponent(userName)}`, { method: \"DELETE\" }),\n authListInvites: () => request<any[]>(\"/auth/invites\"),\n authRevokeInvite: (token: string) =>\n request<any>(`/auth/invites/${encodeURIComponent(token)}`, { method: \"DELETE\" }),\n getPublicManagerStatus: () => request<{ active: boolean; user?: any }>(\"/auth/public-manager\"),\n createPublicManager: () => request<any>(\"/auth/public-manager\", { method: \"POST\" }),\n removePublicManager: () => request<any>(\"/auth/public-manager\", { method: \"DELETE\" }),\n getHealth: () => request<{ status: string; version: string }>(\"/health\"),\n getSettings: () => request<Record<string, string>>(\"/auth/settings\"),\n updateSettings: (data: Record<string, string>) =>\n request<Record<string, string>>(\"/auth/settings\", { method: \"PUT\", body: JSON.stringify(data) }),\n getApiKeys: () =>\n request<Array<{\n id: string; name: string; user?: string; role: string; key_prefix: string;\n created_at?: string; last_used_at?: string | null; revoked: boolean;\n owner_full_name?: string | null; owner_email?: string | null; is_mine?: boolean;\n }>>(\"/auth/api-keys\"),\n createApiKey: (name: string, role: string) =>\n request<{\n id: string; name: string; user?: string; role: string; key_prefix: string; token: string;\n owner_full_name?: string | null; owner_email?: string | null; is_mine?: boolean;\n }>(\"/auth/api-keys\", { method: \"POST\", body: JSON.stringify({ name, role }) }),\n revokeApiKey: (id: string) =>\n request<{ id: string; revoked: boolean }>(\n `/auth/api-keys/${encodeURIComponent(id)}/revoke`, { method: \"POST\" }),\n deleteApiKey: (id: string) =>\n request<{ id: string; deleted: boolean }>(\n `/auth/api-keys/${encodeURIComponent(id)}`, { method: \"DELETE\" }),\n\n getDemoSpend: () =>\n request<{\n caps: { global_hourly_usd: number; per_ip_hourly_usd: number };\n windows: Record<\n string,\n {\n total_usd: number;\n demo_usd: number;\n prompt_tokens: number;\n completion_tokens: number;\n call_count: number;\n unique_ips: number;\n by_provider: Record<\n string,\n {\n cost_usd: number;\n call_count: number;\n prompt_tokens: number;\n completion_tokens: number;\n }\n >;\n }\n >;\n top_ips_24h: Array<{\n ip: string;\n role: string | null;\n cost_usd: number;\n call_count: number;\n }>;\n }>(\"/admin/demo-spend\"),\n};\n","import { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from \"react\";\nimport { api, ApiError } from \"@/api/client\";\n\nexport interface User {\n name: string;\n email: string;\n full_name: string;\n role: \"admin\" | \"manager\" | \"viewer\" | \"public_manager\";\n // Whether the account has a real email+password. Social-login-only users have\n // none (they can set a first one from Settings). Undefined on older sessions\n // until the next /me refresh.\n has_password?: boolean;\n}\n\ninterface AuthContextValue {\n user: User | null;\n loading: boolean;\n login: (email: string, password: string) => Promise<User>;\n register: (email: string, fullName: string, password: string, inviteToken?: string) => Promise<User>;\n logout: () => Promise<void>;\n refreshUser: () => Promise<void>;\n}\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\nexport function AuthProvider({ children }: { children: ReactNode }) {\n const [user, setUser] = useState<User | null>(null);\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n api.authMe()\n .then((u) => setUser(u))\n .catch(() => setUser(null))\n .finally(() => setLoading(false));\n }, []);\n\n const login = useCallback(async (email: string, password: string) => {\n const u = await api.authLogin(email, password);\n setUser(u);\n return u;\n }, []);\n\n const register = useCallback(async (email: string, fullName: string, password: string, inviteToken?: string) => {\n const u = await api.authRegister({ email, full_name: fullName, password, invite_token: inviteToken });\n setUser(u);\n return u;\n }, []);\n\n const logout = useCallback(async () => {\n try { await api.authLogout(); } catch { /* ignore */ }\n setUser(null);\n }, []);\n\n const refreshUser = useCallback(async () => {\n try {\n const u = await api.authMe();\n setUser(u);\n } catch { /* ignore — session check failures are handled elsewhere */ }\n }, []);\n\n return (\n <AuthContext.Provider value={{ user, loading, login, register, logout, refreshUser }}>\n {children}\n </AuthContext.Provider>\n );\n}\n\nexport function useAuth(): AuthContextValue {\n const ctx = useContext(AuthContext);\n if (!ctx) throw new Error(\"useAuth must be used within AuthProvider\");\n return ctx;\n}\n","import {\n createContext,\n useContext,\n useEffect,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { api } from \"@/api/client\";\n\nexport interface ChatSession {\n id: string;\n title: string;\n created_at: string;\n updated_at: string;\n last_message_at?: string | null;\n}\n\nexport interface ChatAttachment {\n id: string;\n filename: string;\n mime_type: string;\n}\n\nexport interface ChatMessage {\n id?: number;\n type: \"user\" | \"assistant\" | \"thinking\" | \"tool_call\" | \"tool_result\" | \"error\";\n content: string;\n tool?: string;\n args?: Record<string, unknown>;\n success?: boolean;\n iteration?: number;\n timestamp?: string;\n attachments?: ChatAttachment[];\n provider?: string;\n model?: string;\n}\n\ntype ConnectionStatus = \"connecting\" | \"connected\" | \"disconnected\";\n\ninterface NavigationFlash {\n group: string;\n item?: string;\n key: number;\n}\n\ninterface PersistedChatMessage {\n id?: number;\n role: string;\n content: string;\n created_at?: string;\n attachments?: ChatAttachment[];\n}\n\ninterface ChatContextValue {\n sessions: ChatSession[];\n connectionStatus: ConnectionStatus;\n connectionVersion: number;\n navigationFlash: NavigationFlash | null;\n createSession: () => Promise<ChatSession>;\n startDemo: (sessionId: string) => Promise<void>;\n completeDemoTyping: (sessionId: string, seq: number) => void;\n deleteSession: (sessionId: string) => Promise<void>;\n loadHistory: (sessionId: string) => Promise<void>;\n loadMoreHistory: (sessionId: string) => Promise<void>;\n clearHistory: (sessionId: string) => Promise<void>;\n sendMessage: (sessionId: string, content: string, attachmentIds?: string[]) => boolean;\n transcribeAudio: (audioBase64: string, audioFormat: string, sessionId?: string) => Promise<string>;\n getMessages: (sessionId?: string) => ChatMessage[];\n hasMoreHistory: (sessionId?: string) => boolean;\n isLoadingOlder: (sessionId?: string) => boolean;\n isThinking: (sessionId?: string) => boolean;\n getDemoStatus: (sessionId?: string) => \"idle\" | \"running\" | \"complete\";\n getDemoTypingCue: (sessionId?: string) => { content: string; seq: number; typingMs: number } | null;\n}\n\ninterface PendingRequest {\n expectedType: string;\n resolve: (value: Record<string, unknown>) => void;\n reject: (error: Error) => void;\n}\n\nconst ChatContext = createContext<ChatContextValue | null>(null);\n\nconst NAV_FLASH_MAP: Record<string, { group: string; item: string }> = {\n \"quotation\": { group: \"Selling\", item: \"Quotation\" },\n \"sales-order\": { group: \"Selling\", item: \"Sales Order\" },\n \"sales-invoice\": { group: \"Selling\", item: \"Sales Invoice\" },\n \"pos-invoice\": { group: \"Selling\", item: \"POS Invoice\" },\n \"purchase-order\": { group: \"Buying\", item: \"Purchase Order\" },\n \"purchase-invoice\": { group: \"Buying\", item: \"Purchase Invoice\" },\n \"payment-entry\": { group: \"Accounting\", item: \"Payment Entry\" },\n \"journal-entry\": { group: \"Accounting\", item: \"Journal Entry\" },\n \"bank-transaction\": { group: \"Accounting\", item: \"Bank Transaction\" },\n \"budget\": { group: \"Accounting\", item: \"Budget\" },\n \"subscription\": { group: \"Accounting\", item: \"Subscription\" },\n \"stock-entry\": { group: \"Stock\", item: \"Stock Entry\" },\n \"delivery-note\": { group: \"Stock\", item: \"Delivery Note\" },\n \"purchase-receipt\": { group: \"Stock\", item: \"Purchase Receipt\" },\n \"pricing-rule\": { group: \"Settings\", item: \"Pricing Rule\" },\n};\n\nconst MASTER_FLASH_MAP: Record<string, { group: string; item: string }> = {\n \"customer\": { group: \"Masters\", item: \"Customer\" },\n \"supplier\": { group: \"Masters\", item: \"Supplier\" },\n \"item\": { group: \"Masters\", item: \"Item\" },\n \"warehouse\": { group: \"Masters\", item: \"Warehouse\" },\n \"company\": { group: \"Masters\", item: \"Company\" },\n};\n\nfunction normalizeDoctype(value: unknown): string | null {\n if (typeof value !== \"string\") return null;\n return value.trim().toLowerCase().replace(/\\s+/g, \"-\");\n}\n\nfunction getNavigationFlashFromTool(tool: string, args?: Record<string, unknown>): { group: string; item: string } | null {\n // Custom analytics tools — flash the sidebar group without targeting an item.\n // (There's no fixed item for custom analytics; the newly touched draft\n // shows up as an entry under the group itself.)\n if (\n tool === \"create_custom_analytics_report\" ||\n tool === \"update_custom_analytics_report\"\n ) {\n return { group: \"Custom Analytics\", item: \"\" };\n }\n\n if (!args) return null;\n\n // Document tools\n let doctype: string | null = null;\n if (\n tool === \"create_document\" ||\n tool === \"update_document\" ||\n tool === \"submit_document\" ||\n tool === \"cancel_document\"\n ) {\n doctype = normalizeDoctype(args.doctype);\n } else if (tool === \"convert_document\") {\n doctype = normalizeDoctype(args.target_doctype);\n }\n if (doctype && NAV_FLASH_MAP[doctype]) {\n return NAV_FLASH_MAP[doctype];\n }\n\n // Master tools\n if (tool === \"create_master\" || tool === \"update_master\") {\n const masterType = normalizeDoctype(args.master_type);\n if (masterType && MASTER_FLASH_MAP[masterType]) {\n return MASTER_FLASH_MAP[masterType];\n }\n }\n\n return null;\n}\n\nfunction mapPersistedMessage(message: PersistedChatMessage): ChatMessage {\n return {\n id: message.id,\n type: message.role === \"user\" ? \"user\" : \"assistant\",\n content: message.content,\n timestamp: message.created_at,\n attachments: message.attachments,\n };\n}\n\nfunction isPersistentMessage(message: ChatMessage): boolean {\n return message.type === \"user\" || message.type === \"assistant\";\n}\n\n// Per-browser memory of chat sessions this visitor has created or opened.\n// Needed because the `public_manager` demo account is shared across all\n// visitors and the server-side list filter hides demo-only chats to prevent\n// pile-up — without this, a visitor's freshly-created demo chat would\n// vanish from the sidebar on page reload.\nconst KNOWN_SESSIONS_KEY = \"lambda-erp:known-chat-sessions\";\n\nfunction getKnownSessionIds(): Set<string> {\n if (typeof localStorage === \"undefined\") return new Set();\n try {\n const raw = localStorage.getItem(KNOWN_SESSIONS_KEY);\n if (!raw) return new Set();\n const parsed = JSON.parse(raw);\n return new Set(Array.isArray(parsed) ? parsed.filter((v) => typeof v === \"string\") : []);\n } catch {\n return new Set();\n }\n}\n\nfunction writeKnownSessionIds(ids: Set<string>) {\n if (typeof localStorage === \"undefined\") return;\n try {\n localStorage.setItem(KNOWN_SESSIONS_KEY, JSON.stringify([...ids]));\n } catch {\n // ignore storage errors (quota / private mode)\n }\n}\n\nexport function rememberSessionId(id: string) {\n const ids = getKnownSessionIds();\n if (ids.has(id)) return;\n ids.add(id);\n writeKnownSessionIds(ids);\n}\n\nfunction forgetSessionId(id: string) {\n const ids = getKnownSessionIds();\n if (!ids.delete(id)) return;\n writeKnownSessionIds(ids);\n}\n\nfunction makeRequestId(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n return `req-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\nfunction toSortTime(timestamp?: string): number {\n if (!timestamp) return 0;\n // Normalize SQLite's space-separated format (\"YYYY-MM-DD HH:MM:SS\") to\n // ISO T-form so it parses consistently with Python `now()` output.\n const s = /^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}/.test(timestamp)\n ? timestamp.replace(\" \", \"T\")\n : timestamp;\n const value = new Date(s).getTime();\n return Number.isNaN(value) ? 0 : value;\n}\n\nexport function ChatProvider({ children }: { children: ReactNode }) {\n const queryClient = useQueryClient();\n const [sessions, setSessions] = useState<ChatSession[]>([]);\n const [messagesBySession, setMessagesBySession] = useState<Record<string, ChatMessage[]>>({});\n const [hasMoreBySession, setHasMoreBySession] = useState<Record<string, boolean>>({});\n const [oldestIdBySession, setOldestIdBySession] = useState<Record<string, number | null>>({});\n const [loadingOlderBySession, setLoadingOlderBySession] = useState<Record<string, boolean>>({});\n const [thinkingBySession, setThinkingBySession] = useState<Record<string, boolean>>({});\n const [demoStatusBySession, setDemoStatusBySession] = useState<Record<string, \"idle\" | \"running\" | \"complete\">>({});\n const [demoTypingCueBySession, setDemoTypingCueBySession] = useState<Record<string, { content: string; seq: number; typingMs: number } | null>>({});\n const [navigationFlash, setNavigationFlash] = useState<NavigationFlash | null>(null);\n const [connectionStatus, setConnectionStatus] = useState<ConnectionStatus>(\"connecting\");\n const [connectionVersion, setConnectionVersion] = useState(0);\n const wsRef = useRef<WebSocket | null>(null);\n const reconnectTimerRef = useRef<number | null>(null);\n const pendingRequestsRef = useRef<Map<string, PendingRequest>>(new Map());\n const pendingCreateSessionRef = useRef<Promise<ChatSession> | null>(null);\n const lastMessageAtRef = useRef<Record<string, string>>({});\n const pendingToolCallsRef = useRef<Record<string, { tool: string; args?: Record<string, unknown> } | null>>({});\n const navFlashTimeoutRef = useRef<number | null>(null);\n\n function rejectPendingRequests(message: string) {\n for (const pending of pendingRequestsRef.current.values()) {\n pending.reject(new Error(message));\n }\n pendingRequestsRef.current.clear();\n }\n\n function updateSessionMessages(sessionId: string, updater: (messages: ChatMessage[]) => ChatMessage[]) {\n setMessagesBySession((prev) => ({\n ...prev,\n [sessionId]: updater(prev[sessionId] ?? []),\n }));\n }\n\n function setSessionThinking(sessionId: string, value: boolean) {\n setThinkingBySession((prev) => ({ ...prev, [sessionId]: value }));\n }\n\n function setSessionDemoStatus(sessionId: string, value: \"idle\" | \"running\" | \"complete\") {\n setDemoStatusBySession((prev) => ({ ...prev, [sessionId]: value }));\n }\n\n function setSessionDemoTypingCue(sessionId: string, value: { content: string; seq: number; typingMs: number } | null) {\n setDemoTypingCueBySession((prev) => ({ ...prev, [sessionId]: value }));\n }\n\n function triggerNavigationFlash(group: string, item?: string) {\n if (navFlashTimeoutRef.current !== null) {\n window.clearTimeout(navFlashTimeoutRef.current);\n }\n setNavigationFlash({ group, item, key: Date.now() });\n navFlashTimeoutRef.current = window.setTimeout(() => {\n setNavigationFlash((prev) => (prev?.group === group && prev?.item === item ? null : prev));\n navFlashTimeoutRef.current = null;\n }, 1100);\n }\n\n function sortSessionsByMessageActivity(sessionList: ChatSession[]): ChatSession[] {\n return [...sessionList].sort((left, right) => {\n const leftTime =\n toSortTime(lastMessageAtRef.current[left.id])\n || toSortTime(left.last_message_at || undefined)\n || toSortTime(left.created_at);\n const rightTime =\n toSortTime(lastMessageAtRef.current[right.id])\n || toSortTime(right.last_message_at || undefined)\n || toSortTime(right.created_at);\n return rightTime - leftTime;\n });\n }\n\n function updateSessionList(updater: (sessions: ChatSession[]) => ChatSession[]) {\n setSessions((prev) => sortSessionsByMessageActivity(updater(prev)));\n }\n\n function recordSessionMessage(sessionId: string, timestamp?: string) {\n const nextTimestamp = timestamp || new Date().toISOString();\n const currentTimestamp = lastMessageAtRef.current[sessionId];\n if (toSortTime(nextTimestamp) >= toSortTime(currentTimestamp)) {\n lastMessageAtRef.current = {\n ...lastMessageAtRef.current,\n [sessionId]: nextTimestamp,\n };\n }\n }\n\n function hydrateLastMessageTimes(sessionList: ChatSession[]) {\n const next = { ...lastMessageAtRef.current };\n for (const session of sessionList) {\n if (session.last_message_at && !next[session.id]) {\n next[session.id] = session.last_message_at;\n }\n }\n lastMessageAtRef.current = next;\n }\n\n function sendRaw(payload: Record<string, unknown>) {\n const ws = wsRef.current;\n if (!ws || ws.readyState !== WebSocket.OPEN) {\n throw new Error(\"Chat is disconnected.\");\n }\n ws.send(JSON.stringify(payload));\n }\n\n function sendRequest(type: string, payload: Record<string, unknown>, expectedType: string): Promise<Record<string, unknown>> {\n return new Promise((resolve, reject) => {\n const requestId = makeRequestId();\n pendingRequestsRef.current.set(requestId, {\n expectedType,\n resolve,\n reject,\n });\n\n try {\n sendRaw({ type, request_id: requestId, ...payload });\n } catch (error) {\n pendingRequestsRef.current.delete(requestId);\n reject(error instanceof Error ? error : new Error(\"Chat request failed.\"));\n }\n });\n }\n\n useEffect(() => {\n let disposed = false;\n\n function connect() {\n if (disposed) return;\n\n setConnectionStatus(\"connecting\");\n\n const protocol = window.location.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n const wsUrl = `${protocol}//${window.location.host}/ws/chat`;\n const ws = new WebSocket(wsUrl);\n wsRef.current = ws;\n\n ws.onopen = () => {\n if (disposed) {\n ws.close();\n return;\n }\n setConnectionStatus(\"connected\");\n setConnectionVersion((prev) => prev + 1);\n };\n\n ws.onmessage = (event) => {\n try {\n const data = JSON.parse(event.data) as Record<string, unknown>;\n const requestId = typeof data.request_id === \"string\" ? data.request_id : null;\n const eventType = typeof data.type === \"string\" ? data.type : null;\n const sessionId = typeof data.session_id === \"string\" ? data.session_id : null;\n\n if (requestId) {\n const pending = pendingRequestsRef.current.get(requestId);\n if (pending) {\n if (eventType === \"error\") {\n pendingRequestsRef.current.delete(requestId);\n pending.reject(new Error(String(data.content || \"Request failed.\")));\n } else if (eventType === pending.expectedType) {\n pendingRequestsRef.current.delete(requestId);\n pending.resolve(data);\n }\n }\n }\n\n if (eventType === \"sessions_list\") {\n const nextSessions = Array.isArray(data.sessions) ? (data.sessions as ChatSession[]) : [];\n hydrateLastMessageTimes(nextSessions);\n setSessions(\n sortSessionsByMessageActivity(\n nextSessions,\n ),\n );\n // Merge in any \"mine\" sessions (tracked per-browser in\n // localStorage) that the server hid from the list because\n // they're demo-only on a shared public_manager account.\n const serverIds = new Set(nextSessions.map((s) => s.id));\n const knownIds = getKnownSessionIds();\n const missing = [...knownIds].filter((id) => !serverIds.has(id));\n if (missing.length > 0) {\n void Promise.all(\n missing.map(async (id) => {\n try {\n const row = await api.getChatSession(id);\n if (!row || row.detail || !row.id) {\n forgetSessionId(id);\n return null;\n }\n return row as ChatSession;\n } catch {\n return null;\n }\n }),\n ).then((fetched) => {\n const resolved = fetched.filter((s): s is ChatSession => !!s);\n if (!resolved.length) return;\n hydrateLastMessageTimes(resolved);\n updateSessionList((prev) => [\n ...resolved.filter((s) => !prev.some((p) => p.id === s.id)),\n ...prev,\n ]);\n });\n }\n return;\n }\n\n if (eventType === \"session_created\") {\n const session = data.session as ChatSession | undefined;\n if (!session) return;\n rememberSessionId(session.id);\n hydrateLastMessageTimes([session]);\n updateSessionList((prev) => [session, ...prev.filter((entry) => entry.id !== session.id)]);\n return;\n }\n\n if (eventType === \"session_deleted\" && sessionId) {\n forgetSessionId(sessionId);\n updateSessionList((prev) => prev.filter((session) => session.id !== sessionId));\n setMessagesBySession((prev) => {\n const next = { ...prev };\n delete next[sessionId];\n return next;\n });\n setThinkingBySession((prev) => {\n const next = { ...prev };\n delete next[sessionId];\n return next;\n });\n setDemoStatusBySession((prev) => {\n const next = { ...prev };\n delete next[sessionId];\n return next;\n });\n setDemoTypingCueBySession((prev) => {\n const next = { ...prev };\n delete next[sessionId];\n return next;\n });\n setHasMoreBySession((prev) => {\n const next = { ...prev };\n delete next[sessionId];\n return next;\n });\n setOldestIdBySession((prev) => {\n const next = { ...prev };\n delete next[sessionId];\n return next;\n });\n setLoadingOlderBySession((prev) => {\n const next = { ...prev };\n delete next[sessionId];\n return next;\n });\n const nextLastMessageAt = { ...lastMessageAtRef.current };\n delete nextLastMessageAt[sessionId];\n lastMessageAtRef.current = nextLastMessageAt;\n return;\n }\n\n if (eventType === \"history_loaded\" && sessionId) {\n const persisted = Array.isArray(data.messages)\n ? (data.messages as PersistedChatMessage[]).map(mapPersistedMessage)\n : [];\n const isPrepend = data.before_id != null;\n const hasMore = Boolean(data.has_more);\n const oldestId =\n typeof data.oldest_id === \"number\" ? data.oldest_id : null;\n\n setMessagesBySession((prev) => {\n if (isPrepend) {\n const existing = prev[sessionId] ?? [];\n const existingIds = new Set(\n existing\n .map((entry) => entry.id)\n .filter((id): id is number => typeof id === \"number\"),\n );\n const filtered = persisted.filter(\n (entry) => entry.id === undefined || !existingIds.has(entry.id),\n );\n return { ...prev, [sessionId]: [...filtered, ...existing] };\n }\n return { ...prev, [sessionId]: persisted };\n });\n\n setHasMoreBySession((prev) => ({ ...prev, [sessionId]: hasMore }));\n setOldestIdBySession((prev) => ({ ...prev, [sessionId]: oldestId }));\n setLoadingOlderBySession((prev) => ({ ...prev, [sessionId]: false }));\n\n const title = typeof data.title === \"string\" ? data.title : null;\n if (title) {\n updateSessionList((prev) =>\n prev.map((session) => (\n session.id === sessionId ? { ...session, title } : session\n )),\n );\n }\n\n if (!isPrepend) {\n const lastPersistedMessage = persisted[persisted.length - 1];\n if (lastPersistedMessage?.timestamp) {\n recordSessionMessage(sessionId, lastPersistedMessage.timestamp);\n updateSessionList((prev) => prev);\n }\n }\n return;\n }\n\n if (eventType === \"history_cleared\" && sessionId) {\n setMessagesBySession((prev) => ({ ...prev, [sessionId]: [] }));\n setHasMoreBySession((prev) => ({ ...prev, [sessionId]: false }));\n setOldestIdBySession((prev) => ({ ...prev, [sessionId]: null }));\n setLoadingOlderBySession((prev) => ({ ...prev, [sessionId]: false }));\n setSessionThinking(sessionId, false);\n setSessionDemoStatus(sessionId, \"idle\");\n setSessionDemoTypingCue(sessionId, null);\n return;\n }\n\n if (eventType === \"message_added\" && sessionId) {\n const message = data.message as PersistedChatMessage | undefined;\n if (!message) return;\n recordSessionMessage(sessionId, message.created_at);\n if (message.role === \"user\") {\n setSessionDemoTypingCue(sessionId, null);\n }\n updateSessionMessages(sessionId, (prev) => [\n ...prev.filter((entry) => entry.type !== \"thinking\"),\n mapPersistedMessage(message),\n ]);\n updateSessionList((prev) => prev);\n return;\n }\n\n if (eventType === \"demo_started\" && sessionId) {\n setSessionDemoStatus(sessionId, \"running\");\n setSessionDemoTypingCue(sessionId, null);\n return;\n }\n\n if (eventType === \"demo_typing\" && sessionId) {\n setSessionDemoStatus(sessionId, \"running\");\n setSessionDemoTypingCue(sessionId, {\n content: String(data.content || \"\"),\n seq: Math.max(0, Number(data.seq || 0)),\n typingMs: Math.max(0, Number(data.typing_ms || 0)),\n });\n return;\n }\n\n if (eventType === \"demo_replay_complete\" && sessionId) {\n setSessionDemoStatus(sessionId, \"complete\");\n setSessionDemoTypingCue(sessionId, null);\n return;\n }\n\n if (eventType === \"navigation_flash\") {\n const group = typeof data.group === \"string\" ? data.group : \"\";\n const item = typeof data.item === \"string\" ? data.item : undefined;\n if (group) {\n triggerNavigationFlash(group, item);\n }\n return;\n }\n\n if (eventType === \"session_title_updated\" && sessionId) {\n const title = typeof data.title === \"string\" ? data.title : \"\";\n updateSessionList((prev) =>\n prev.map((session) => (\n session.id === sessionId ? { ...session, title } : session\n )),\n );\n return;\n }\n\n if (eventType === \"thinking\" && sessionId) {\n setSessionThinking(sessionId, true);\n updateSessionMessages(sessionId, (prev) => {\n const prior = prev.find((m) => m.type === \"thinking\");\n return [\n ...prev.filter((message) => message.type !== \"thinking\"),\n {\n type: \"thinking\",\n content: `Thinking (step ${data.iteration})...`,\n provider: prior?.provider,\n model: prior?.model,\n },\n ];\n });\n return;\n }\n\n if (eventType === \"llm_provider\" && sessionId) {\n const provider = typeof data.provider === \"string\" ? data.provider : undefined;\n const model = typeof data.model === \"string\" ? data.model : undefined;\n const role = typeof data.role === \"string\" ? data.role : undefined;\n const content = role === \"code_specialist\"\n ? \"Delegating to code specialist...\"\n : undefined;\n setSessionThinking(sessionId, true);\n updateSessionMessages(sessionId, (prev) => {\n const hasThinking = prev.some((m) => m.type === \"thinking\");\n if (hasThinking) {\n return prev.map((message) => (\n message.type === \"thinking\"\n ? {\n ...message,\n provider,\n model,\n ...(content ? { content } : {}),\n }\n : message\n ));\n }\n // No active thinking bubble (e.g. we're mid-tool_call and the\n // backend just handed off to the code specialist). Add one so\n // the provider handoff is visible in the UI.\n return [\n ...prev,\n {\n type: \"thinking\",\n content: content ?? \"Thinking...\",\n provider,\n model,\n },\n ];\n });\n return;\n }\n\n if (eventType === \"tool_call\" && sessionId) {\n pendingToolCallsRef.current = {\n ...pendingToolCallsRef.current,\n [sessionId]: {\n tool: String(data.tool || \"\"),\n args: data.args as Record<string, unknown> | undefined,\n },\n };\n updateSessionMessages(sessionId, (prev) => [\n ...prev.filter((message) => message.type !== \"thinking\"),\n {\n type: \"tool_call\",\n content: `Calling ${data.tool}...`,\n tool: data.tool as string,\n args: data.args as Record<string, unknown>,\n },\n ]);\n return;\n }\n\n if (eventType === \"tool_result\" && sessionId) {\n const pendingToolCall = pendingToolCallsRef.current[sessionId];\n if (pendingToolCall && pendingToolCall.tool === String(data.tool || \"\") && Boolean(data.success)) {\n const isCustomAnalyticsTool =\n pendingToolCall.tool === \"create_custom_analytics_report\" ||\n pendingToolCall.tool === \"update_custom_analytics_report\";\n if (isCustomAnalyticsTool) {\n // Prefer the id the backend just committed (covers create);\n // fall back to the tool's own args (covers update with an\n // unreturned id). The item value becomes the draft id so the\n // sidebar can highlight that specific row.\n const backendReportId = typeof data.report_id === \"string\" ? data.report_id : undefined;\n const argReportId = typeof pendingToolCall.args?.report_id === \"string\"\n ? (pendingToolCall.args.report_id as string)\n : undefined;\n const reportId = backendReportId || argReportId || \"\";\n triggerNavigationFlash(\"Custom Analytics\", reportId);\n queryClient.invalidateQueries({ queryKey: [\"runtime-drafts\"] });\n } else {\n const flashTarget = getNavigationFlashFromTool(pendingToolCall.tool, pendingToolCall.args);\n if (flashTarget) {\n triggerNavigationFlash(flashTarget.group, flashTarget.item);\n }\n }\n }\n pendingToolCallsRef.current = {\n ...pendingToolCallsRef.current,\n [sessionId]: null,\n };\n updateSessionMessages(sessionId, (prev) => [\n ...prev,\n {\n type: \"tool_result\",\n content: String(data.summary || \"\"),\n tool: data.tool as string,\n success: Boolean(data.success),\n },\n ]);\n return;\n }\n\n if (eventType === \"complete\" && sessionId) {\n setSessionThinking(sessionId, false);\n updateSessionMessages(sessionId, (prev) => prev.filter((message) => message.type !== \"thinking\"));\n return;\n }\n\n if (eventType === \"error\") {\n if (requestId) {\n return;\n }\n\n if (sessionId) {\n setSessionThinking(sessionId, false);\n updateSessionMessages(sessionId, (prev) => [\n ...prev.filter((message) => message.type !== \"thinking\"),\n { type: \"error\", content: String(data.content || \"Chat error.\") },\n ]);\n }\n }\n } catch {\n // Ignore malformed socket events.\n }\n };\n\n ws.onerror = () => {\n ws.close();\n };\n\n ws.onclose = (event) => {\n if (wsRef.current === ws) {\n wsRef.current = null;\n }\n rejectPendingRequests(\"Chat disconnected.\");\n setConnectionStatus(\"disconnected\");\n if (disposed) return;\n if (event.code === 4001 || event.code === 4003) {\n window.location.href = \"/login\";\n return;\n }\n reconnectTimerRef.current = window.setTimeout(connect, 3000);\n };\n }\n\n connect();\n\n return () => {\n disposed = true;\n if (reconnectTimerRef.current !== null) {\n window.clearTimeout(reconnectTimerRef.current);\n }\n if (navFlashTimeoutRef.current !== null) {\n window.clearTimeout(navFlashTimeoutRef.current);\n }\n rejectPendingRequests(\"Chat disconnected.\");\n if (wsRef.current) {\n const ws = wsRef.current;\n wsRef.current = null;\n ws.close();\n }\n };\n }, []);\n\n async function createSession(): Promise<ChatSession> {\n if (pendingCreateSessionRef.current) {\n return pendingCreateSessionRef.current;\n }\n\n const promise = sendRequest(\"create_session\", {}, \"session_created\")\n .then((data) => data.session as ChatSession)\n .finally(() => {\n if (pendingCreateSessionRef.current === promise) {\n pendingCreateSessionRef.current = null;\n }\n });\n\n pendingCreateSessionRef.current = promise;\n return promise;\n }\n\n async function startDemo(sessionId: string): Promise<void> {\n setSessionDemoStatus(sessionId, \"running\");\n setSessionDemoTypingCue(sessionId, null);\n try {\n await sendRequest(\"start_demo\", { session_id: sessionId }, \"demo_started\");\n } catch (error) {\n setSessionDemoStatus(sessionId, \"idle\");\n throw error;\n }\n }\n\n function completeDemoTyping(sessionId: string, seq: number): void {\n try {\n sendRaw({ type: \"demo_typing_done\", session_id: sessionId, seq });\n } catch {\n // Ignore dropped acknowledgements; backend has a timeout fallback.\n }\n }\n\n async function deleteSession(sessionId: string): Promise<void> {\n await sendRequest(\"delete_session\", { session_id: sessionId }, \"session_deleted\");\n }\n\n async function loadHistory(sessionId: string): Promise<void> {\n await sendRequest(\"load_history\", { session_id: sessionId }, \"history_loaded\");\n }\n\n async function loadMoreHistory(sessionId: string): Promise<void> {\n if (loadingOlderBySession[sessionId]) return;\n const oldestId = oldestIdBySession[sessionId];\n if (oldestId == null) return;\n if (!hasMoreBySession[sessionId]) return;\n setLoadingOlderBySession((prev) => ({ ...prev, [sessionId]: true }));\n try {\n await sendRequest(\n \"load_history\",\n { session_id: sessionId, before_id: oldestId },\n \"history_loaded\",\n );\n } catch (error) {\n setLoadingOlderBySession((prev) => ({ ...prev, [sessionId]: false }));\n throw error;\n }\n }\n\n async function clearHistory(sessionId: string): Promise<void> {\n await sendRequest(\"clear_history\", { session_id: sessionId }, \"history_cleared\");\n }\n\n function sendMessage(sessionId: string, content: string, attachmentIds?: string[]): boolean {\n const trimmed = content.trim();\n const hasAttachments = (attachmentIds?.length ?? 0) > 0;\n if (!trimmed && !hasAttachments) return false;\n\n try {\n setSessionThinking(sessionId, true);\n const payload: Record<string, unknown> = {\n type: \"send_message\",\n session_id: sessionId,\n content: trimmed,\n };\n if (hasAttachments) payload.attachment_ids = attachmentIds;\n sendRaw(payload);\n return true;\n } catch {\n setSessionThinking(sessionId, false);\n return false;\n }\n }\n\n async function transcribeAudio(audioBase64: string, audioFormat: string, sessionId?: string): Promise<string> {\n const data = await sendRequest(\n \"transcribe\",\n { audio_data: audioBase64, audio_format: audioFormat, session_id: sessionId },\n \"transcription_result\",\n );\n if (!data.success) {\n throw new Error(typeof data.error === \"string\" ? data.error : \"Transcription failed.\");\n }\n return typeof data.text === \"string\" ? data.text : \"\";\n }\n\n function getMessages(sessionId?: string): ChatMessage[] {\n if (!sessionId) return [];\n return messagesBySession[sessionId] ?? [];\n }\n\n function isThinking(sessionId?: string): boolean {\n if (!sessionId) return false;\n return Boolean(thinkingBySession[sessionId]);\n }\n\n function hasMoreHistory(sessionId?: string): boolean {\n if (!sessionId) return false;\n return Boolean(hasMoreBySession[sessionId]);\n }\n\n function isLoadingOlder(sessionId?: string): boolean {\n if (!sessionId) return false;\n return Boolean(loadingOlderBySession[sessionId]);\n }\n\n function getDemoStatus(sessionId?: string): \"idle\" | \"running\" | \"complete\" {\n if (!sessionId) return \"idle\";\n return demoStatusBySession[sessionId] ?? \"idle\";\n }\n\n function getDemoTypingCue(sessionId?: string): { content: string; seq: number; typingMs: number } | null {\n if (!sessionId) return null;\n return demoTypingCueBySession[sessionId] ?? null;\n }\n\n return (\n <ChatContext.Provider\n value={{\n sessions,\n connectionStatus,\n connectionVersion,\n navigationFlash,\n createSession,\n startDemo,\n completeDemoTyping,\n deleteSession,\n loadHistory,\n loadMoreHistory,\n clearHistory,\n sendMessage,\n transcribeAudio,\n getMessages,\n hasMoreHistory,\n isLoadingOlder,\n isThinking,\n getDemoStatus,\n getDemoTypingCue,\n }}\n >\n {children}\n </ChatContext.Provider>\n );\n}\n\nexport function useChat(): ChatContextValue {\n const context = useContext(ChatContext);\n if (!context) {\n throw new Error(\"useChat must be used within ChatProvider.\");\n }\n return context;\n}\n","/** Merge class names (simplified clsx). */\nexport function cn(...classes: (string | false | null | undefined)[]) {\n return classes.filter(Boolean).join(\" \");\n}\n\n/** Format a number as currency. */\nexport function formatCurrency(value: number | null | undefined, currency = \"USD\") {\n return new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency,\n minimumFractionDigits: 2,\n }).format(value ?? 0);\n}\n\n/** Format a number with commas. */\nexport function formatNumber(value: number | null | undefined, decimals = 2) {\n return new Intl.NumberFormat(\"en-US\", {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n }).format(value ?? 0);\n}\n\n// Display locale for dates. Default: the viewer's browser locale — the old\n// hardcoded \"en-US\" forced US month/day order (and English month names) on\n// every deployment. A deployment can pin it, e.g. setDateLocale(\"de-CH\") for\n// DD.MM.YYYY everywhere, regardless of the viewer's browser.\nlet dateLocale: string | undefined;\n\n/** Pin the locale used by formatDate (undefined = the viewer's browser locale). */\nexport function setDateLocale(locale: string | undefined) {\n dateLocale = locale;\n}\n\n/** Format a date string for display (numeric, day-first per the locale). */\nexport function formatDate(value: string | null | undefined) {\n if (!value) return \"\";\n return new Date(value).toLocaleDateString(dateLocale, {\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n });\n}\n\n/** Safely parse a float, defaulting to 0. */\nexport function flt(value: unknown, precision?: number): number {\n const n = parseFloat(String(value ?? 0)) || 0;\n return precision !== undefined ? parseFloat(n.toFixed(precision)) : n;\n}\n","import { cn } from \"@/lib/utils\";\n\nconst variantClasses: Record<string, string> = {\n // Primary: brand-coloured fill + a 1px inset top highlight for depth\n // (button-highlight shadow). On press, the button shifts down 1px —\n // tiny detail, large perceived \"this is responsive\".\n primary:\n \"bg-brand text-brand-fg shadow-button-highlight hover:bg-brand/90 active:translate-y-px focus-visible:ring-brand/40\",\n secondary:\n \"bg-surface text-fg ring-1 ring-line hover:bg-surface-subtle active:translate-y-px focus-visible:ring-fg/20\",\n danger:\n \"bg-red-600 text-white shadow-button-highlight hover:bg-red-700 active:translate-y-px focus-visible:ring-red-500/40\",\n ghost:\n \"bg-transparent text-fg-muted hover:bg-surface-subtle hover:text-fg focus-visible:ring-fg/20\",\n};\n\nconst sizeClasses: Record<string, string> = {\n sm: \"h-8 px-3 text-sm\",\n md: \"h-10 px-4 text-sm\",\n lg: \"h-11 px-5 text-sm\",\n};\n\ninterface ButtonProps {\n variant?: \"primary\" | \"secondary\" | \"danger\" | \"ghost\";\n size?: \"sm\" | \"md\" | \"lg\";\n disabled?: boolean;\n onClick?: React.MouseEventHandler<HTMLButtonElement>;\n children: React.ReactNode;\n className?: string;\n type?: \"button\" | \"submit\" | \"reset\";\n}\n\nexport function Button({\n variant = \"primary\",\n size = \"md\",\n disabled,\n onClick,\n children,\n className,\n type = \"button\",\n}: ButtonProps) {\n return (\n <button\n type={type}\n disabled={disabled}\n onClick={onClick}\n className={cn(\n // Layout + base interaction. focus-visible (not :focus) so\n // mouse clicks don't leave a permanent ring; only keyboard\n // navigation gets the visible outline.\n \"inline-flex items-center justify-center gap-2 rounded-lg font-medium\",\n \"transition-all duration-150\",\n \"focus-visible:outline-none focus-visible:ring-2\",\n \"disabled:cursor-not-allowed disabled:opacity-50 disabled:active:translate-y-0\",\n variantClasses[variant],\n sizeClasses[size],\n className,\n )}\n >\n {children}\n </button>\n );\n}\n","import { cn } from \"@/lib/utils\";\n\ninterface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n label?: string;\n /** Optional helper text below the input. */\n hint?: string;\n /** Error text — when set, overrides hint and shows a red border. */\n error?: string;\n}\n\nexport function Input({ label, hint, error, className, id, ...props }: InputProps) {\n const inputId = id || (label ? label.toLowerCase().replace(/\\s+/g, \"-\") : undefined);\n\n return (\n <div>\n {label && (\n <label\n htmlFor={inputId}\n className=\"mb-1.5 block text-sm font-medium text-fg\"\n >\n {label}\n </label>\n )}\n <input\n id={inputId}\n aria-invalid={!!error || undefined}\n aria-describedby={error || hint ? `${inputId}-help` : undefined}\n className={cn(\n // Bigger touch target (h-10) than the previous py-2 default;\n // brand-coloured halo on focus instead of a single hard ring.\n // text-sm is fine on desktop; the global media-query in\n // index.css forces 16px on mobile to suppress iOS auto-zoom.\n \"block h-10 w-full rounded-lg bg-surface px-3 text-sm text-fg\",\n \"ring-1 ring-line transition-all\",\n \"placeholder:text-fg-muted/70\",\n \"focus:outline-none focus:ring-2 focus:ring-brand/30 focus:border-transparent\",\n \"disabled:cursor-not-allowed disabled:bg-surface-subtle disabled:text-fg-muted\",\n error && \"ring-red-400 focus:ring-red-400/30\",\n className,\n )}\n {...props}\n />\n {(error || hint) && (\n <p\n id={`${inputId}-help`}\n className={cn(\n \"mt-1.5 text-xs\",\n error ? \"text-red-600\" : \"text-fg-muted\",\n )}\n >\n {error || hint}\n </p>\n )}\n </div>\n );\n}\n","// Shared, styled confirm/prompt dialogs — a replacement for window.confirm /\n// window.prompt. Mount <DialogProvider> once (AppShell does), then anywhere in\n// the tree call the useConfirm() / usePrompt() hooks:\n//\n// const confirm = useConfirm();\n// if (await confirm({ title: \"Delete?\", danger: true })) { ... }\n//\n// const prompt = usePrompt();\n// const name = await prompt({ title: \"Rename\", defaultValue: current });\n//\n// For low-stakes, in-row actions prefer <ConfirmButton> (confirm-button.tsx),\n// which arms inline instead of opening a modal.\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useState,\n type ReactNode,\n} from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\n\ntype ConfirmOpts = {\n title: string;\n body?: ReactNode;\n confirmLabel?: string;\n cancelLabel?: string;\n danger?: boolean;\n};\n\ntype PromptOpts = ConfirmOpts & {\n defaultValue?: string;\n placeholder?: string;\n inputType?: \"text\" | \"date\" | \"number\";\n};\n\ntype DialogState =\n | { kind: \"confirm\"; opts: ConfirmOpts; resolve: (v: boolean) => void }\n | { kind: \"prompt\"; opts: PromptOpts; resolve: (v: string | null) => void }\n | null;\n\ntype DialogApi = {\n confirm: (opts: ConfirmOpts) => Promise<boolean>;\n prompt: (opts: PromptOpts) => Promise<string | null>;\n};\n\nconst DialogContext = createContext<DialogApi | null>(null);\n\nexport function DialogProvider({ children }: { children: ReactNode }) {\n const { t } = useTranslation();\n const [state, setState] = useState<DialogState>(null);\n const [value, setValue] = useState(\"\");\n\n const confirm = useCallback(\n (opts: ConfirmOpts) =>\n new Promise<boolean>((resolve) => setState({ kind: \"confirm\", opts, resolve })),\n [],\n );\n const prompt = useCallback(\n (opts: PromptOpts) =>\n new Promise<string | null>((resolve) => {\n setValue(opts.defaultValue ?? \"\");\n setState({ kind: \"prompt\", opts, resolve });\n }),\n [],\n );\n\n const api = useMemo<DialogApi>(() => ({ confirm, prompt }), [confirm, prompt]);\n\n const settle = (result: boolean | string | null) => {\n if (!state) return;\n (state.resolve as (v: boolean | string | null) => void)(result);\n setState(null);\n };\n const onConfirm = () => settle(state?.kind === \"prompt\" ? value : true);\n const onCancel = () => settle(state?.kind === \"prompt\" ? null : false);\n\n return (\n <DialogContext.Provider value={api}>\n {children}\n {state && (\n <div\n className=\"fixed inset-0 z-[100] flex items-center justify-center p-4\"\n role=\"dialog\"\n aria-modal=\"true\"\n onKeyDown={(e) => {\n if (e.key === \"Escape\") onCancel();\n }}\n >\n <div className=\"absolute inset-0 bg-black/40 backdrop-blur-[1px]\" onClick={onCancel} />\n <div className=\"relative w-full max-w-md rounded-xl bg-surface p-5 shadow-card ring-1 ring-line\">\n <h2 className=\"text-lg font-semibold text-fg\">{state.opts.title}</h2>\n {state.opts.body != null && (\n <div className=\"mt-2 text-sm text-fg-muted\">{state.opts.body}</div>\n )}\n {state.kind === \"prompt\" && (\n <Input\n autoFocus\n type={state.opts.inputType ?? \"text\"}\n placeholder={state.opts.placeholder}\n value={value}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") onConfirm();\n }}\n className=\"mt-3\"\n />\n )}\n <div className=\"mt-5 flex justify-end gap-2\">\n <Button variant=\"secondary\" onClick={onCancel}>\n {state.opts.cancelLabel ?? t(\"common.cancel\", { defaultValue: \"Cancel\" })}\n </Button>\n <Button variant={state.opts.danger ? \"danger\" : \"primary\"} onClick={onConfirm}>\n {state.opts.confirmLabel ?? t(\"common.ok\", { defaultValue: \"OK\" })}\n </Button>\n </div>\n </div>\n </div>\n )}\n </DialogContext.Provider>\n );\n}\n\nfunction useDialog(): DialogApi {\n const ctx = useContext(DialogContext);\n if (!ctx) throw new Error(\"useConfirm/usePrompt must be used within <DialogProvider>\");\n return ctx;\n}\n\n/** Returns confirm(opts) => Promise<boolean>. Replaces window.confirm. */\nexport function useConfirm() {\n return useDialog().confirm;\n}\n\n/** Returns prompt(opts) => Promise<string|null>. Replaces window.prompt. */\nexport function usePrompt() {\n return useDialog().prompt;\n}\n","/**\n * Sidebar navigation registry.\n *\n * The default groups below drive the demo app's sidebar. A customer\n * deployment built on the published library can add a group, append items to\n * an existing group, or replace a group wholesale via the registration\n * helpers — without editing the sidebar component. The sidebar reads the\n * registry live (getNavGroups), so registrations made at startup show up.\n */\nimport type { ReactNode } from \"react\";\nimport {\n FileText,\n BarChart3,\n Database,\n Package,\n ShoppingCart,\n CreditCard,\n BookOpen,\n Settings,\n} from \"lucide-react\";\n\nexport interface NavItem {\n label: string;\n path: string;\n}\n\nexport interface NavGroup {\n label: string;\n icon: ReactNode;\n items: NavItem[];\n}\n\nconst NAV_GROUPS: NavGroup[] = [\n {\n label: \"Introduction\",\n icon: <BookOpen className=\"h-4 w-4\" />,\n items: [\n { label: \"Getting Started\", path: \"/tutorial\" },\n { label: \"Company Setup\", path: \"/setup\" },\n { label: \"Opening Balances\", path: \"/setup/opening-balances\" },\n ],\n },\n {\n label: \"Selling\",\n icon: <ShoppingCart className=\"h-4 w-4\" />,\n items: [\n { label: \"Quotation\", path: \"/app/quotation\" },\n { label: \"Proposal\", path: \"/app/proposal\" },\n { label: \"Sales Order\", path: \"/app/sales-order\" },\n { label: \"Sales Invoice\", path: \"/app/sales-invoice\" },\n { label: \"POS Invoice\", path: \"/app/pos-invoice\" },\n ],\n },\n {\n label: \"Buying\",\n icon: <CreditCard className=\"h-4 w-4\" />,\n items: [\n { label: \"Purchase Order\", path: \"/app/purchase-order\" },\n { label: \"Purchase Invoice\", path: \"/app/purchase-invoice\" },\n ],\n },\n {\n label: \"Accounting\",\n icon: <FileText className=\"h-4 w-4\" />,\n items: [\n { label: \"Chart of Accounts\", path: \"/reports/chart-of-accounts\" },\n { label: \"Payment Entry\", path: \"/app/payment-entry\" },\n { label: \"Journal Entry\", path: \"/app/journal-entry\" },\n { label: \"Bank Transaction\", path: \"/app/bank-transaction\" },\n { label: \"Budget\", path: \"/app/budget\" },\n { label: \"Subscription\", path: \"/app/subscription\" },\n ],\n },\n {\n label: \"Stock\",\n icon: <Package className=\"h-4 w-4\" />,\n items: [\n { label: \"Stock Entry\", path: \"/app/stock-entry\" },\n { label: \"Delivery Note\", path: \"/app/delivery-note\" },\n { label: \"Purchase Receipt\", path: \"/app/purchase-receipt\" },\n ],\n },\n {\n label: \"Reports\",\n icon: <BarChart3 className=\"h-4 w-4\" />,\n items: [\n { label: \"Trial Balance\", path: \"/reports/trial-balance\" },\n { label: \"Profit & Loss\", path: \"/reports/profit-and-loss\" },\n { label: \"Balance Sheet\", path: \"/reports/balance-sheet\" },\n { label: \"General Ledger\", path: \"/reports/general-ledger\" },\n { label: \"AR Aging\", path: \"/reports/ar-aging\" },\n { label: \"AP Aging\", path: \"/reports/ap-aging\" },\n { label: \"Analytics\", path: \"/reports/analytics\" },\n { label: \"Stock Balance\", path: \"/reports/stock-balance\" },\n ],\n },\n {\n label: \"Masters\",\n icon: <Database className=\"h-4 w-4\" />,\n items: [\n { label: \"Company\", path: \"/masters/company\" },\n { label: \"Customer\", path: \"/masters/customer\" },\n { label: \"Supplier\", path: \"/masters/supplier\" },\n { label: \"Item\", path: \"/masters/item\" },\n { label: \"Warehouse\", path: \"/masters/warehouse\" },\n ],\n },\n {\n label: \"Settings\",\n icon: <Settings className=\"h-4 w-4\" />,\n items: [\n { label: \"General\", path: \"/admin/settings\" },\n { label: \"Pricing Rule\", path: \"/app/pricing-rule\" },\n { label: \"Users & Team\", path: \"/admin/users\" },\n ],\n },\n];\n\n/** Live list the sidebar renders from. */\nexport function getNavGroups(): NavGroup[] {\n return NAV_GROUPS;\n}\n\n/**\n * Add a nav group, or replace an existing one with the same label. Pass\n * `index` to control placement (default: appended at the end).\n */\nexport function registerNavGroup(group: NavGroup, opts?: { index?: number }) {\n const existing = NAV_GROUPS.findIndex((g) => g.label === group.label);\n if (existing >= 0) {\n NAV_GROUPS[existing] = group;\n return;\n }\n if (opts?.index != null) {\n NAV_GROUPS.splice(opts.index, 0, group);\n } else {\n NAV_GROUPS.push(group);\n }\n}\n\n/** Append an item to an existing group (creating the group if absent). */\nexport function registerNavItem(groupLabel: string, item: NavItem) {\n const group = NAV_GROUPS.find((g) => g.label === groupLabel);\n if (group) {\n group.items.push(item);\n } else {\n NAV_GROUPS.push({ label: groupLabel, icon: null, items: [item] });\n }\n}\n","/**\n * Branding / theme configuration.\n *\n * The visual theme is already CSS-variable based (see index.css `:root`\n * tokens, surfaced to Tailwind as `brand`, `surface`, `fg`, `line`, …). A\n * customer deployment built on the published library rebrands by calling\n * `configureBranding` at startup: override the product name, point at a logo,\n * and/or override any of the `:root` design tokens at runtime.\n *\n * For deeper restyling the customer's own Tailwind build (which scans this\n * package — the \"consumer scans source\" model) can add utilities freely; this\n * helper covers the common case of swapping name/logo/colors without a custom\n * stylesheet.\n */\nexport interface Branding {\n /** Product name — used for the document title and as the sidebar fallback. */\n appName: string;\n /** Optional logo URL (falls back to the core CSS-mask logo when unset). */\n logoUrl?: string;\n /**\n * CSS custom properties to set on :root, e.g. { \"--brand\": \"260 80% 55%\" }.\n * The leading \"--\" is optional. Values follow the token format in index.css\n * (HSL channel triplets for color tokens).\n */\n tokens?: Record<string, string>;\n}\n\nlet branding: Branding = { appName: \"Lambda ERP\" };\n\nexport function configureBranding(next: Partial<Branding>) {\n branding = { ...branding, ...next };\n if (typeof document === \"undefined\") return;\n if (next.appName) document.title = next.appName;\n if (next.tokens) {\n const root = document.documentElement;\n for (const [key, value] of Object.entries(next.tokens)) {\n root.style.setProperty(key.startsWith(\"--\") ? key : `--${key}`, value);\n }\n }\n}\n\nexport function getBranding(): Branding {\n return branding;\n}\n","import { useState, useCallback, useEffect, useMemo } from \"react\";\nimport { NavLink, useLocation, useNavigate } from \"react-router-dom\";\nimport { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useTranslation } from \"react-i18next\";\nimport { api } from \"@/api/client\";\n\n// --- Persist collapsed sidebar groups in localStorage ---\nconst STORAGE_KEY = \"sidebar-collapsed\";\n\nfunction getCollapsed(): Set<string> {\n try {\n const raw = localStorage.getItem(STORAGE_KEY);\n return raw ? new Set(JSON.parse(raw)) : new Set();\n } catch {\n return new Set();\n }\n}\n\nfunction setCollapsed(collapsed: Set<string>) {\n localStorage.setItem(STORAGE_KEY, JSON.stringify([...collapsed]));\n}\n\nfunction useSidebarToggle(key: string) {\n const [open, setOpen] = useState(() => !getCollapsed().has(key));\n const toggle = useCallback(() => {\n setOpen((prev) => {\n const collapsed = getCollapsed();\n if (prev) {\n collapsed.add(key);\n } else {\n collapsed.delete(key);\n }\n setCollapsed(collapsed);\n return !prev;\n });\n }, [key]);\n const expand = useCallback(() => {\n setOpen((prev) => {\n if (prev) return prev;\n const collapsed = getCollapsed();\n collapsed.delete(key);\n setCollapsed(collapsed);\n return true;\n });\n }, [key]);\n return [open, toggle, expand] as const;\n}\nimport {\n MessageCircle,\n ChevronDown,\n ChevronRight,\n Plus,\n Trash2,\n LineChart,\n} from \"lucide-react\";\nimport { useMutation } from \"@tanstack/react-query\";\nimport { useChat } from \"@/components/chat/chat-provider\";\nimport { getNavGroups, type NavGroup } from \"@/lib/nav\";\nimport { getBranding } from \"@/lib/branding\";\nimport { cn } from \"@/lib/utils\";\n\nexport const FLASH_STYLES: Record<string, string> = {\n \"Introduction\": \"bg-fuchsia-300 text-fuchsia-950 ring-2 ring-inset ring-fuchsia-100\",\n \"Selling\": \"bg-emerald-300 text-emerald-950 ring-2 ring-inset ring-emerald-100\",\n \"Buying\": \"bg-rose-300 text-rose-950 ring-2 ring-inset ring-rose-100\",\n \"Accounting\": \"bg-amber-300 text-amber-950 ring-2 ring-inset ring-amber-100\",\n \"Stock\": \"bg-blue-300 text-blue-950 ring-2 ring-inset ring-blue-100\",\n \"Reports\": \"bg-indigo-300 text-indigo-950 ring-2 ring-inset ring-indigo-100\",\n \"Masters\": \"bg-lime-300 text-lime-950 ring-2 ring-inset ring-lime-100\",\n \"Settings\": \"bg-purple-300 text-purple-950 ring-2 ring-inset ring-purple-100\",\n \"Custom Analytics\": \"bg-indigo-300 text-indigo-950 ring-2 ring-inset ring-indigo-100\",\n};\n\nfunction ChatGroup() {\n const [open, toggle] = useSidebarToggle(\"chats\");\n const location = useLocation();\n const navigate = useNavigate();\n const { t } = useTranslation();\n const { sessions, createSession, deleteSession } = useChat();\n\n const handleNewChat = async () => {\n try {\n const session = await createSession();\n navigate(`/chat/${session.id}`);\n } catch {\n // ignore\n }\n };\n\n const handleDelete = async (e: React.MouseEvent, sessionId: string) => {\n e.preventDefault();\n e.stopPropagation();\n try {\n await deleteSession(sessionId);\n // If we deleted the active chat, navigate away\n if (window.location.pathname === `/chat/${sessionId}`) {\n navigate(\"/\");\n }\n } catch {\n // ignore\n }\n };\n\n return (\n <div>\n <button\n type=\"button\"\n onClick={toggle}\n className=\"flex w-full items-center gap-2 px-4 py-2 text-xs font-semibold uppercase tracking-wider text-fg-muted transition-colors hover:text-fg\"\n >\n <MessageCircle className=\"h-4 w-4\" />\n <span className=\"flex-1 text-left\">{t(\"nav.chats\")}</span>\n {open ? (\n <ChevronDown className=\"h-3.5 w-3.5\" />\n ) : (\n <ChevronRight className=\"h-3.5 w-3.5\" />\n )}\n </button>\n {open && (\n <ul className=\"mb-1\">\n {/* New Chat button */}\n <li>\n <button\n onClick={handleNewChat}\n className=\"flex w-full items-center gap-2 px-4 py-1.5 pl-10 text-sm text-brand transition-colors hover:bg-brand/5\"\n >\n <Plus className=\"h-3.5 w-3.5\" />\n {t(\"nav.newChat\")}\n </button>\n </li>\n {/* Existing sessions */}\n {sessions.map((session) => {\n const active = location.pathname === `/chat/${session.id}`;\n return (\n <li key={session.id} className=\"group relative\">\n <NavLink\n to={`/chat/${session.id}`}\n className={cn(\n \"relative block truncate px-4 py-1.5 pl-10 pr-8 text-sm transition-colors\",\n active\n ? \"bg-surface-subtle font-medium text-fg\"\n : \"text-fg-muted hover:bg-surface-subtle hover:text-fg\",\n )}\n >\n {session.title}\n </NavLink>\n {active && <ActiveAccent />}\n <button\n onClick={(e) => handleDelete(e, session.id)}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 rounded p-0.5 text-fg-muted opacity-0 transition-opacity hover:text-red-500 group-hover:opacity-100\"\n title={t(\"nav.deleteChat\")}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </button>\n </li>\n );\n })}\n </ul>\n )}\n </div>\n );\n}\n\n/** 2px brand-colored accent strip on the left edge — Linear-style\n * active indicator. Pulled out so all three nav patterns (chats,\n * custom analytics, generic groups) reuse one definition. */\nfunction ActiveAccent() {\n return (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute left-0 top-1/2 h-5 w-[2px] -translate-y-1/2 rounded-r bg-brand\"\n />\n );\n}\n\nfunction CustomAnalyticsGroup() {\n const [open, toggle, expand] = useSidebarToggle(\"custom-analytics\");\n const location = useLocation();\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n const { t } = useTranslation();\n const { navigationFlash, sessions, createSession } = useChat();\n const isGroupFlashing = navigationFlash?.group === \"Custom Analytics\";\n const flashStyle = FLASH_STYLES[\"Custom Analytics\"];\n\n const { data } = useQuery({\n queryKey: [\"runtime-drafts\"],\n queryFn: () => api.listRuntimeDrafts(),\n staleTime: 30_000,\n });\n const drafts = data?.drafts ?? [];\n\n // Any flash targeting this group should expand the group, refetch the\n // draft list, and let the row-level flash animation draw attention to\n // the newly-created / touched entry.\n useEffect(() => {\n if (navigationFlash?.group !== \"Custom Analytics\") return;\n expand();\n queryClient.invalidateQueries({ queryKey: [\"runtime-drafts\"] });\n }, [navigationFlash?.key, queryClient, expand]);\n\n const deleteMutation = useMutation({\n mutationFn: (id: string) => api.deleteRuntimeDraft(id),\n onSuccess: (_result, id) => {\n queryClient.invalidateQueries({ queryKey: [\"runtime-drafts\"] });\n const match = location.search.includes(`report_id=${id}`);\n if (match) navigate(\"/reports/analytics\");\n },\n });\n\n const handleDelete = async (e: React.MouseEvent, id: string) => {\n e.preventDefault();\n e.stopPropagation();\n deleteMutation.mutate(id);\n };\n\n const handleNew = async () => {\n const prefill =\n \"Build me a custom analytics report: <describe what you want — e.g. top 10 customers by revenue for the last quarter, or monthly purchases trend by supplier>\";\n let targetSessionId = sessions[0]?.id || \"\";\n if (!targetSessionId) {\n try {\n const created = await createSession();\n targetSessionId = created.id;\n } catch {\n navigate(\"/reports/analytics\");\n return;\n }\n }\n navigate(`/chat/${targetSessionId}`, { state: { prefillMessage: prefill } });\n };\n\n return (\n <div>\n <button\n type=\"button\"\n onClick={toggle}\n className={cn(\n \"flex w-full items-center gap-2 px-4 py-2 text-xs font-semibold uppercase tracking-wider text-fg-muted transition-all duration-300 hover:text-fg\",\n isGroupFlashing && flashStyle,\n )}\n >\n <LineChart className=\"h-4 w-4\" />\n <span className=\"flex-1 text-left\">{t(\"nav.customAnalytics\")}</span>\n {open ? (\n <ChevronDown className=\"h-3.5 w-3.5\" />\n ) : (\n <ChevronRight className=\"h-3.5 w-3.5\" />\n )}\n </button>\n {open && (\n <ul className=\"mb-1\">\n <li>\n <button\n onClick={handleNew}\n className=\"flex w-full items-center gap-2 px-4 py-1.5 pl-10 text-sm text-brand transition-colors hover:bg-brand/5\"\n >\n <Plus className=\"h-3.5 w-3.5\" />\n {t(\"nav.newAnalytics\")}\n </button>\n </li>\n {drafts.map((draft) => {\n const path = `/reports/analytics?report_id=${draft.id}`;\n const active = location.pathname === \"/reports/analytics\" && location.search.includes(`report_id=${draft.id}`);\n const isItemFlashing =\n navigationFlash?.group === \"Custom Analytics\" &&\n navigationFlash?.item === draft.id;\n return (\n <li key={draft.id} className=\"group relative\">\n <NavLink\n to={path}\n className={cn(\n \"relative block truncate px-4 py-1.5 pl-10 pr-8 text-sm transition-all duration-300\",\n !active && \"text-fg-muted hover:bg-surface-subtle hover:text-fg\",\n active && \"bg-surface-subtle font-medium text-fg\",\n isItemFlashing && flashStyle,\n )}\n title={draft.title}\n >\n {draft.title}\n </NavLink>\n {active && <ActiveAccent />}\n <button\n onClick={(e) => handleDelete(e, draft.id)}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 rounded p-0.5 text-fg-muted opacity-0 transition-opacity hover:text-red-500 group-hover:opacity-100\"\n title={t(\"nav.deleteReport\")}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </button>\n </li>\n );\n })}\n </ul>\n )}\n </div>\n );\n}\n\nfunction SidebarGroup({ group }: { group: NavGroup }) {\n const [open, toggle] = useSidebarToggle(group.label);\n const { t } = useTranslation();\n const { navigationFlash } = useChat();\n const isGroupFlashing = navigationFlash?.group === group.label;\n const flashStyle = FLASH_STYLES[group.label] ?? \"bg-blue-300 text-blue-950 ring-2 ring-inset ring-blue-100\";\n\n return (\n <div>\n <button\n type=\"button\"\n onClick={toggle}\n className={cn(\n \"flex w-full items-center gap-2 px-4 py-2 text-xs font-semibold uppercase tracking-wider text-fg-muted transition-all duration-300 hover:text-fg\",\n isGroupFlashing && flashStyle,\n )}\n >\n {group.icon}\n <span className=\"flex-1 text-left\">{t(`nav.groups.${group.label}`, { defaultValue: group.label })}</span>\n {open ? (\n <ChevronDown className=\"h-3.5 w-3.5\" />\n ) : (\n <ChevronRight className=\"h-3.5 w-3.5\" />\n )}\n </button>\n {open && (\n <ul className=\"mb-1\">\n {group.items.map((item) => {\n // Exact matching when another item's path is nested under this one\n // (e.g. /setup vs /setup/opening-balances). Without `end`, NavLink\n // treats the shorter path as active on the longer one's page, so\n // both rows highlight grey at once.\n const end = group.items.some(\n (other) => other.path !== item.path && other.path.startsWith(item.path + \"/\"),\n );\n return (\n <li key={item.path} className=\"relative\">\n <NavLink\n to={item.path}\n end={end}\n className={({ isActive }) =>\n cn(\n \"relative block px-4 py-1.5 pl-10 text-sm transition-all duration-300\",\n !isActive && \"text-fg-muted hover:bg-surface-subtle hover:text-fg\",\n isActive && \"bg-surface-subtle font-medium text-fg\",\n navigationFlash?.group === group.label && navigationFlash?.item === item.label &&\n flashStyle,\n )\n }\n >\n {({ isActive }) => (\n <>\n {isActive && <ActiveAccent />}\n {t(`nav.items.${item.label}`, { defaultValue: item.label })}\n </>\n )}\n </NavLink>\n </li>\n );\n })}\n </ul>\n )}\n </div>\n );\n}\n\nconst HIDDEN_PATHS: Record<string, string> = {\n \"/setup/opening-balances\": \"opening_balances_enabled\",\n};\n\ninterface SidebarProps {\n isMobileOpen?: boolean;\n onClose?: () => void;\n}\n\nexport function Sidebar({ isMobileOpen = false, onClose }: SidebarProps) {\n const { data: settings } = useQuery({\n queryKey: [\"settings\"],\n queryFn: () => api.getSettings(),\n staleTime: 60_000,\n });\n\n const { data: setupStatus } = useQuery({\n queryKey: [\"setup-status\"],\n queryFn: () => api.setupStatus(),\n staleTime: 60_000,\n });\n\n const firstCompany = setupStatus?.companies?.[0];\n const companyName: string =\n firstCompany?.company_name || firstCompany?.name || getBranding().appName;\n\n const groups = useMemo(() => {\n const base = getNavGroups();\n return base.map((group) => ({\n ...group,\n items: group.items.filter((item) => {\n // Company Setup is a one-time step — hide it once a company exists.\n if (item.path === \"/setup\" && setupStatus?.setup_complete) return false;\n // Settings-gated items (default to shown until settings load).\n const settingKey = HIDDEN_PATHS[item.path];\n if (!settingKey) return true;\n if (!settings) return true;\n return settings[settingKey] !== \"0\";\n }),\n }));\n }, [settings, setupStatus]);\n\n return (\n <aside\n className={cn(\n \"fixed left-0 top-0 z-40 flex h-dvh w-64 flex-col border-r border-line bg-surface transition-transform duration-300 ease-out\",\n \"md:translate-x-0\",\n isMobileOpen ? \"translate-x-0 shadow-2xl\" : \"-translate-x-full\",\n )}\n >\n <div className=\"relative flex h-10 items-center justify-center gap-3 border-b border-line px-4\">\n <NavLink\n to=\"/\"\n className=\"min-w-0 truncate text-base font-semibold text-fg-muted transition-colors hover:text-brand\"\n title={`${companyName} — Dashboard`}\n >\n {companyName}\n </NavLink>\n <div className=\"hidden h-4 w-px shrink-0 bg-line md:block\" aria-hidden=\"true\" />\n <a\n href=\"https://lambda.dev/erp\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label=\"Lambda ERP\"\n title=\"Lambda ERP\"\n className=\"hidden shrink-0 md:block\"\n >\n <span className=\"lambda-logo-icon block\" role=\"img\" aria-label=\"Lambda ERP\" />\n </a>\n {/* Close button — mobile only. Absolute so it doesn't offset centering. */}\n <button\n onClick={onClose}\n className=\"absolute right-3 top-1/2 -translate-y-1/2 rounded p-1 text-fg-muted transition-colors hover:bg-surface-subtle hover:text-fg md:hidden\"\n aria-label=\"Close menu\"\n >\n <svg viewBox=\"0 0 20 20\" width=\"18\" height=\"18\" fill=\"currentColor\">\n <path d=\"M10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 011.414-1.414L10 8.586z\" />\n </svg>\n </button>\n </div>\n <nav className=\"flex-1 overflow-y-auto py-3\">\n <ChatGroup />\n <CustomAnalyticsGroup />\n {groups.map((group) => (\n <SidebarGroup key={group.label} group={group} />\n ))}\n </nav>\n </aside>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport { Outlet, useLocation, useNavigate } from \"react-router-dom\";\nimport { useTranslation } from \"react-i18next\";\nimport type { TFunction } from \"i18next\";\nimport { ArrowLeft } from \"lucide-react\";\nimport { ChatProvider, useChat } from \"@/components/chat/chat-provider\";\nimport { DialogProvider } from \"@/components/ui/dialog\";\nimport { Sidebar, FLASH_STYLES } from \"@/components/layout/sidebar\";\nimport { useAuth } from \"@/contexts/auth-context\";\nimport { cn } from \"@/lib/utils\";\n\nconst titleCase = (slug: string) =>\n slug.replace(/-/g, \" \").replace(/\\b\\w/g, (c) => c.toUpperCase());\n\n// The page title shown in the header. Looks up a translated label by route;\n// any slug without a translation falls back to a title-cased version of itself\n// (so newly-added doctypes still get a sensible English title).\nfunction deriveTitle(pathname: string, t: TFunction): string {\n const parts = pathname.split(\"/\").filter(Boolean);\n\n if (parts[0] === \"setup\") return t(\"titles.setup\");\n if (parts[0] === \"tutorial\") return t(\"titles.tutorial\");\n if (parts[0] === \"chat\") return t(\"titles.chat\");\n\n if (parts[0] === \"reports\") {\n const slug = parts[1] || \"\";\n return t(`titles.${slug}`, { defaultValue: slug ? titleCase(slug) : t(\"titles.reports\") });\n }\n\n if (parts[0] === \"masters\") {\n const type = parts[1] || \"\";\n const cap = type.charAt(0).toUpperCase() + type.slice(1);\n const one = t(`masters.${type}.one`, { defaultValue: cap });\n if (parts[2] === \"new\") return t(\"header.new\", { label: one });\n if (parts[2]) return `${one}: ${decodeURIComponent(parts[2])}`;\n return t(`masters.${type}.other`, { defaultValue: `${cap}s` });\n }\n\n if (parts[0] === \"app\") {\n const slug = parts[1] || \"\";\n const cap = titleCase(slug);\n const one = t(`doctypes.${slug}.one`, { defaultValue: cap });\n if (parts[2] === \"new\") return t(\"header.new\", { label: one });\n if (parts[2]) return `${one}: ${decodeURIComponent(parts[2])}`;\n return t(`doctypes.${slug}.other`, { defaultValue: `${cap}s` });\n }\n\n return t(\"titles.dashboard\");\n}\n\n// Where the header back button leads. Only pages with a natural \"up\" target\n// get one: doctype/master detail + new forms go to their list, the opening\n// balances page goes back to setup. Top-level pages (lists, dashboard,\n// reports, admin) have no parent list, so they show no back button.\nfunction deriveBackPath(pathname: string): string | null {\n const parts = pathname.split(\"/\").filter(Boolean);\n if ((parts[0] === \"app\" || parts[0] === \"masters\") && parts.length > 2) {\n return `/${parts[0]}/${parts[1]}`;\n }\n if (parts[0] === \"setup\" && parts.length > 1) return \"/setup\";\n return null;\n}\n\nexport function AppShell() {\n return (\n <DialogProvider>\n <ChatProvider>\n <AppShellContent />\n </ChatProvider>\n </DialogProvider>\n );\n}\n\nfunction AppShellContent() {\n const { pathname } = useLocation();\n const navigate = useNavigate();\n const { user, logout } = useAuth();\n const { navigationFlash } = useChat();\n const { t } = useTranslation();\n const pageTitle = deriveTitle(pathname, t);\n const backPath = deriveBackPath(pathname);\n\n const handleBack = () => {\n if (!backPath) return;\n // Prefer real history (restores the list's scroll/filter state); the\n // parent path is the fallback for deep links with no in-app history.\n if (window.history.state?.idx > 0) {\n navigate(-1);\n } else {\n navigate(backPath);\n }\n };\n const [mobileOpen, setMobileOpen] = useState(false);\n\n // Auto-close the mobile sidebar on navigation\n useEffect(() => {\n setMobileOpen(false);\n }, [pathname]);\n\n // When a tool fires a navigation flash and the sidebar is hidden (mobile),\n // pulse the hamburger button in the group's flash color instead.\n const flashStyle = navigationFlash ? FLASH_STYLES[navigationFlash.group] : null;\n\n return (\n <div className=\"flex h-dvh bg-surface-muted\">\n <Sidebar isMobileOpen={mobileOpen} onClose={() => setMobileOpen(false)} />\n {/* Mobile backdrop — only shown when sidebar is open on small screens */}\n {mobileOpen && (\n <div\n onClick={() => setMobileOpen(false)}\n className=\"fixed inset-0 z-30 bg-black/40 md:hidden\"\n aria-hidden=\"true\"\n />\n )}\n <div className=\"flex flex-1 flex-col overflow-hidden md:ml-64\">\n <header className=\"flex h-10 shrink-0 items-center justify-between border-b border-gray-200 bg-white px-4 md:px-6\">\n <div className=\"flex items-center gap-3\">\n <button\n onClick={() => setMobileOpen(true)}\n className={cn(\n \"rounded p-1 text-gray-500 transition-all duration-300 hover:bg-gray-100 hover:text-gray-900 md:hidden\",\n flashStyle,\n )}\n aria-label={t(\"header.openMenu\")}\n >\n <svg viewBox=\"0 0 20 20\" fill=\"currentColor\" width=\"22\" height=\"22\">\n <path d=\"M6.835 4c-.451.004-.82.012-1.137.038-.386.032-.659.085-.876.162l-.2.086c-.44.224-.807.564-1.063.982l-.103.184c-.126.247-.206.562-.248 1.076-.043.523-.043 1.19-.043 2.135v2.664c0 .944 0 1.612.043 2.135.042.515.122.829.248 1.076l.103.184c.256.418.624.758 1.063.982l.2.086c.217.077.49.13.876.162.316.026.685.034 1.136.038zm11.33 7.327c0 .922 0 1.654-.048 2.243-.043.522-.125.977-.305 1.395l-.082.177a4 4 0 0 1-1.473 1.593l-.276.155c-.465.237-.974.338-1.57.387-.59.048-1.322.048-2.244.048H7.833c-.922 0-1.654 0-2.243-.048-.522-.042-.977-.126-1.395-.305l-.176-.082a4 4 0 0 1-1.594-1.473l-.154-.275c-.238-.466-.34-.975-.388-1.572-.048-.589-.048-1.32-.048-2.243V8.663c0-.922 0-1.654.048-2.243.049-.597.15-1.106.388-1.571l.154-.276a4 4 0 0 1 1.594-1.472l.176-.083c.418-.18.873-.263 1.395-.305.589-.048 1.32-.048 2.243-.048h4.334c.922 0 1.654 0 2.243.048.597.049 1.106.15 1.571.388l.276.154a4 4 0 0 1 1.473 1.594l.082.176c.18.418.262.873.305 1.395.048.589.048 1.32.048 2.243zm-10 4.668h4.002c.944 0 1.612 0 2.135-.043.514-.042.829-.122 1.076-.248l.184-.103c.418-.256.758-.624.982-1.063l.086-.2c.077-.217.13-.49.162-.876.043-.523.043-1.19.043-2.135V8.663c0-.944 0-1.612-.043-2.135-.032-.386-.085-.659-.162-.876l-.086-.2a2.67 2.67 0 0 0-.982-1.063l-.184-.103c-.247-.126-.562-.206-1.076-.248-.523-.043-1.19-.043-2.135-.043H8.164L8.165 4z\"/>\n </svg>\n </button>\n {backPath && (\n <button\n onClick={handleBack}\n className=\"-ml-1 rounded p-1 text-gray-500 hover:bg-gray-100 hover:text-gray-900\"\n aria-label={t(\"header.back\")}\n >\n <ArrowLeft className=\"h-5 w-5\" />\n </button>\n )}\n <h1 className=\"text-base font-semibold text-gray-500 md:text-lg\">{pageTitle}</h1>\n </div>\n <div className=\"flex items-center gap-3\">\n <span className=\"hidden text-sm text-gray-500 sm:inline\">\n {user?.full_name}\n <span className=\"ml-1.5 rounded bg-gray-100 px-1.5 py-0.5 text-xs font-medium text-gray-600\">\n {user?.role}\n </span>\n </span>\n <button\n onClick={logout}\n className=\"text-sm text-gray-500 hover:text-gray-700\"\n >\n {t(\"header.logout\")}\n </button>\n </div>\n </header>\n <main className=\"flex-1 overflow-auto p-4 md:p-6\">\n <Outlet />\n </main>\n </div>\n </div>\n );\n}\n","import { Navigate } from \"react-router-dom\";\nimport { useAuth } from \"@/contexts/auth-context\";\n\nexport function ProtectedRoute({ children }: { children: React.ReactNode }) {\n const { user, loading } = useAuth();\n\n if (loading) {\n return (\n <div className=\"flex h-dvh items-center justify-center\">\n <div className=\"text-gray-400\">Loading...</div>\n </div>\n );\n }\n\n if (!user) {\n return <Navigate to=\"/login\" replace />;\n }\n\n return <>{children}</>;\n}\n","import { cn } from \"@/lib/utils\";\n\ninterface CardProps {\n title?: string;\n children: React.ReactNode;\n className?: string;\n /** When true, renders the hover-elevation shadow + cursor pointer.\n * Use for cards that the whole tile is clickable. */\n interactive?: boolean;\n}\n\nexport function Card({ title, children, className, interactive }: CardProps) {\n return (\n <div\n className={cn(\n // Surface + 1px hairline ring + multi-layer soft shadow gives\n // the card depth on a tinted page background. The shadow is\n // closer in feel to Linear / Vercel than Tailwind's default\n // shadow-sm, which on white-on-white pages was effectively\n // invisible.\n \"rounded-xl bg-surface p-6 ring-1 ring-line shadow-card transition-all\",\n interactive && \"cursor-pointer hover:shadow-card-hover hover:ring-line/80\",\n className,\n )}\n >\n {title && (\n <h3 className=\"mb-4 text-base font-semibold tracking-tight text-fg\">\n {title}\n </h3>\n )}\n {children}\n </div>\n );\n}\n","import { cn } from \"@/lib/utils\";\n\n// Tinted-background + ring-on-inset + leading dot pattern. Reads as\n// \"modern enterprise\" (Linear, Stripe) compared to the previous\n// solid bg-color-100 / text-color-800 chips.\n//\n// Each variant has three matched tones: a near-white tint as the\n// background, a saturated text colour, and a slightly darker ring.\nconst variantClasses: Record<string, string> = {\n default:\n \"bg-brand/10 text-brand ring-1 ring-inset ring-brand/20\",\n success:\n \"bg-emerald-50 text-emerald-700 ring-1 ring-inset ring-emerald-200\",\n warning:\n \"bg-amber-50 text-amber-700 ring-1 ring-inset ring-amber-200\",\n danger:\n \"bg-rose-50 text-rose-700 ring-1 ring-inset ring-rose-200\",\n secondary:\n \"bg-surface-subtle text-fg-muted ring-1 ring-inset ring-line\",\n};\n\ninterface BadgeProps {\n variant?: \"default\" | \"success\" | \"warning\" | \"danger\" | \"secondary\";\n /** Show a leading status dot. Off by default; turn on for status\n * pills (Draft / Submitted / Cancelled etc.). */\n dot?: boolean;\n children: React.ReactNode;\n className?: string;\n}\n\nexport function Badge({ variant = \"default\", dot, children, className }: BadgeProps) {\n return (\n <span\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-xs font-medium\",\n variantClasses[variant],\n className,\n )}\n >\n {dot && <span className=\"h-1.5 w-1.5 rounded-full bg-current\" />}\n {children}\n </span>\n );\n}\n","import { useTranslation } from \"react-i18next\";\nimport { Badge } from \"@/components/ui/badge\";\n\ntype BadgeVariant = \"default\" | \"success\" | \"warning\" | \"danger\" | \"secondary\";\n\nconst STATUS_VARIANT_MAP: Record<string, BadgeVariant> = {\n Draft: \"secondary\",\n Open: \"default\",\n Submitted: \"default\",\n \"To Deliver and Bill\": \"warning\",\n \"To Deliver\": \"warning\",\n \"To Bill\": \"warning\",\n Completed: \"success\",\n Ordered: \"success\",\n Paid: \"success\",\n Cancelled: \"danger\",\n Discarded: \"secondary\",\n Overdue: \"danger\",\n};\n\ninterface StatusBadgeProps {\n status: string;\n}\n\nexport function StatusBadge({ status }: StatusBadgeProps) {\n const { t } = useTranslation();\n // Variant keys off the backend's English status; only the label is localized.\n const variant = STATUS_VARIANT_MAP[status] ?? \"secondary\";\n\n return <Badge variant={variant}>{t(`status.${status}`, { defaultValue: status })}</Badge>;\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { api } from \"@/api/client\";\n\n/**\n * The company's base/functional currency — what the ledger and all financial\n * statements are expressed in. Reports show this (not per-document currencies).\n * Falls back to USD until the company list loads. Pass a company name to pick\n * its currency in a multi-company setup; otherwise the first company is used.\n */\nexport function useBaseCurrency(company?: string): string {\n const { data } = useQuery({\n queryKey: [\"setup-status\"],\n queryFn: () => api.setupStatus(),\n staleTime: 5 * 60 * 1000,\n });\n const companies: any[] = data?.companies ?? [];\n if (company) {\n const match = companies.find(\n (c) => c.name === company || c.company_name === company,\n );\n if (match?.default_currency) return match.default_currency;\n }\n return companies[0]?.default_currency || \"USD\";\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { Link } from \"react-router-dom\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n TrendingUp,\n ArrowDownRight,\n ArrowUpRight,\n Package,\n Receipt,\n ShoppingCart,\n Wallet,\n FileText,\n type LucideIcon,\n} from \"lucide-react\";\nimport { api } from \"@/api/client\";\nimport { Card } from \"@/components/ui/card\";\nimport { StatusBadge } from \"@/components/document/status-badge\";\nimport { formatCurrency as fmtCurrency, formatDate } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\n\n// ─── Metric cards ──────────────────────────────────────────────────\n\ninterface MetricCardProps {\n title: string;\n value: number | undefined;\n icon: LucideIcon;\n /** Tailwind colour class for the icon halo, e.g. \"text-emerald-600\n * bg-emerald-500/10\". Defaults to brand. */\n tone?: string;\n}\n\nfunction MetricCard({ title, value, icon: Icon, tone }: MetricCardProps) {\n const toneClass = tone ?? \"text-brand bg-brand/10\";\n const baseCurrency = useBaseCurrency();\n const formatCurrency = (v: number | null | undefined) => fmtCurrency(v, baseCurrency);\n return (\n <Card>\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <p className=\"text-sm font-medium text-fg-muted\">{title}</p>\n <p className=\"mt-1.5 text-2xl font-semibold tracking-tight tabular-nums text-fg\">\n {formatCurrency(value ?? 0)}\n </p>\n </div>\n <div className={`shrink-0 rounded-lg p-2 ${toneClass}`}>\n <Icon className=\"h-5 w-5\" strokeWidth={2} />\n </div>\n </div>\n </Card>\n );\n}\n\nfunction MetricCardSkeleton() {\n return (\n <Card>\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"h-4 w-24 animate-pulse rounded bg-surface-subtle\" />\n <div className=\"mt-2.5 h-7 w-32 animate-pulse rounded bg-surface-subtle\" />\n </div>\n <div className=\"h-9 w-9 shrink-0 animate-pulse rounded-lg bg-surface-subtle\" />\n </div>\n </Card>\n );\n}\n\n// ─── Recent documents ──────────────────────────────────────────────\n\n// Each doctype gets a recognisable icon. Falls back to FileText for\n// anything we haven't mapped yet.\nconst DOCTYPE_ICON: Record<string, LucideIcon> = {\n \"Sales Invoice\": Receipt,\n \"Purchase Invoice\": Receipt,\n \"Payment Entry\": Wallet,\n \"Sales Order\": ShoppingCart,\n \"Quotation\": FileText,\n};\n\ninterface RecentDoc {\n doctype?: string;\n type?: string; // legacy field name — kept for backward compat\n name: string;\n status: string;\n creation?: string;\n date?: string; // legacy field name — kept for backward compat\n}\n\nfunction RecentDocumentRow({ doc }: { doc: RecentDoc }) {\n const { t } = useTranslation();\n const doctype = doc.doctype ?? doc.type ?? \"Document\";\n const date = doc.creation ?? doc.date;\n const Icon = DOCTYPE_ICON[doctype] ?? FileText;\n // Doctype slug — e.g. \"Sales Invoice\" → \"sales-invoice\", matching the\n // routes defined in routes.tsx and used by the sidebar.\n const slug = doctype.toLowerCase().replace(/\\s+/g, \"-\");\n const href = `/app/${slug}/${encodeURIComponent(doc.name)}`;\n\n return (\n <Link\n to={href}\n className=\"grid grid-cols-[auto_1fr_auto_auto] items-center gap-3 rounded-lg px-3 py-2.5 transition-colors hover:bg-surface-subtle\"\n >\n <div className=\"rounded-md bg-surface-subtle p-1.5 text-fg-muted\">\n <Icon className=\"h-4 w-4\" strokeWidth={2} />\n </div>\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-medium text-fg\">{doc.name}</div>\n <div className=\"truncate text-xs text-fg-muted\">{t(`nav.items.${doctype}`, { defaultValue: doctype })}</div>\n </div>\n <StatusBadge status={doc.status} />\n <div className=\"hidden text-xs tabular-nums text-fg-muted sm:block\">\n {date ? formatDate(date) : \"—\"}\n </div>\n </Link>\n );\n}\n\nfunction RecentDocumentRowSkeleton() {\n return (\n <div className=\"grid grid-cols-[auto_1fr_auto_auto] items-center gap-3 px-3 py-2.5\">\n <div className=\"h-7 w-7 animate-pulse rounded-md bg-surface-subtle\" />\n <div className=\"min-w-0 space-y-1.5\">\n <div className=\"h-3.5 w-32 animate-pulse rounded bg-surface-subtle\" />\n <div className=\"h-3 w-20 animate-pulse rounded bg-surface-subtle\" />\n </div>\n <div className=\"h-5 w-16 animate-pulse rounded-full bg-surface-subtle\" />\n <div className=\"hidden h-3 w-16 animate-pulse rounded bg-surface-subtle sm:block\" />\n </div>\n );\n}\n\n// ─── Page ──────────────────────────────────────────────────────────\n\nexport default function DashboardPage() {\n const { t } = useTranslation();\n const { data, isLoading } = useQuery({\n queryKey: [\"dashboard-summary\"],\n queryFn: () => api.dashboardSummary(),\n });\n\n return (\n <div className=\"space-y-6\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n {isLoading ? (\n <>\n <MetricCardSkeleton />\n <MetricCardSkeleton />\n <MetricCardSkeleton />\n <MetricCardSkeleton />\n </>\n ) : (\n <>\n <MetricCard\n title={t(\"dashboard.totalRevenue\")}\n value={data?.total_revenue}\n icon={TrendingUp}\n tone=\"text-emerald-600 bg-emerald-500/10\"\n />\n <MetricCard\n title={t(\"dashboard.outstandingReceivable\")}\n value={data?.outstanding_receivable}\n icon={ArrowDownRight}\n tone=\"text-sky-600 bg-sky-500/10\"\n />\n <MetricCard\n title={t(\"dashboard.outstandingPayable\")}\n value={data?.outstanding_payable}\n icon={ArrowUpRight}\n tone=\"text-amber-600 bg-amber-500/10\"\n />\n <MetricCard\n title={t(\"dashboard.totalStockValue\")}\n value={data?.total_stock_value}\n icon={Package}\n tone=\"text-brand bg-brand/10\"\n />\n </>\n )}\n </div>\n\n <Card title={t(\"dashboard.recentDocuments\")}>\n <div className=\"-mx-3 space-y-0.5\">\n {isLoading ? (\n <>\n <RecentDocumentRowSkeleton />\n <RecentDocumentRowSkeleton />\n <RecentDocumentRowSkeleton />\n <RecentDocumentRowSkeleton />\n <RecentDocumentRowSkeleton />\n </>\n ) : data?.recent_documents && data.recent_documents.length > 0 ? (\n data.recent_documents.map((doc: RecentDoc, idx: number) => (\n <RecentDocumentRow key={`${doc.name}-${idx}`} doc={doc} />\n ))\n ) : (\n <div className=\"px-3 py-10 text-center text-sm text-fg-muted\">\n {t(\"dashboard.noRecentDocuments\")}\n </div>\n )}\n </div>\n </Card>\n </div>\n );\n}\n","// Remembers the list a user was last looking at, per doctype — its filters (so a\n// detail page's prev/next stays within that filtered set) and its query string\n// (so \"back to list\" returns to it). Backed by sessionStorage so it survives a\n// detail-page reload; scoped per tab. Read by DocPager on the detail page.\n\nexport type ListContext = {\n /** Filters as the list built them (status / from_date / to_date / …). */\n filters: Record<string, unknown>;\n /** The list's URL query string (e.g. \"?status=Draft\"), for back-to-list. */\n search: string;\n};\n\nconst KEY = \"lad.docListContext\";\n\nfunction readAll(): Record<string, ListContext> {\n try {\n return JSON.parse(sessionStorage.getItem(KEY) || \"{}\");\n } catch {\n return {};\n }\n}\n\nexport function setListContext(doctype: string, ctx: ListContext): void {\n try {\n const all = readAll();\n all[doctype] = ctx;\n sessionStorage.setItem(KEY, JSON.stringify(all));\n } catch {\n /* sessionStorage unavailable — prev/next just falls back to no filters. */\n }\n}\n\nexport function getListContext(doctype: string): ListContext | undefined {\n return readAll()[doctype];\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { api } from \"@/api/client\";\n\nexport function useDocumentList(\n doctype: string,\n filters?: Record<string, string | number | undefined>,\n) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"documents\", doctype, filters],\n queryFn: () => api.listDocuments(doctype, filters),\n enabled: !!doctype,\n });\n\n return { data, isLoading, error, refetch };\n}\n","import { useCallback } from \"react\";\nimport { useSearchParams } from \"react-router-dom\";\n\n/**\n * Atomic multi-param updater. Works around a react-router-dom quirk:\n * calling several `useUrlState` setters in the same handler races, because\n * each functional updater reads the same cached `prev` and the last call\n * wins — silently dropping the other updates. Pass all changes in one call\n * so they land in a single navigate.\n *\n * `null`, `undefined`, or empty string remove the param from the URL.\n */\nexport function useUrlPatch() {\n const [, setParams] = useSearchParams();\n return useCallback(\n (patch: Record<string, string | number | null | undefined>) => {\n setParams(\n (prev) => {\n const p = new URLSearchParams(prev);\n for (const [key, value] of Object.entries(patch)) {\n if (value === \"\" || value == null) {\n p.delete(key);\n } else {\n p.set(key, String(value));\n }\n }\n return p;\n },\n { replace: true },\n );\n },\n [setParams],\n );\n}\n\n/**\n * A URL-backed useState for a single query param.\n *\n * - Initial value is read from the URL; falls back to `defaultValue`.\n * - Updates use `{ replace: true }` so filter/pagination tweaks don't pollute\n * browser history — the Back button still takes the user to where they came\n * from, not through each intermediate filter state.\n * - Values equal to `defaultValue` (and empty strings) are stripped from the\n * URL so a freshly-loaded page doesn't carry a bunch of `?status=All&page=1`\n * noise.\n * - Coerces to number when `defaultValue` is a number.\n */\nexport function useUrlState<T extends string | number>(\n key: string,\n defaultValue: T,\n): [T, (next: T) => void] {\n const [params, setParams] = useSearchParams();\n const raw = params.get(key);\n\n let value: T;\n if (raw === null) {\n value = defaultValue;\n } else if (typeof defaultValue === \"number\") {\n const parsed = Number(raw);\n value = (Number.isFinite(parsed) ? parsed : defaultValue) as T;\n } else {\n value = raw as T;\n }\n\n const setValue = useCallback(\n (next: T) => {\n setParams(\n (prev) => {\n const p = new URLSearchParams(prev);\n if (next === defaultValue || next === \"\" || next == null) {\n p.delete(key);\n } else {\n p.set(key, String(next));\n }\n return p;\n },\n { replace: true },\n );\n },\n [key, defaultValue, setParams],\n );\n\n return [value, setValue];\n}\n","/**\n * Doctype metadata registry.\n *\n * This drives the generic list and form pages. Instead of coding 8 separate\n * pages, a single registry defines the fields, columns, and actions for each\n * document type.\n */\n\nexport interface FieldDef {\n name: string;\n label: string;\n type: \"text\" | \"number\" | \"currency\" | \"date\" | \"link\" | \"select\" | \"textarea\";\n required?: boolean;\n readOnly?: boolean;\n linkDoctype?: string; // for type=link, which master to search\n linkDoctypeField?: string; // for type=link, read the linkDoctype from this sibling field's value (lowercase)\n // For type=select: either plain strings (shown as-is) or {value, label}\n // pairs when the stored value is machine-friendly (e.g. \"1\"/\"0\") but the\n // user-visible label should read differently (\"Yes\"/\"No\").\n options?: Array<string | { value: string; label: string }>;\n // For type=select with a runtime-populated option list. \"currency\" fills the\n // dropdown from the available-currencies endpoint instead of static options.\n optionsSource?: \"currency\";\n default?: any;\n hint?: string; // tooltip text shown via a help icon next to the label\n}\n\nexport interface ChildTableDef {\n label: string;\n key: string; // field name on the parent doc (e.g. \"items\", \"taxes\", \"accounts\")\n fields: FieldDef[];\n}\n\nexport interface ConversionDef {\n label: string;\n targetDoctype: string;\n}\n\nexport interface DoctypeConfig {\n slug: string;\n label: string;\n dateField: string;\n partyField?: string;\n partyLabel?: string;\n amountField?: string;\n fields: FieldDef[];\n childTables: ChildTableDef[];\n listColumns: string[];\n // Field names to expose as dropdown filters above the list. Each must name a\n // `type: \"select\"` field in `fields`; its options drive the dropdown and the\n // selection is sent as a plain column filter (status=Contacted, fit=A). When\n // set, these replace the built-in Draft/Submitted/Cancelled status dropdown —\n // the right call for non-submittable doctypes whose `status` is a business\n // field, not a docstatus. Omit to keep the default status filter.\n listFilters?: string[];\n // Column names the list's free-text search box matches against (case-\n // insensitive substring), e.g. [\"company_name\", \"uid\", \"town\"]. When set, the\n // list shows a debounced search box; the backend can also match via a\n // registered related-table expansion (register_search_expansion). Omit for no\n // search box.\n searchFields?: string[];\n canSubmit: boolean;\n canCancel: boolean;\n conversions: ConversionDef[];\n}\n\n// --- Shared child table definitions ---\n\nconst ITEM_FIELDS: FieldDef[] = [\n { name: \"item_code\", label: \"Item\", type: \"link\", linkDoctype: \"item\", required: true },\n { name: \"item_name\", label: \"Item Name\", type: \"text\", readOnly: true },\n // Per-line description/blurb. Defaults from the Item master on save (an empty\n // value falls back to the master, so leaving it blank never wipes anything);\n // type here to override it for this document only — like a Proposal position.\n { name: \"description\", label: \"Description\", type: \"textarea\" },\n { name: \"qty\", label: \"Qty\", type: \"number\", required: true },\n { name: \"rate\", label: \"Rate\", type: \"currency\", required: true },\n { name: \"amount\", label: \"Amount\", type: \"currency\", readOnly: true },\n];\n\n// Quotation lines additionally carry a billing frequency: one-time or a\n// recurring cadence. Recurring lines are totalled separately on the offer\n// (their own per-period subtotal), so they don't inflate the one-time total.\n// Values match the Subscription billing intervals exactly (kept in English;\n// the branded PDF localizes them for display).\nconst QUOTATION_ITEM_FIELDS: FieldDef[] = [\n ...ITEM_FIELDS,\n {\n name: \"frequency\",\n label: \"Frequency\",\n type: \"select\",\n options: [\"One-time\", \"Monthly\", \"Quarterly\", \"Half-Yearly\", \"Yearly\"],\n default: \"One-time\",\n },\n];\n\n// Transaction currency picker, shared by all sales/purchase documents. The\n// dropdown is populated at runtime (base + convertible currencies) and the\n// form pre-selects the party's (or company's) default currency on new docs.\nconst CURRENCY_FIELD: FieldDef = {\n name: \"currency\", label: \"Currency\", type: \"select\", optionsSource: \"currency\",\n hint: \"The currency this document is transacted in. Defaults from the party's (or the company's) default currency. The ledger still posts in the company base currency, translated at this document's exchange rate.\",\n};\n\nconst TAX_FIELDS: FieldDef[] = [\n {\n name: \"charge_type\", label: \"Type\", type: \"select\",\n options: [\"On Net Total\", \"On Previous Row Amount\", \"On Previous Row Total\", \"Actual\", \"On Item Quantity\"],\n default: \"On Net Total\",\n },\n { name: \"account_head\", label: \"Account\", type: \"link\", linkDoctype: \"account\" },\n { name: \"description\", label: \"Description\", type: \"text\" },\n { name: \"rate\", label: \"Rate (%)\", type: \"number\" },\n { name: \"tax_amount\", label: \"Amount\", type: \"currency\", readOnly: true },\n];\n\n// --- Doctype configs ---\n\nconst CONFIGS: Record<string, DoctypeConfig> = {\n quotation: {\n slug: \"quotation\",\n label: \"Quotation\",\n dateField: \"transaction_date\",\n partyField: \"customer\",\n partyLabel: \"Customer\",\n amountField: \"grand_total\",\n fields: [\n { name: \"customer\", label: \"Customer\", type: \"link\", linkDoctype: \"customer\", required: true },\n { name: \"transaction_date\", label: \"Date\", type: \"date\", required: true },\n { name: \"valid_till\", label: \"Valid Till\", type: \"date\" },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n CURRENCY_FIELD,\n { name: \"net_total\", label: \"Net Total\", type: \"currency\", readOnly: true },\n { name: \"total_taxes_and_charges\", label: \"Tax\", type: \"currency\", readOnly: true },\n { name: \"grand_total\", label: \"Grand Total\", type: \"currency\", readOnly: true },\n { name: \"remarks\", label: \"Notes / Terms\", type: \"textarea\" },\n ],\n childTables: [\n { key: \"items\", label: \"Items\", fields: QUOTATION_ITEM_FIELDS },\n { key: \"taxes\", label: \"Taxes\", fields: TAX_FIELDS },\n ],\n listColumns: [\"name\", \"customer\", \"transaction_date\", \"grand_total\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [\n { label: \"Create Sales Order\", targetDoctype: \"Sales Order\" },\n { label: \"Create Sales Invoice\", targetDoctype: \"Sales Invoice\" },\n { label: \"Create Delivery Note\", targetDoctype: \"Delivery Note\" },\n ],\n },\n\n // Proposal (Sammelofferte) — the form is a custom builder (see\n // pages/proposals/proposal-form.tsx, routed ahead of the generic form). This\n // config only drives the generic LIST page: columns + label + title.\n proposal: {\n slug: \"proposal\",\n label: \"Proposal\",\n dateField: \"proposal_date\",\n partyField: \"customer\",\n partyLabel: \"Customer\",\n fields: [],\n childTables: [],\n listColumns: [\"name\", \"title\", \"customer\", \"modified\"],\n canSubmit: false,\n canCancel: false,\n conversions: [],\n },\n\n \"sales-order\": {\n slug: \"sales-order\",\n label: \"Sales Order\",\n dateField: \"transaction_date\",\n partyField: \"customer\",\n partyLabel: \"Customer\",\n amountField: \"grand_total\",\n fields: [\n { name: \"customer\", label: \"Customer\", type: \"link\", linkDoctype: \"customer\", required: true },\n { name: \"transaction_date\", label: \"Date\", type: \"date\", required: true },\n { name: \"delivery_date\", label: \"Delivery Date\", type: \"date\" },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n CURRENCY_FIELD,\n { name: \"per_delivered\", label: \"% Delivered\", type: \"number\", readOnly: true },\n { name: \"per_billed\", label: \"% Billed\", type: \"number\", readOnly: true },\n { name: \"net_total\", label: \"Net Total\", type: \"currency\", readOnly: true },\n { name: \"grand_total\", label: \"Grand Total\", type: \"currency\", readOnly: true },\n { name: \"remarks\", label: \"Notes / Terms\", type: \"textarea\" },\n ],\n childTables: [\n { key: \"items\", label: \"Items\", fields: ITEM_FIELDS },\n { key: \"taxes\", label: \"Taxes\", fields: TAX_FIELDS },\n ],\n listColumns: [\"name\", \"customer\", \"transaction_date\", \"grand_total\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [\n { label: \"Create Sales Invoice\", targetDoctype: \"Sales Invoice\" },\n { label: \"Create Delivery Note\", targetDoctype: \"Delivery Note\" },\n ],\n },\n\n \"sales-invoice\": {\n slug: \"sales-invoice\",\n label: \"Sales Invoice\",\n dateField: \"posting_date\",\n partyField: \"customer\",\n partyLabel: \"Customer\",\n amountField: \"grand_total\",\n fields: [\n { name: \"customer\", label: \"Customer\", type: \"link\", linkDoctype: \"customer\", required: true },\n { name: \"posting_date\", label: \"Posting Date\", type: \"date\", required: true },\n { name: \"due_date\", label: \"Due Date\", type: \"date\" },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n CURRENCY_FIELD,\n { name: \"net_total\", label: \"Net Total\", type: \"currency\", readOnly: true },\n { name: \"total_taxes_and_charges\", label: \"Tax\", type: \"currency\", readOnly: true },\n { name: \"grand_total\", label: \"Grand Total\", type: \"currency\", readOnly: true },\n { name: \"outstanding_amount\", label: \"Outstanding\", type: \"currency\", readOnly: true },\n { name: \"remarks\", label: \"Notes / Terms\", type: \"textarea\" },\n ],\n childTables: [\n { key: \"items\", label: \"Items\", fields: [...ITEM_FIELDS, { name: \"income_account\", label: \"Income Account\", type: \"link\", linkDoctype: \"account\" }] },\n { key: \"taxes\", label: \"Taxes\", fields: TAX_FIELDS },\n ],\n listColumns: [\"name\", \"customer\", \"posting_date\", \"grand_total\", \"outstanding_amount\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [\n { label: \"Create Credit Note\", targetDoctype: \"Sales Invoice\" },\n ],\n },\n\n \"purchase-order\": {\n slug: \"purchase-order\",\n label: \"Purchase Order\",\n dateField: \"transaction_date\",\n partyField: \"supplier\",\n partyLabel: \"Supplier\",\n amountField: \"grand_total\",\n fields: [\n { name: \"supplier\", label: \"Supplier\", type: \"link\", linkDoctype: \"supplier\", required: true },\n { name: \"transaction_date\", label: \"Date\", type: \"date\", required: true },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n CURRENCY_FIELD,\n { name: \"net_total\", label: \"Net Total\", type: \"currency\", readOnly: true },\n { name: \"grand_total\", label: \"Grand Total\", type: \"currency\", readOnly: true },\n { name: \"remarks\", label: \"Notes / Terms\", type: \"textarea\" },\n ],\n childTables: [\n { key: \"items\", label: \"Items\", fields: [...ITEM_FIELDS, { name: \"warehouse\", label: \"Warehouse\", type: \"link\", linkDoctype: \"warehouse\" }] },\n { key: \"taxes\", label: \"Taxes\", fields: TAX_FIELDS },\n ],\n listColumns: [\"name\", \"supplier\", \"transaction_date\", \"grand_total\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [\n { label: \"Create Purchase Invoice\", targetDoctype: \"Purchase Invoice\" },\n { label: \"Create Purchase Receipt\", targetDoctype: \"Purchase Receipt\" },\n ],\n },\n\n \"purchase-invoice\": {\n slug: \"purchase-invoice\",\n label: \"Purchase Invoice\",\n dateField: \"posting_date\",\n partyField: \"supplier\",\n partyLabel: \"Supplier\",\n amountField: \"grand_total\",\n fields: [\n { name: \"supplier\", label: \"Supplier\", type: \"link\", linkDoctype: \"supplier\", required: true },\n { name: \"posting_date\", label: \"Posting Date\", type: \"date\", required: true },\n { name: \"due_date\", label: \"Due Date\", type: \"date\" },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n CURRENCY_FIELD,\n { name: \"update_stock\", label: \"Update Stock\", type: \"select\",\n options: [{ value: \"0\", label: \"No\" }, { value: \"1\", label: \"Yes\" }], default: \"0\",\n hint: \"If Yes, submitting this invoice also receives stock into the item warehouses.\",\n },\n { name: \"net_total\", label: \"Net Total\", type: \"currency\", readOnly: true },\n { name: \"grand_total\", label: \"Grand Total\", type: \"currency\", readOnly: true },\n { name: \"outstanding_amount\", label: \"Outstanding\", type: \"currency\", readOnly: true },\n { name: \"remarks\", label: \"Notes / Terms\", type: \"textarea\" },\n ],\n childTables: [\n {\n key: \"items\",\n label: \"Items\",\n fields: [\n ...ITEM_FIELDS,\n { name: \"warehouse\", label: \"Warehouse\", type: \"link\", linkDoctype: \"warehouse\",\n hint: \"Required when Update Stock is Yes — the received goods land in this warehouse.\",\n },\n { name: \"expense_account\", label: \"Expense Account\", type: \"link\", linkDoctype: \"account\" },\n ],\n },\n { key: \"taxes\", label: \"Taxes\", fields: TAX_FIELDS },\n ],\n listColumns: [\"name\", \"supplier\", \"posting_date\", \"grand_total\", \"outstanding_amount\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [\n { label: \"Create Debit Note\", targetDoctype: \"Purchase Invoice\" },\n ],\n },\n\n \"payment-entry\": {\n slug: \"payment-entry\",\n label: \"Payment Entry\",\n dateField: \"posting_date\",\n partyField: \"party\",\n partyLabel: \"Party\",\n amountField: \"paid_amount\",\n fields: [\n {\n name: \"payment_type\", label: \"Payment Type\", type: \"select\",\n options: [\"Receive\", \"Pay\", \"Internal Transfer\"], required: true,\n hint: \"Receive: customer pays you. Pay: you pay a supplier. Internal Transfer: move money between your own accounts.\",\n },\n { name: \"posting_date\", label: \"Posting Date\", type: \"date\", required: true },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n { name: \"party_type\", label: \"Party Type\", type: \"select\", options: [\"Customer\", \"Supplier\"],\n hint: \"Select Customer when receiving money, Supplier when paying.\",\n },\n { name: \"party\", label: \"Party\", type: \"link\", linkDoctypeField: \"party_type\" },\n { name: \"paid_from\", label: \"Paid From\", type: \"link\", linkDoctype: \"account\",\n hint: \"The account money is coming from (e.g. Accounts Receivable when receiving, Bank when paying).\",\n },\n { name: \"paid_to\", label: \"Paid To\", type: \"link\", linkDoctype: \"account\",\n hint: \"The account money is going to (e.g. Bank when receiving, Accounts Payable when paying).\",\n },\n { name: \"paid_amount\", label: \"Paid Amount\", type: \"currency\", required: true,\n hint: \"The total amount of money changing hands. This is the amount that hits the bank account.\",\n },\n ],\n childTables: [\n {\n key: \"references\", label: \"Payment References\", fields: [\n { name: \"reference_doctype\", label: \"Type\", type: \"select\", options: [\"Sales Invoice\", \"Purchase Invoice\"], default: \"Sales Invoice\" },\n { name: \"reference_name\", label: \"Invoice\", type: \"link\", linkDoctypeField: \"reference_doctype\",\n hint: \"The invoice this payment is being applied against.\",\n },\n { name: \"total_amount\", label: \"Total\", type: \"currency\", readOnly: true,\n hint: \"The full amount of the referenced invoice.\",\n },\n { name: \"outstanding_amount\", label: \"Outstanding\", type: \"currency\", readOnly: true,\n hint: \"How much is still unpaid on this invoice.\",\n },\n { name: \"allocated_amount\", label: \"Allocated\", type: \"currency\",\n hint: \"How much of this payment to apply against this invoice. Can be less than Paid Amount for partial payments, or split across multiple invoices.\",\n },\n ],\n },\n ],\n listColumns: [\"name\", \"payment_type\", \"party\", \"posting_date\", \"paid_amount\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [],\n },\n\n \"journal-entry\": {\n slug: \"journal-entry\",\n label: \"Journal Entry\",\n dateField: \"posting_date\",\n amountField: \"total_debit\",\n fields: [\n { name: \"posting_date\", label: \"Posting Date\", type: \"date\", required: true },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n { name: \"remark\", label: \"Remark\", type: \"textarea\" },\n { name: \"total_debit\", label: \"Total Debit\", type: \"currency\", readOnly: true },\n { name: \"total_credit\", label: \"Total Credit\", type: \"currency\", readOnly: true },\n ],\n childTables: [\n {\n key: \"accounts\", label: \"Account Entries\", fields: [\n { name: \"account\", label: \"Account\", type: \"link\", linkDoctype: \"account\", required: true },\n { name: \"party_type\", label: \"Party Type\", type: \"select\", options: [\"\", \"Customer\", \"Supplier\"] },\n { name: \"party\", label: \"Party\", type: \"link\", linkDoctypeField: \"party_type\" },\n { name: \"debit\", label: \"Debit\", type: \"currency\" },\n { name: \"credit\", label: \"Credit\", type: \"currency\" },\n { name: \"cost_center\", label: \"Cost Center\", type: \"link\", linkDoctype: \"cost-center\" },\n ],\n },\n ],\n listColumns: [\"name\", \"posting_date\", \"remark\", \"total_debit\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [],\n },\n\n \"stock-entry\": {\n slug: \"stock-entry\",\n label: \"Stock Entry\",\n dateField: \"posting_date\",\n amountField: \"total_amount\",\n fields: [\n {\n name: \"stock_entry_type\", label: \"Type\", type: \"select\",\n options: [\"Material Receipt\", \"Material Issue\", \"Material Transfer\", \"Opening Stock\"], required: true,\n hint: \"Opening Stock is for one-time initial inventory (contra: Opening Balance Equity). Material Receipt/Issue are for adjustments and write-offs (contra: Stock Adjustment).\",\n },\n { name: \"posting_date\", label: \"Posting Date\", type: \"date\", required: true },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n { name: \"from_warehouse\", label: \"Source Warehouse\", type: \"link\", linkDoctype: \"warehouse\" },\n { name: \"to_warehouse\", label: \"Target Warehouse\", type: \"link\", linkDoctype: \"warehouse\" },\n { name: \"total_incoming_value\", label: \"Incoming Value\", type: \"currency\", readOnly: true },\n { name: \"total_outgoing_value\", label: \"Outgoing Value\", type: \"currency\", readOnly: true },\n ],\n childTables: [\n {\n key: \"items\", label: \"Items\", fields: [\n { name: \"item_code\", label: \"Item\", type: \"link\", linkDoctype: \"item\", required: true },\n { name: \"item_name\", label: \"Item Name\", type: \"text\", readOnly: true },\n { name: \"qty\", label: \"Qty\", type: \"number\", required: true },\n { name: \"s_warehouse\", label: \"Source\", type: \"link\", linkDoctype: \"warehouse\" },\n { name: \"t_warehouse\", label: \"Target\", type: \"link\", linkDoctype: \"warehouse\" },\n { name: \"basic_rate\", label: \"Rate\", type: \"currency\" },\n { name: \"basic_amount\", label: \"Amount\", type: \"currency\", readOnly: true },\n ],\n },\n ],\n listColumns: [\"name\", \"stock_entry_type\", \"posting_date\", \"total_amount\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [],\n },\n\n \"delivery-note\": {\n slug: \"delivery-note\",\n label: \"Delivery Note\",\n dateField: \"posting_date\",\n partyField: \"customer\",\n partyLabel: \"Customer\",\n amountField: \"grand_total\",\n fields: [\n { name: \"customer\", label: \"Customer\", type: \"link\", linkDoctype: \"customer\", required: true },\n { name: \"posting_date\", label: \"Posting Date\", type: \"date\", required: true },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n CURRENCY_FIELD,\n { name: \"net_total\", label: \"Net Total\", type: \"currency\", readOnly: true },\n { name: \"total_taxes_and_charges\", label: \"Tax\", type: \"currency\", readOnly: true },\n { name: \"grand_total\", label: \"Grand Total\", type: \"currency\", readOnly: true },\n { name: \"remarks\", label: \"Notes / Terms\", type: \"textarea\" },\n ],\n childTables: [\n {\n key: \"items\", label: \"Items\", fields: [\n ...ITEM_FIELDS,\n { name: \"warehouse\", label: \"Warehouse\", type: \"link\", linkDoctype: \"warehouse\", required: true },\n ],\n },\n { key: \"taxes\", label: \"Taxes\", fields: TAX_FIELDS },\n ],\n listColumns: [\"name\", \"customer\", \"posting_date\", \"grand_total\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [\n { label: \"Create Return\", targetDoctype: \"Delivery Note\" },\n ],\n },\n\n \"purchase-receipt\": {\n slug: \"purchase-receipt\",\n label: \"Purchase Receipt\",\n dateField: \"posting_date\",\n partyField: \"supplier\",\n partyLabel: \"Supplier\",\n amountField: \"grand_total\",\n fields: [\n { name: \"supplier\", label: \"Supplier\", type: \"link\", linkDoctype: \"supplier\", required: true },\n { name: \"posting_date\", label: \"Posting Date\", type: \"date\", required: true },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n CURRENCY_FIELD,\n { name: \"net_total\", label: \"Net Total\", type: \"currency\", readOnly: true },\n { name: \"total_taxes_and_charges\", label: \"Tax\", type: \"currency\", readOnly: true },\n { name: \"grand_total\", label: \"Grand Total\", type: \"currency\", readOnly: true },\n { name: \"remarks\", label: \"Notes / Terms\", type: \"textarea\" },\n ],\n childTables: [\n {\n key: \"items\", label: \"Items\", fields: [\n ...ITEM_FIELDS,\n { name: \"warehouse\", label: \"Warehouse\", type: \"link\", linkDoctype: \"warehouse\", required: true },\n ],\n },\n { key: \"taxes\", label: \"Taxes\", fields: TAX_FIELDS },\n ],\n listColumns: [\"name\", \"supplier\", \"posting_date\", \"grand_total\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [\n { label: \"Create Return\", targetDoctype: \"Purchase Receipt\" },\n ],\n },\n\n \"pos-invoice\": {\n slug: \"pos-invoice\",\n label: \"POS Invoice\",\n dateField: \"posting_date\",\n partyField: \"customer\",\n partyLabel: \"Customer\",\n amountField: \"grand_total\",\n fields: [\n { name: \"customer\", label: \"Customer\", type: \"link\", linkDoctype: \"customer\", required: true },\n { name: \"posting_date\", label: \"Posting Date\", type: \"date\", required: true },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n CURRENCY_FIELD,\n { name: \"update_stock\", label: \"Update Stock\", type: \"select\",\n options: [{ value: \"1\", label: \"Yes\" }, { value: \"0\", label: \"No\" }], default: \"1\",\n hint: \"If Yes, submitting this invoice also reduces stock from the item warehouses.\",\n },\n { name: \"net_total\", label: \"Net Total\", type: \"currency\", readOnly: true },\n { name: \"total_taxes_and_charges\", label: \"Tax\", type: \"currency\", readOnly: true },\n { name: \"grand_total\", label: \"Grand Total\", type: \"currency\", readOnly: true },\n { name: \"paid_amount\", label: \"Paid Amount\", type: \"currency\", readOnly: true },\n { name: \"change_amount\", label: \"Change\", type: \"currency\", readOnly: true },\n ],\n childTables: [\n {\n key: \"items\", label: \"Items\", fields: [\n ...ITEM_FIELDS,\n { name: \"warehouse\", label: \"Warehouse\", type: \"link\", linkDoctype: \"warehouse\",\n hint: \"Required when Update Stock is Yes — this is where stock is drawn from.\",\n },\n ],\n },\n { key: \"taxes\", label: \"Taxes\", fields: TAX_FIELDS },\n {\n key: \"payments\", label: \"Payments\", fields: [\n { name: \"mode_of_payment\", label: \"Mode\", type: \"select\", options: [\"Cash\", \"Card\", \"Bank Transfer\"], default: \"Cash\" },\n { name: \"account\", label: \"Account\", type: \"link\", linkDoctype: \"account\" },\n { name: \"amount\", label: \"Amount\", type: \"currency\", required: true },\n ],\n },\n ],\n listColumns: [\"name\", \"customer\", \"posting_date\", \"grand_total\", \"status\"],\n canSubmit: true,\n canCancel: true,\n conversions: [],\n },\n\n \"pricing-rule\": {\n slug: \"pricing-rule\",\n label: \"Pricing Rule\",\n dateField: \"valid_from\",\n amountField: \"discount_percentage\",\n fields: [\n { name: \"title\", label: \"Title\", type: \"text\", required: true },\n { name: \"item_code\", label: \"Item\", type: \"link\", linkDoctype: \"item\", required: true },\n { name: \"selling\", label: \"Selling\", type: \"select\", options: [\"1\", \"0\"], default: \"1\" },\n { name: \"buying\", label: \"Buying\", type: \"select\", options: [\"1\", \"0\"], default: \"0\" },\n { name: \"rate_or_discount\", label: \"Type\", type: \"select\", options: [\"Discount Percentage\", \"Discount Amount\", \"Rate\"], default: \"Discount Percentage\" },\n { name: \"discount_percentage\", label: \"Discount %\", type: \"number\" },\n { name: \"discount_amount\", label: \"Discount Amt\", type: \"currency\" },\n { name: \"rate\", label: \"Rate\", type: \"currency\" },\n { name: \"min_qty\", label: \"Min Qty\", type: \"number\" },\n { name: \"valid_from\", label: \"Valid From\", type: \"date\" },\n { name: \"valid_upto\", label: \"Valid Upto\", type: \"date\" },\n { name: \"priority\", label: \"Priority\", type: \"number\" },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\" },\n { name: \"enabled\", label: \"Enabled\", type: \"select\", options: [\"1\", \"0\"], default: \"1\" },\n ],\n childTables: [],\n listColumns: [\"name\", \"title\", \"item_code\", \"rate_or_discount\", \"discount_percentage\", \"status\"],\n canSubmit: false,\n canCancel: false,\n conversions: [],\n },\n\n \"budget\": {\n slug: \"budget\",\n label: \"Budget\",\n dateField: \"fiscal_year\",\n amountField: \"budget_amount\",\n fields: [\n { name: \"account\", label: \"Account\", type: \"link\", linkDoctype: \"account\", required: true },\n { name: \"cost_center\", label: \"Cost Center\", type: \"link\", linkDoctype: \"cost-center\" },\n { name: \"fiscal_year\", label: \"Fiscal Year\", type: \"text\", required: true },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\", required: true },\n { name: \"budget_amount\", label: \"Budget Amount\", type: \"currency\", required: true },\n { name: \"action_if_exceeded\", label: \"If Exceeded\", type: \"select\", options: [\"Stop\", \"Warn\", \"Ignore\"], default: \"Warn\",\n hint: \"Stop: prevents the transaction. Warn: allows it but logs a warning. Ignore: no check.\",\n },\n ],\n childTables: [\n {\n key: \"monthly_distribution\", label: \"Monthly Distribution\", fields: [\n { name: \"month\", label: \"Month\", type: \"select\", options: [\n \"January\", \"February\", \"March\", \"April\", \"May\", \"June\",\n \"July\", \"August\", \"September\", \"October\", \"November\", \"December\",\n ]},\n { name: \"percentage\", label: \"%\", type: \"number\" },\n ],\n },\n ],\n listColumns: [\"name\", \"account\", \"cost_center\", \"fiscal_year\", \"budget_amount\"],\n canSubmit: false,\n canCancel: false,\n conversions: [],\n },\n\n \"subscription\": {\n slug: \"subscription\",\n label: \"Subscription\",\n dateField: \"start_date\",\n fields: [\n { name: \"party_type\", label: \"Party Type\", type: \"select\", options: [\"Customer\", \"Supplier\"], required: true },\n { name: \"party\", label: \"Party\", type: \"link\", linkDoctypeField: \"party_type\", required: true },\n { name: \"company\", label: \"Company\", type: \"link\", linkDoctype: \"company\" },\n { name: \"start_date\", label: \"Start Date\", type: \"date\", required: true },\n { name: \"end_date\", label: \"End Date\", type: \"date\" },\n { name: \"billing_interval\", label: \"Billing Interval\", type: \"select\", options: [\"Monthly\", \"Quarterly\", \"Half-Yearly\", \"Yearly\"], default: \"Monthly\" },\n { name: \"current_invoice_start\", label: \"Current Period Start\", type: \"date\", readOnly: true },\n { name: \"current_invoice_end\", label: \"Current Period End\", type: \"date\", readOnly: true },\n { name: \"status\", label: \"Status\", type: \"text\", readOnly: true },\n ],\n childTables: [\n {\n key: \"plans\", label: \"Plan Items\", fields: [\n { name: \"item_code\", label: \"Item\", type: \"link\", linkDoctype: \"item\", required: true },\n { name: \"item_name\", label: \"Item Name\", type: \"text\", readOnly: true },\n { name: \"qty\", label: \"Qty\", type: \"number\", default: 1 },\n { name: \"rate\", label: \"Rate\", type: \"currency\", required: true },\n ],\n },\n ],\n listColumns: [\"name\", \"party\", \"billing_interval\", \"start_date\", \"status\"],\n canSubmit: false,\n canCancel: false,\n conversions: [],\n },\n\n \"bank-transaction\": {\n slug: \"bank-transaction\",\n label: \"Bank Transaction\",\n dateField: \"posting_date\",\n fields: [\n { name: \"bank_account\", label: \"Bank Account\", type: \"link\", linkDoctype: \"account\", required: true },\n { name: \"posting_date\", label: \"Date\", type: \"date\", required: true },\n { name: \"deposit\", label: \"Deposit\", type: \"currency\" },\n { name: \"withdrawal\", label: \"Withdrawal\", type: \"currency\" },\n { name: \"description\", label: \"Description\", type: \"text\" },\n { name: \"reference_number\", label: \"Reference No\", type: \"text\" },\n { name: \"reference_doctype\", label: \"Matched Type\", type: \"select\", options: [\"\", \"Payment Entry\", \"Sales Invoice\", \"Purchase Invoice\", \"Journal Entry\"] },\n { name: \"reference_name\", label: \"Matched Doc\", type: \"link\", linkDoctypeField: \"reference_doctype\" },\n { name: \"allocated_amount\", label: \"Allocated\", type: \"currency\", readOnly: true },\n { name: \"unallocated_amount\", label: \"Unallocated\", type: \"currency\", readOnly: true },\n { name: \"status\", label: \"Status\", type: \"text\", readOnly: true },\n ],\n childTables: [],\n listColumns: [\"name\", \"posting_date\", \"deposit\", \"withdrawal\", \"status\"],\n canSubmit: false,\n canCancel: false,\n conversions: [],\n },\n};\n\nexport function getDoctypeConfig(slug: string): DoctypeConfig | undefined {\n return CONFIGS[slug];\n}\n\n/**\n * Register (or override) a doctype config. A customer deployment built on the\n * published library calls this at startup to add a new document type or swap\n * the form/list schema of a core one. The list/form pages read CONFIGS live\n * via getDoctypeConfig, so a registration takes effect immediately.\n */\nexport function registerDoctype(config: DoctypeConfig) {\n CONFIGS[config.slug] = config;\n}\n\nexport function getAllDoctypeConfigs(): DoctypeConfig[] {\n return Object.values(CONFIGS);\n}\n\nexport const DOCTYPE_SLUGS = Object.keys(CONFIGS);\n","// Prev/next navigation for a document detail page. Steps through records in the\n// same order + filters as the list the user came from (via the doc-list-context\n// store), using the backend keyset `/adjacent` endpoint. Works on every doctype;\n// exported so a deployment's custom detail page can drop it in too.\n//\n// Buttons: ‹ = previous (up the list), › = next (down). Keyboard (only when not\n// typing in a field): k / ← = prev, j / → = next, Esc / u = back to the list.\n// Cmd/Ctrl+S = save (fires even while typing) when an onSave is provided.\nimport { useEffect } from \"react\";\nimport { useNavigate } from \"react-router-dom\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { ChevronLeft, ChevronRight } from \"lucide-react\";\nimport { api } from \"@/api/client\";\nimport { getListContext } from \"@/lib/doc-list-context\";\n\nexport function DocPager({ slug, name, onSave, kind = \"document\" }: {\n slug: string;\n name: string;\n /** Called on Cmd/Ctrl+S. Omit if the page has nothing to save. */\n onSave?: () => void;\n /** \"master\" pages through /masters/{slug} (name ASC) instead of /app/{slug}. */\n kind?: \"document\" | \"master\";\n}) {\n const navigate = useNavigate();\n const isMaster = kind === \"master\";\n // Masters get their own context namespace so e.g. a \"lead\" master and a\n // \"lead\" doctype list don't clobber each other's stashed URL.\n const ctx = getListContext(isMaster ? `master:${slug}` : slug);\n const base = isMaster ? `/masters/${slug}` : `/app/${slug}`;\n\n const { data } = useQuery({\n queryKey: [\"adjacent\", kind, slug, name, ctx?.filters ?? null],\n queryFn: () =>\n isMaster\n ? api.adjacentMaster(slug, name)\n : api.adjacentDocument(slug, name, ctx?.filters as any),\n });\n const prev = data?.prev ?? null;\n const next = data?.next ?? null;\n\n useEffect(() => {\n const goPrev = () => prev && navigate(`${base}/${prev}`);\n const goNext = () => next && navigate(`${base}/${next}`);\n const back = () => navigate(`${base}${ctx?.search || \"\"}`);\n\n const onKey = (e: KeyboardEvent) => {\n // Save works even mid-edit.\n if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === \"s\") {\n if (onSave) { e.preventDefault(); onSave(); }\n return;\n }\n const el = document.activeElement as HTMLElement | null;\n const typing = !!el && (/^(input|textarea|select)$/i.test(el.tagName) || el.isContentEditable);\n if (typing || e.metaKey || e.ctrlKey || e.altKey) return;\n if (e.key === \"j\" || e.key === \"ArrowRight\") { e.preventDefault(); goNext(); }\n else if (e.key === \"k\" || e.key === \"ArrowLeft\") { e.preventDefault(); goPrev(); }\n else if (e.key === \"Escape\" || e.key === \"u\") { e.preventDefault(); back(); }\n };\n window.addEventListener(\"keydown\", onKey);\n return () => window.removeEventListener(\"keydown\", onKey);\n }, [prev, next, base, ctx?.search, onSave, navigate]);\n\n const btn =\n \"rounded-md border border-line bg-surface p-1.5 text-fg-muted transition hover:bg-surface-subtle hover:text-fg disabled:cursor-default disabled:opacity-40\";\n\n return (\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n disabled={!prev}\n title=\"Previous record (k / ←)\"\n onClick={() => prev && navigate(`${base}/${prev}`)}\n className={btn}\n >\n <ChevronLeft className=\"h-4 w-4\" />\n </button>\n <button\n type=\"button\"\n disabled={!next}\n title=\"Next record (j / →)\"\n onClick={() => next && navigate(`${base}/${next}`)}\n className={btn}\n >\n <ChevronRight className=\"h-4 w-4\" />\n </button>\n </div>\n );\n}\n","import { cn } from \"@/lib/utils\";\n\n// Either a plain string (shown as both label + value) or an object form for\n// nicer labels (e.g. Yes/No on top of a boolean 1/0 value).\nexport type SelectOption = string | { value: string; label: string };\n\ninterface SelectProps {\n label?: string;\n options: SelectOption[];\n value?: string;\n onChange?: React.ChangeEventHandler<HTMLSelectElement>;\n className?: string;\n required?: boolean;\n disabled?: boolean;\n}\n\nfunction normalizeOption(opt: SelectOption): { value: string; label: string } {\n return typeof opt === \"string\" ? { value: opt, label: opt } : opt;\n}\n\nexport function Select({ label, options, value, onChange, className, required, disabled }: SelectProps) {\n const selectId = label ? label.toLowerCase().replace(/\\s+/g, \"-\") : undefined;\n\n return (\n <div>\n {label && (\n <label\n htmlFor={selectId}\n className=\"mb-1.5 block text-sm font-medium text-fg\"\n >\n {label}\n </label>\n )}\n <select\n id={selectId}\n value={value}\n onChange={onChange}\n required={required}\n disabled={disabled}\n className={cn(\n // Same shape as the Input primitive: h-10, surface bg, line ring,\n // brand-tinted halo on focus.\n \"block h-10 w-full rounded-lg bg-surface px-3 text-sm text-fg\",\n \"ring-1 ring-line transition-all\",\n \"focus:outline-none focus:ring-2 focus:ring-brand/30\",\n \"disabled:cursor-not-allowed disabled:bg-surface-subtle disabled:text-fg-muted\",\n className,\n )}\n >\n <option value=\"\">Select...</option>\n {options.map((opt) => {\n const { value: v, label: l } = normalizeOption(opt);\n return (\n <option key={v} value={v}>\n {l}\n </option>\n );\n })}\n </select>\n </div>\n );\n}\n","import { useState } from \"react\";\n\nexport function HintTooltip({ text }: { text: string }) {\n const [visible, setVisible] = useState(false);\n\n return (\n <span className=\"relative ml-1 inline-flex\">\n <button\n type=\"button\"\n className=\"inline-flex h-4 w-4 items-center justify-center rounded-full border border-gray-300 text-[10px] font-medium text-gray-400 hover:border-gray-400 hover:text-gray-600\"\n onMouseEnter={() => setVisible(true)}\n onMouseLeave={() => setVisible(false)}\n onClick={() => setVisible((v) => !v)}\n >\n ?\n </button>\n {visible && (\n <div className=\"absolute bottom-full left-1/2 z-50 mb-2 w-64 -translate-x-1/2 rounded-md bg-gray-900 px-3 py-2 text-xs leading-relaxed text-white shadow-lg\">\n {text}\n <div className=\"absolute left-1/2 top-full -translate-x-1/2 border-4 border-transparent border-t-gray-900\" />\n </div>\n )}\n </span>\n );\n}\n","import { useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Info } from \"lucide-react\";\n\n// Info icon next to the Notes / Terms label that explains the light markup the\n// field supports on the PDF (see api/remarks_md.py in the core). Opens on hover\n// or click; the handlers sit on the wrapper so the popover stays open while the\n// pointer moves into it to read.\nexport function NotesMarkupHelp() {\n const { t } = useTranslation();\n const [open, setOpen] = useState(false);\n\n const rows: [string, string][] = [\n [\"# Heading\", t(\"notesMarkup.heading\", { defaultValue: \"bold heading\" })],\n [\"*italic* **bold**\", t(\"notesMarkup.emphasis\", { defaultValue: \"italic / bold\" })],\n [\"---\", t(\"notesMarkup.rule\", { defaultValue: \"horizontal divider line\" })],\n [\n \">> Period | Amount\",\n t(\"notesMarkup.price\", {\n defaultValue: \"right-aligned price beside the text above (e.g. Monthly | CHF 380.—)\",\n }),\n ],\n ];\n\n return (\n <span\n className=\"relative ml-1 inline-flex align-middle\"\n onMouseEnter={() => setOpen(true)}\n onMouseLeave={() => setOpen(false)}\n >\n <button\n type=\"button\"\n className=\"inline-flex h-4 w-4 items-center justify-center rounded-full text-fg-muted hover:text-fg\"\n onClick={() => setOpen((v) => !v)}\n aria-label={t(\"notesMarkup.title\", { defaultValue: \"Formatting help\" })}\n >\n <Info className=\"h-3.5 w-3.5\" />\n </button>\n {open && (\n <div className=\"absolute bottom-full left-0 z-50 mb-2 w-80 rounded-md bg-gray-900 px-3 py-2.5 text-xs leading-relaxed text-white shadow-lg\">\n <p className=\"mb-2 text-gray-200\">\n {t(\"notesMarkup.intro\", {\n defaultValue: \"The Notes / Terms text supports light formatting on the PDF:\",\n })}\n </p>\n <table className=\"w-full border-separate border-spacing-y-1\">\n <tbody>\n {rows.map(([syntax, desc]) => (\n <tr key={syntax}>\n <td className=\"pr-3 align-top font-mono text-[11px] text-emerald-300\">{syntax}</td>\n <td className=\"align-top text-gray-200\">{desc}</td>\n </tr>\n ))}\n </tbody>\n </table>\n <p className=\"mt-2 text-gray-400\">\n {t(\"notesMarkup.block\", { defaultValue: \"Separate blocks with a blank line.\" })}\n </p>\n </div>\n )}\n </span>\n );\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { api } from \"@/api/client\";\n\n/**\n * Currencies the ERP can transact in — the company base currency plus any\n * currency that has an exchange rate on file or is set as a party/company\n * default. Used to populate the document currency dropdown, so a document can\n * only be denominated in a currency the books can convert back to base.\n *\n * Pass `enabled=false` to skip the fetch (e.g. from fields that aren't currency\n * pickers, keeping React Query's request count down).\n */\nexport function useCurrencies(company?: string, enabled = true): string[] {\n const { data } = useQuery({\n queryKey: [\"currencies\", company ?? \"\"],\n queryFn: () => api.currencies(company),\n enabled,\n staleTime: 5 * 60 * 1000,\n });\n return data?.currencies ?? [];\n}\n","import { useState, useEffect, useRef, useCallback, useMemo } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { Link, useParams, useNavigate } from \"react-router-dom\";\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { api } from \"@/api/client\";\nimport { getDoctypeConfig, type FieldDef, type ChildTableDef } from \"@/lib/doctypes\";\nimport { StatusBadge } from \"@/components/document/status-badge\";\nimport { DocPager } from \"@/components/document/doc-pager\";\nimport { Button } from \"@/components/ui/button\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Select } from \"@/components/ui/select\";\nimport { formatCurrency, flt } from \"@/lib/utils\";\nimport { HintTooltip } from \"@/components/ui/hint-tooltip\";\nimport { NotesMarkupHelp } from \"@/components/ui/notes-markup-help\";\nimport { useCurrencies } from \"@/hooks/use-currencies\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\nimport { useTranslation } from \"react-i18next\";\n\n// ---------------------------------------------------------------------------\n// Link resolution — where does clicking \"customer\" / \"account\" / etc. lead?\n// ---------------------------------------------------------------------------\n\n// Link doctypes that have a real MasterForm page. Anything else falls through\n// to a special route (Account → GL report) or renders as plain text.\nconst LINKABLE_MASTERS = new Set([\n \"customer\",\n \"supplier\",\n \"item\",\n \"warehouse\",\n]);\n\nexport function linkRefHref(linkDoctype: string | undefined | null, value: string): string | null {\n if (!linkDoctype || !value) return null;\n if (LINKABLE_MASTERS.has(linkDoctype)) {\n return `/masters/${linkDoctype}/${encodeURIComponent(value)}`;\n }\n if (linkDoctype === \"account\") {\n // No standalone Account page — deep-link into the GL report pre-filtered\n // to this account, which is what users actually want to see.\n return `/reports/general-ledger?account=${encodeURIComponent(value)}`;\n }\n // cost_center / company / anything else: no destination yet.\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// FieldLabel -- label with optional hint tooltip\n// ---------------------------------------------------------------------------\n\nfunction FieldLabel({ label, hint, extra }: { label: string; hint?: string; extra?: React.ReactNode }) {\n return (\n <label className=\"mb-1.5 block text-sm font-medium text-fg\">\n {label}\n {hint && <HintTooltip text={hint} />}\n {extra}\n </label>\n );\n}\n\n// ---------------------------------------------------------------------------\n// LinkField -- simple search-as-you-type select for master data\n// ---------------------------------------------------------------------------\n\nfunction LinkField({\n field,\n value,\n onChange,\n disabled,\n hideLabel,\n}: {\n field: FieldDef;\n value: string;\n onChange: (v: string) => void;\n disabled?: boolean;\n hideLabel?: boolean;\n}) {\n const [query, setQuery] = useState(value ?? \"\");\n const [open, setOpen] = useState(false);\n // The dropdown is portaled to <body> so it isn't clipped by the line-items\n // table's overflow-x-auto scroll container; we track the input's viewport\n // rect to position it (and follow it on scroll/resize).\n const wrapRef = useRef<HTMLDivElement>(null);\n const [menuRect, setMenuRect] = useState<{ top: number; left: number; width: number } | null>(null);\n\n const { data: options } = useQuery({\n queryKey: [\"link-search\", field.linkDoctype, query],\n queryFn: () => api.searchLink(field.linkDoctype!, query),\n enabled: !!field.linkDoctype && open,\n });\n\n useEffect(() => {\n setQuery(value ?? \"\");\n }, [value]);\n\n useEffect(() => {\n if (!open) return;\n const update = () => {\n const el = wrapRef.current;\n if (el) {\n const r = el.getBoundingClientRect();\n setMenuRect({ top: r.bottom, left: r.left, width: r.width });\n }\n };\n update();\n // capture=true so scrolling any ancestor (the table's scroller) repositions it.\n window.addEventListener(\"scroll\", update, true);\n window.addEventListener(\"resize\", update);\n return () => {\n window.removeEventListener(\"scroll\", update, true);\n window.removeEventListener(\"resize\", update);\n };\n }, [open]);\n\n if (disabled) {\n return (\n <div>\n {!hideLabel && <label className=\"mb-1.5 block text-sm font-medium text-fg\">{field.label}</label>}\n <p className=\"py-2 text-sm text-fg\">{value || \"-\"}</p>\n </div>\n );\n }\n\n return (\n <div className=\"relative\" ref={wrapRef}>\n <Input\n label={hideLabel ? undefined : field.label}\n value={query}\n onChange={(e) => {\n setQuery(e.target.value);\n setOpen(true);\n }}\n onFocus={() => setOpen(true)}\n onBlur={() => setTimeout(() => setOpen(false), 200)}\n />\n {open && options && options.length > 0 && menuRect && createPortal(\n <ul\n className=\"fixed z-50 mt-1 max-h-40 overflow-auto rounded-lg bg-surface ring-1 ring-line shadow-card-hover\"\n style={{ top: menuRect.top, left: menuRect.left, width: menuRect.width }}\n >\n {options.map((opt: any) => (\n <li\n key={opt.name}\n className=\"cursor-pointer px-3 py-2 text-sm text-fg transition-colors hover:bg-surface-subtle\"\n onMouseDown={() => {\n onChange(opt.name);\n setQuery(opt.name);\n setOpen(false);\n }}\n >\n {opt.name}\n </li>\n ))}\n </ul>,\n document.body,\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// FieldRenderer\n// ---------------------------------------------------------------------------\n\nfunction FieldRenderer({\n field,\n value,\n onChange,\n readOnly,\n rowData,\n hideLabel,\n currency = \"USD\",\n}: {\n field: FieldDef;\n value: any;\n onChange: (v: any) => void;\n readOnly: boolean;\n rowData?: Record<string, any>;\n /** Suppress the in-cell field label. Used by ChildTableEditor where the\n * table column header already shows the label — repeating it inside\n * every row makes mobile cells taller and wider than they need to be. */\n hideLabel?: boolean;\n /** The document's currency, so amounts render with the right symbol\n * (€/£/¥…) instead of always $. */\n currency?: string;\n}) {\n const { t } = useTranslation();\n const isDisabled = readOnly || !!field.readOnly;\n const Label = () =>\n hideLabel ? null : (\n <FieldLabel label={t(`fields.${field.label}`, { defaultValue: field.label })} hint={field.hint} />\n );\n\n // Currency pickers get their options from the available-currencies endpoint\n // rather than a static list. The fetch is skipped for every other field.\n const needsCurrencyOptions =\n field.type === \"select\" && field.optionsSource === \"currency\";\n const currencyOptions = useCurrencies(undefined, needsCurrencyOptions);\n\n if (isDisabled) {\n // Link fields render as a clickable link in read-only mode when there's a\n // real destination. Matches the sky-600 treatment in document lists.\n if (field.type === \"link\" && value) {\n const resolvedLinkDoctype =\n field.linkDoctypeField && rowData\n ? String(rowData[field.linkDoctypeField] ?? \"\")\n .toLowerCase()\n .replace(/\\s+/g, \"-\")\n : field.linkDoctype;\n const href = linkRefHref(resolvedLinkDoctype, String(value));\n if (href) {\n return (\n <div>\n <Label />\n <p className={hideLabel ? \"text-sm\" : \"py-2 text-sm\"}>\n <Link\n to={href}\n className=\"text-sky-600 hover:text-sky-800 hover:underline\"\n >\n {value}\n </Link>\n </p>\n </div>\n );\n }\n }\n\n let display = value ?? \"-\";\n if ((field.type === \"currency\") && typeof value === \"number\") {\n display = formatCurrency(value, currency);\n }\n // Multi-line fields (Notes / Terms) keep their line breaks when shown\n // read-only, instead of collapsing to one paragraph like a <p> does.\n const pClass = [\n hideLabel ? \"text-sm text-fg\" : \"py-2 text-sm text-fg\",\n field.type === \"textarea\" ? \"whitespace-pre-line\" : \"\",\n ].join(\" \").trim();\n return (\n <div>\n <Label />\n <p className={pClass}>{display}</p>\n </div>\n );\n }\n\n if (field.type === \"link\") {\n const resolvedField = field.linkDoctypeField && rowData\n ? { ...field, linkDoctype: rowData[field.linkDoctypeField]?.toLowerCase().replace(/\\s+/g, \"-\") }\n : field;\n return (\n <div>\n <Label />\n <LinkField\n field={resolvedField}\n value={value ?? \"\"}\n onChange={onChange}\n disabled={isDisabled}\n hideLabel\n />\n </div>\n );\n }\n\n if (field.type === \"select\" && (field.options || needsCurrencyOptions)) {\n // Keep the doc's own currency selectable even if it's not in the fetched\n // list (e.g. an older currency no longer on any rate/default).\n const options = needsCurrencyOptions\n ? value && !currencyOptions.includes(value)\n ? [value, ...currencyOptions]\n : currencyOptions\n : field.options!;\n return (\n <div>\n <Label />\n <Select\n options={options}\n value={value ?? \"\"}\n onChange={(e) => onChange(e.target.value)}\n />\n </div>\n );\n }\n\n if (field.type === \"textarea\") {\n // The `remarks` field is rendered from a light markup on the PDF, so it\n // gets the formatting-help icon. Parent textareas (not child-table cells)\n // are roomier since they sit on their own full-width row.\n const showMarkupHelp = field.name === \"remarks\";\n return (\n <div>\n {!hideLabel && (\n <FieldLabel\n label={t(`fields.${field.label}`, { defaultValue: field.label })}\n hint={field.hint}\n extra={showMarkupHelp ? <NotesMarkupHelp /> : undefined}\n />\n )}\n <textarea\n className=\"block w-full rounded-lg bg-surface px-3 py-2 text-sm text-fg ring-1 ring-line transition-all placeholder:text-fg-muted/70 focus:outline-none focus:ring-2 focus:ring-brand/30\"\n rows={hideLabel ? 3 : 7}\n value={value ?? \"\"}\n onChange={(e) => onChange(e.target.value)}\n />\n </div>\n );\n }\n\n const inputType =\n field.type === \"number\" || field.type === \"currency\"\n ? \"number\"\n : field.type === \"date\"\n ? \"date\"\n : \"text\";\n\n return (\n <div>\n <Label />\n <Input\n type={inputType}\n step={field.type === \"currency\" ? \"0.01\" : undefined}\n value={value ?? \"\"}\n onChange={(e) =>\n onChange(\n inputType === \"number\" ? parseFloat(e.target.value) || 0 : e.target.value,\n )\n }\n />\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// ChildTableEditor\n// ---------------------------------------------------------------------------\n\nfunction ChildTableEditor({\n tableDef,\n rows,\n onChange,\n readOnly,\n currency = \"USD\",\n}: {\n tableDef: ChildTableDef;\n rows: any[];\n onChange: (rows: any[]) => void;\n readOnly: boolean;\n currency?: string;\n}) {\n const { t } = useTranslation();\n const updateRow = (idx: number, fieldName: string, value: any) => {\n const updated = rows.map((row, i) =>\n i === idx ? { ...row, [fieldName]: value } : row,\n );\n onChange(updated);\n };\n\n const addRow = () => {\n const blank: any = {};\n tableDef.fields.forEach((f) => {\n blank[f.name] = f.default ?? (f.type === \"number\" || f.type === \"currency\" ? 0 : \"\");\n });\n onChange([...rows, blank]);\n };\n\n const removeRow = (idx: number) => {\n onChange(rows.filter((_, i) => i !== idx));\n };\n\n return (\n <Card title={t(`tables.${tableDef.key}`, { defaultValue: tableDef.label })}>\n <div className=\"-mx-6 overflow-x-auto px-6\">\n <table className=\"min-w-full divide-y divide-line text-sm\">\n <thead>\n <tr>\n <th className=\"px-2 py-2 text-left text-xs font-medium uppercase tracking-wide text-fg-muted\">\n #\n </th>\n {tableDef.fields.map((f) => (\n <th\n key={f.name}\n className=\"px-2 py-2 text-left text-xs font-medium uppercase tracking-wide text-fg-muted\"\n >\n {t(`fields.${f.label}`, { defaultValue: f.label })}\n </th>\n ))}\n {!readOnly && (\n <th className=\"px-2 py-2 text-left text-xs font-medium uppercase tracking-wide text-fg-muted\" />\n )}\n </tr>\n </thead>\n <tbody className=\"divide-y divide-line\">\n {rows.map((row, idx) => (\n <tr key={idx}>\n <td className=\"px-2 py-1 text-fg-muted\">{idx + 1}</td>\n {tableDef.fields.map((f) => (\n <td key={f.name} className=\"px-2 py-1 align-top\">\n <FieldRenderer\n field={f}\n value={row[f.name]}\n onChange={(v) => updateRow(idx, f.name, v)}\n readOnly={readOnly}\n rowData={row}\n hideLabel\n currency={currency}\n />\n </td>\n ))}\n {!readOnly && (\n <td className=\"px-2 py-1\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => removeRow(idx)}\n >\n Remove\n </Button>\n </td>\n )}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n {!readOnly && (\n <div className=\"mt-2\">\n <Button variant=\"secondary\" size=\"sm\" onClick={addRow}>\n {t(\"common.addRow\")}\n </Button>\n </div>\n )}\n </Card>\n );\n}\n\n// ---------------------------------------------------------------------------\n// DocumentActions\n// ---------------------------------------------------------------------------\n\nfunction DocumentActions({\n isNew,\n doctype,\n name,\n docstatus,\n discarded,\n saving,\n config,\n onSave,\n onSubmit,\n onCancel,\n onConvert,\n onDiscard,\n}: {\n isNew: boolean;\n doctype?: string;\n name?: string;\n docstatus: number;\n discarded?: boolean;\n saving: boolean;\n config: ReturnType<typeof getDoctypeConfig>;\n onSave: () => void;\n onSubmit: () => void;\n onCancel: () => void;\n onConvert: (targetDoctype: string) => void;\n onDiscard: () => void;\n}) {\n const { t } = useTranslation();\n // Two-step cancel: clicking \"Cancel\" doesn't cancel — it arms confirmation.\n // The confirm button then renders in a DIFFERENT place (pushed right) while\n // the original spot becomes a safe \"Don't cancel\", so a double-click can't\n // accidentally go through with this irreversible action.\n const [confirmingCancel, setConfirmingCancel] = useState(false);\n // Discard (drafts only) is a soft delete — reversible at the DB level — so a\n // lighter inline two-step arm is enough.\n const [confirmingDiscard, setConfirmingDiscard] = useState(false);\n if (!config) return null;\n\n const pdfUrl = !isNew && doctype && name\n ? `/api/documents/${doctype}/${encodeURIComponent(name)}/pdf`\n : null;\n\n const showCancel = !isNew && config.canCancel && docstatus === 1;\n\n return (\n <div className=\"flex flex-wrap items-center gap-2\">\n {pdfUrl && (\n <Button variant=\"secondary\" onClick={() => window.open(pdfUrl, \"_blank\")}>\n {t(\"common.pdf\")}\n </Button>\n )}\n {docstatus < 1 && !discarded && (\n <Button onClick={onSave} disabled={saving}>\n {saving ? t(\"common.saving\") : t(\"common.save\")}\n </Button>\n )}\n {!isNew && config.canSubmit && docstatus === 0 && !discarded && (\n <Button variant=\"secondary\" onClick={onSubmit}>\n {t(\"common.submit\")}\n </Button>\n )}\n {/* Discard draft (soft delete) — only on an unsubmitted, saved draft. */}\n {!isNew && config.canSubmit && docstatus === 0 && !discarded && (\n confirmingDiscard ? (\n <>\n <Button variant=\"secondary\" onClick={() => setConfirmingDiscard(false)}>\n {t(\"common.keepDraft\")}\n </Button>\n <Button\n variant=\"danger\"\n onClick={() => {\n setConfirmingDiscard(false);\n onDiscard();\n }}\n >\n {t(\"common.discardDraftConfirm\")}\n </Button>\n </>\n ) : (\n <Button variant=\"ghost\" onClick={() => setConfirmingDiscard(true)}>\n {t(\"common.discardDraft\")}\n </Button>\n )\n )}\n {/* Original Cancel button position. In confirm mode it becomes the safe\n \"Don't cancel\" so a stray repeat click here aborts rather than fires. */}\n {showCancel && (\n confirmingCancel ? (\n <Button variant=\"secondary\" onClick={() => setConfirmingCancel(false)}>\n {t(\"common.cancelDocAbort\")}\n </Button>\n ) : (\n <Button variant=\"danger\" onClick={() => setConfirmingCancel(true)}>\n {t(\"common.cancelDoc\")}\n </Button>\n )\n )}\n {/* Conversions are hidden while confirming to keep the choice unambiguous. */}\n {!isNew &&\n docstatus === 1 &&\n !confirmingCancel &&\n config.conversions.map((conv) => (\n <Button\n key={conv.targetDoctype}\n variant=\"secondary\"\n onClick={() => onConvert(conv.targetDoctype)}\n >\n {t(`conversions.${conv.label}`, { defaultValue: conv.label })}\n </Button>\n ))}\n {/* The actual confirm — deliberately placed far from the original button\n (pushed to the opposite end) so it can't be hit by a double-click. */}\n {showCancel && confirmingCancel && (\n <Button\n variant=\"danger\"\n className=\"ml-auto\"\n onClick={() => {\n setConfirmingCancel(false);\n onCancel();\n }}\n >\n {t(\"common.cancelDocConfirmBtn\")}\n </Button>\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Recalculation helper\n// ---------------------------------------------------------------------------\n\nfunction recalculate(formData: any, config: ReturnType<typeof getDoctypeConfig>) {\n if (!config) return formData;\n\n const updated = { ...formData };\n\n // Recalculate item amounts\n const hasItems = config.childTables.some((ct) => ct.key === \"items\");\n if (hasItems && Array.isArray(updated.items)) {\n updated.items = updated.items.map((item: any) => ({\n ...item,\n amount: flt(item.qty, 2) * flt(item.rate, 2),\n }));\n\n updated.net_total = updated.items.reduce(\n (sum: number, item: any) => sum + flt(item.amount, 2),\n 0,\n );\n }\n\n // Recalculate taxes\n const hasTaxes = config.childTables.some((ct) => ct.key === \"taxes\");\n if (hasTaxes && Array.isArray(updated.taxes)) {\n updated.taxes = updated.taxes.map((tax: any) => {\n if (tax.charge_type === \"On Net Total\") {\n return {\n ...tax,\n tax_amount: flt(updated.net_total, 2) * flt(tax.rate, 2) / 100,\n };\n }\n return tax;\n });\n\n const totalTax = updated.taxes.reduce(\n (sum: number, t: any) => sum + flt(t.tax_amount, 2),\n 0,\n );\n updated.total_taxes_and_charges = totalTax;\n updated.grand_total = flt(updated.net_total, 2) + totalTax;\n }\n\n return updated;\n}\n\n// ---------------------------------------------------------------------------\n// Main form page\n// ---------------------------------------------------------------------------\n\nexport default function DocumentFormPage() {\n const { doctype, name } = useParams<{ doctype: string; name: string }>();\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n const { t } = useTranslation();\n const config = getDoctypeConfig(doctype ?? \"\");\n const isNew = !name;\n\n const [formData, setFormData] = useState<any>({});\n // True once the user picks a currency by hand, so auto-defaulting backs off.\n const [currencyTouched, setCurrencyTouched] = useState(false);\n\n // Fetch existing document\n const { data: existingDoc, isLoading } = useQuery({\n queryKey: [\"document\", doctype, name],\n queryFn: () => api.getDocument(doctype!, name!),\n enabled: !!doctype && !!name && !isNew,\n });\n\n // --- Currency defaulting (new documents only) ----------------------------\n // Pre-fill the transaction currency from the selected party's default\n // currency, falling back to the company base — mirroring the backend's\n // precedence — until the user picks one. Only sales/purchase docs have it.\n const hasCurrencyField = useMemo(\n () => !!config?.fields.some((f) => f.name === \"currency\"),\n [config],\n );\n const partyType = config?.partyField;\n const partyName = partyType ? formData[partyType] : undefined;\n const companyCurrency = useBaseCurrency(formData.company);\n\n const { data: partyMaster } = useQuery({\n queryKey: [\"master\", partyType, partyName],\n queryFn: () => api.getMaster(partyType!, partyName!),\n enabled: isNew && hasCurrencyField && !!partyType && !!partyName,\n staleTime: 5 * 60 * 1000,\n });\n\n useEffect(() => {\n if (!isNew || !hasCurrencyField || currencyTouched) return;\n let suggested: string | undefined;\n if (partyName) {\n if (!partyMaster) return; // wait for the party's currency before defaulting\n suggested = partyMaster.default_currency || companyCurrency;\n } else {\n suggested = companyCurrency;\n }\n if (suggested && suggested !== formData.currency) {\n setFormData((prev: any) => ({ ...prev, currency: suggested }));\n }\n }, [\n isNew, hasCurrencyField, currencyTouched,\n partyName, partyMaster, companyCurrency, formData.currency,\n ]);\n\n // Initialize formData\n useEffect(() => {\n if (isNew && config) {\n const defaults: any = {};\n config.fields.forEach((f) => {\n if (f.type === \"date\") {\n defaults[f.name] = new Date().toISOString().split(\"T\")[0];\n } else {\n defaults[f.name] = f.default ?? \"\";\n }\n });\n config.childTables.forEach((ct) => {\n defaults[ct.key] = [];\n });\n defaults.docstatus = 0;\n setFormData(defaults);\n } else if (existingDoc) {\n setFormData(existingDoc);\n }\n }, [isNew, existingDoc, config]);\n\n // Mutations\n const createMut = useMutation({\n mutationFn: (data: any) => api.createDocument(doctype!, data),\n onSuccess: (result) => {\n queryClient.invalidateQueries({ queryKey: [\"documents\", doctype] });\n navigate(`/app/${doctype}/${result.name}`, { replace: true });\n },\n });\n\n const updateMut = useMutation({\n mutationFn: (data: any) => api.updateDocument(doctype!, name!, data),\n onSuccess: (result) => {\n queryClient.invalidateQueries({ queryKey: [\"document\", doctype, name] });\n queryClient.invalidateQueries({ queryKey: [\"documents\", doctype] });\n setFormData(result);\n },\n });\n\n const submitMut = useMutation({\n mutationFn: () => api.submitDocument(doctype!, name!),\n onSuccess: (result) => {\n setFormData(result);\n queryClient.invalidateQueries({ queryKey: [\"document\", doctype, name] });\n queryClient.invalidateQueries({ queryKey: [\"documents\", doctype] });\n },\n });\n\n const cancelMut = useMutation({\n mutationFn: () => api.cancelDocument(doctype!, name!),\n onSuccess: (result) => {\n setFormData(result);\n queryClient.invalidateQueries({ queryKey: [\"document\", doctype, name] });\n queryClient.invalidateQueries({ queryKey: [\"documents\", doctype] });\n },\n });\n\n const discardMut = useMutation({\n mutationFn: () => api.discardDocument(doctype!, name!),\n onSuccess: () => {\n // The draft is now hidden from the default list; leave the editor.\n queryClient.invalidateQueries({ queryKey: [\"documents\", doctype] });\n navigate(`/app/${doctype}`, { replace: true });\n },\n });\n\n const convertMut = useMutation({\n mutationFn: (targetDoctype: string) =>\n api.convertDocument(doctype!, name!, targetDoctype),\n onSuccess: (result, targetDoctype) => {\n const targetSlug = targetDoctype.toLowerCase().replace(/\\s+/g, \"-\");\n navigate(`/app/${targetSlug}/${result.name}`);\n },\n });\n\n // Field change handler with recalculation\n const setField = useCallback(\n (fieldName: string, value: any) => {\n if (fieldName === \"currency\") setCurrencyTouched(true);\n setFormData((prev: any) => {\n const next = { ...prev, [fieldName]: value };\n // A new currency invalidates any prior rate; clear it so the backend\n // re-resolves the exchange rate for the chosen currency.\n if (fieldName === \"currency\") next.conversion_rate = 0;\n return recalculate(next, config);\n });\n },\n [config],\n );\n\n const setChildTable = useCallback(\n (key: string, rows: any[]) => {\n setFormData((prev: any) => {\n const next = { ...prev, [key]: rows };\n return recalculate(next, config);\n });\n },\n [config],\n );\n\n const handleSave = () => {\n if (isNew) {\n createMut.mutate(formData);\n } else {\n updateMut.mutate(formData);\n }\n };\n\n const handleSubmit = () => {\n submitMut.mutate();\n };\n\n const handleCancel = () => {\n // Cancelling reverses all postings (GL + stock) and is irreversible. The\n // two-step confirm UI lives in DocumentActions (the confirm button appears\n // in a different place, so a double-click can't fire it by accident).\n cancelMut.mutate();\n };\n\n const handleConvert = (targetDoctype: string) => {\n convertMut.mutate(targetDoctype);\n };\n\n const handleDiscard = () => {\n // Soft delete of an unwanted draft — no postings to reverse. Confirmation\n // is handled inline in DocumentActions.\n discardMut.mutate();\n };\n\n if (!config) {\n return (\n <p className=\"text-fg-muted\">\n Unknown document type: {doctype}\n </p>\n );\n }\n\n if (!isNew && isLoading) {\n return <p className=\"text-fg-muted\">{t(\"common.loading\")}</p>;\n }\n\n const docstatus: number = formData.docstatus ?? 0;\n const discarded = !!formData.discarded;\n // A discarded draft is voided/terminal — lock it like a submitted document.\n const readOnly = docstatus >= 1 || discarded;\n\n // The document's currency drives how amounts are formatted (€/£/¥ vs $).\n // Documents without a currency field (Stock Entry, …) store their values in\n // the company BASE currency — falling back to a hardcoded USD stamped $ on\n // CHF numbers. Fall back to the company currency instead.\n const docCurrency: string = formData.currency || companyCurrency;\n const docRate: number = flt(formData.conversion_rate ?? 1);\n\n // Separate editable parent fields from computed/totals fields. Textareas\n // (Notes / Terms) are pulled onto their own full-width row below the grid so\n // there's room to write — and to surface the markup the field supports.\n const editableFields = config.fields.filter((f) => !f.readOnly);\n const gridFields = editableFields.filter((f) => f.type !== \"textarea\");\n const noteFields = editableFields.filter((f) => f.type === \"textarea\");\n const totalsFields = config.fields.filter((f) => f.readOnly);\n\n return (\n <div className=\"space-y-6\">\n {/* Header — stacks on mobile (status pill on top, action buttons\n below) since on a narrow screen the action buttons wrap to multiple\n lines and items-center vertically centers the pill against the\n tall buttons column, leaving it floating in dead space. From sm:\n up, side-by-side again. */}\n <div className=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex items-center gap-3\">\n {!isNew && <DocPager slug={config.slug} name={name!} onSave={handleSave} />}\n {!isNew && formData.status && (\n <StatusBadge status={formData.status} />\n )}\n {!isNew && formData.currency && (\n <span\n className=\"inline-flex items-center gap-1 rounded-full bg-surface-subtle px-2.5 py-0.5 text-xs font-medium text-fg-muted ring-1 ring-line\"\n title={docRate !== 1 ? `1 ${docCurrency} = ${docRate} base currency` : undefined}\n >\n {docCurrency}\n {docRate !== 1 && <span className=\"text-fg-muted/70\">@ {docRate}</span>}\n </span>\n )}\n </div>\n <DocumentActions\n isNew={isNew}\n doctype={doctype}\n name={name}\n docstatus={docstatus}\n saving={createMut.isPending || updateMut.isPending}\n config={config}\n discarded={discarded}\n onSave={handleSave}\n onSubmit={handleSubmit}\n onCancel={handleCancel}\n onConvert={handleConvert}\n onDiscard={handleDiscard}\n />\n </div>\n\n {/* Error display */}\n {(createMut.error || updateMut.error || submitMut.error || cancelMut.error) && (\n <div className=\"rounded-lg bg-rose-50 p-4 text-sm text-rose-700 ring-1 ring-rose-200\">\n {(createMut.error ?? updateMut.error ?? submitMut.error ?? cancelMut.error)\n ?.message ?? t(\"common.errorOccurred\")}\n </div>\n )}\n\n {/* Parent fields */}\n <Card>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {gridFields.map((field) => (\n <FieldRenderer\n key={field.name}\n field={field}\n value={formData[field.name]}\n onChange={(v) => setField(field.name, v)}\n readOnly={readOnly}\n rowData={formData}\n currency={docCurrency}\n />\n ))}\n </div>\n {/* Notes / Terms — full width, below Company/Currency etc. */}\n {noteFields.length > 0 && (\n <div className=\"mt-4 space-y-4\">\n {noteFields.map((field) => (\n <FieldRenderer\n key={field.name}\n field={field}\n value={formData[field.name]}\n onChange={(v) => setField(field.name, v)}\n readOnly={readOnly}\n rowData={formData}\n currency={docCurrency}\n />\n ))}\n </div>\n )}\n </Card>\n\n {/* Child tables */}\n {config.childTables.map((ct) => (\n <ChildTableEditor\n key={ct.key}\n tableDef={ct}\n rows={formData[ct.key] ?? []}\n onChange={(rows) => setChildTable(ct.key, rows)}\n readOnly={readOnly}\n currency={docCurrency}\n />\n ))}\n\n {/* Totals section */}\n {totalsFields.length > 0 && (\n <Card title={t(\"common.totals\")}>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n {totalsFields.map((field) => (\n <FieldRenderer\n key={field.name}\n field={field}\n value={formData[field.name]}\n onChange={() => {}}\n readOnly={true}\n currency={docCurrency}\n />\n ))}\n </div>\n </Card>\n )}\n </div>\n );\n}\n","function iso(d: Date): string {\n return d.toISOString().split(\"T\")[0];\n}\n\nfunction startOfWeek(d: Date): Date {\n const r = new Date(d);\n const day = r.getDay();\n // Monday = 1; JS Sunday = 0 → treat Sunday as 7\n const diff = day === 0 ? 6 : day - 1;\n r.setDate(r.getDate() - diff);\n return r;\n}\n\nfunction endOfWeek(d: Date): Date {\n const s = startOfWeek(d);\n s.setDate(s.getDate() + 6);\n return s;\n}\n\nfunction startOfMonth(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth(), 1);\n}\n\nfunction endOfMonth(d: Date): Date {\n return new Date(d.getFullYear(), d.getMonth() + 1, 0);\n}\n\nfunction startOfQuarter(d: Date): Date {\n const q = Math.floor(d.getMonth() / 3);\n return new Date(d.getFullYear(), q * 3, 1);\n}\n\nfunction endOfQuarter(d: Date): Date {\n const s = startOfQuarter(d);\n return new Date(s.getFullYear(), s.getMonth() + 3, 0);\n}\n\nfunction startOfYear(d: Date): Date {\n return new Date(d.getFullYear(), 0, 1);\n}\n\nfunction endOfYear(d: Date): Date {\n return new Date(d.getFullYear(), 11, 31);\n}\n\ninterface Preset {\n label: string;\n range: () => [string, string];\n}\n\nconst PRESETS: Preset[] = [\n {\n label: \"Today\",\n range: () => {\n const t = iso(new Date());\n return [t, t];\n },\n },\n {\n label: \"This Week\",\n range: () => [iso(startOfWeek(new Date())), iso(endOfWeek(new Date()))],\n },\n {\n label: \"This Month\",\n range: () => [iso(startOfMonth(new Date())), iso(endOfMonth(new Date()))],\n },\n {\n label: \"This Quarter\",\n range: () => [iso(startOfQuarter(new Date())), iso(endOfQuarter(new Date()))],\n },\n {\n label: \"This Year\",\n range: () => [iso(startOfYear(new Date())), iso(endOfYear(new Date()))],\n },\n {\n label: \"Last Month\",\n range: () => {\n const now = new Date();\n const lastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);\n return [iso(startOfMonth(lastMonth)), iso(endOfMonth(lastMonth))];\n },\n },\n {\n label: \"Last Quarter\",\n range: () => {\n const now = new Date();\n const lastQuarter = new Date(now.getFullYear(), now.getMonth() - 3, 1);\n return [iso(startOfQuarter(lastQuarter)), iso(endOfQuarter(lastQuarter))];\n },\n },\n {\n label: \"Last Year\",\n range: () => {\n const lastYear = new Date(new Date().getFullYear() - 1, 6, 1);\n return [iso(startOfYear(lastYear)), iso(endOfYear(lastYear))];\n },\n },\n];\n\ninterface DateRangePresetsProps {\n onSelect: (from: string, to: string) => void;\n}\n\nexport function DateRangePresets({ onSelect }: DateRangePresetsProps) {\n return (\n <div className=\"flex flex-wrap gap-1.5\">\n {PRESETS.map((p) => (\n <button\n key={p.label}\n type=\"button\"\n onClick={() => {\n const [from, to] = p.range();\n onSelect(from, to);\n }}\n className=\"rounded-full bg-surface px-3 py-1 text-xs text-fg-muted ring-1 ring-line transition-all hover:bg-surface-subtle hover:text-fg hover:ring-brand/30\"\n >\n {p.label}\n </button>\n ))}\n </div>\n );\n}\n\ninterface SingleDatePresetsProps {\n onSelect: (date: string) => void;\n}\n\nexport function SingleDatePresets({ onSelect }: SingleDatePresetsProps) {\n const presets: { label: string; value: () => string }[] = [\n { label: \"Today\", value: () => iso(new Date()) },\n { label: \"End of This Month\", value: () => iso(endOfMonth(new Date())) },\n { label: \"End of Last Month\", value: () => {\n const now = new Date();\n return iso(endOfMonth(new Date(now.getFullYear(), now.getMonth() - 1, 1)));\n } },\n { label: \"End of This Quarter\", value: () => iso(endOfQuarter(new Date())) },\n { label: \"End of This Year\", value: () => iso(endOfYear(new Date())) },\n { label: \"End of Last Year\", value: () => iso(endOfYear(new Date(new Date().getFullYear() - 1, 0, 1))) },\n ];\n\n return (\n <div className=\"flex flex-wrap gap-1.5\">\n {presets.map((p) => (\n <button\n key={p.label}\n type=\"button\"\n onClick={() => onSelect(p.value())}\n className=\"rounded-full bg-surface px-3 py-1 text-xs text-fg-muted ring-1 ring-line transition-all hover:bg-surface-subtle hover:text-fg hover:ring-brand/30\"\n >\n {p.label}\n </button>\n ))}\n </div>\n );\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { Link, useParams, useLocation } from \"react-router-dom\";\nimport { setListContext } from \"@/lib/doc-list-context\";\nimport { useTranslation } from \"react-i18next\";\nimport {\n useReactTable,\n getCoreRowModel,\n flexRender,\n createColumnHelper,\n type ColumnDef,\n} from \"@tanstack/react-table\";\nimport { useDocumentList } from \"@/hooks/use-document-list\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\nimport { useUrlState, useUrlPatch } from \"@/hooks/use-url-state\";\nimport { getDoctypeConfig } from \"@/lib/doctypes\";\nimport { linkRefHref } from \"@/pages/documents/document-form\";\nimport { StatusBadge } from \"@/components/document/status-badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Select } from \"@/components/ui/select\";\nimport { DateRangePresets } from \"@/components/ui/date-range-presets\";\nimport { formatCurrency, formatDate } from \"@/lib/utils\";\n\nconst STATUS_OPTIONS = [\"All\", \"Draft\", \"Submitted\", \"Cancelled\"];\n\nconst CURRENCY_FIELDS = new Set([\n \"grand_total\",\n \"outstanding_amount\",\n \"paid_amount\",\n \"total_debit\",\n \"total_amount\",\n \"net_total\",\n]);\n\nconst DATE_FIELDS = new Set([\n \"transaction_date\",\n \"posting_date\",\n \"due_date\",\n \"delivery_date\",\n \"valid_till\",\n \"date\",\n]);\n\n// Columns that reference a master record — rendered as clickable links to the master page.\nconst MASTER_REF_FIELDS: Record<string, string> = {\n customer: \"customer\",\n supplier: \"supplier\",\n item_code: \"item\",\n item: \"item\",\n warehouse: \"warehouse\",\n company: \"company\",\n account: \"account\",\n cost_center: \"cost-center\",\n};\n\n// `party` references different master types depending on `party_type` in the row.\nfunction partyMasterType(partyType: unknown): string | null {\n if (typeof partyType !== \"string\") return null;\n const t = partyType.toLowerCase();\n if (t === \"customer\") return \"customer\";\n if (t === \"supplier\") return \"supplier\";\n return null;\n}\n\nconst PAGE_SIZE_OPTIONS = [\"25\", \"50\", \"100\", \"200\"];\n\n// Pagination controls, rendered both above and below the table so long lists\n// don't force a scroll to the bottom to page. The current page is a typeable\n// field (commit on Enter/blur, clamped to 1..totalPages).\nfunction ListPager({\n page,\n totalPages,\n pageSize,\n total,\n rangeStart,\n rangeEnd,\n setPage,\n setPageSize,\n}: {\n page: number;\n totalPages: number;\n pageSize: number;\n total: number;\n rangeStart: number;\n rangeEnd: number;\n setPage: (p: number) => void;\n setPageSize: (n: number) => void;\n}) {\n const { t } = useTranslation();\n const [pageInput, setPageInput] = useState(String(page + 1));\n useEffect(() => setPageInput(String(page + 1)), [page]);\n\n const commit = () => {\n const n = parseInt(pageInput, 10);\n if (!isNaN(n)) setPage(Math.min(totalPages, Math.max(1, n)) - 1);\n else setPageInput(String(page + 1));\n };\n\n return (\n <div className=\"flex flex-wrap items-center justify-between gap-3 text-sm text-fg-muted\">\n <div>\n {t(\"common.showing\")} <span className=\"font-medium text-fg\">{rangeStart}–{rangeEnd}</span>{\" \"}\n {t(\"common.of\")} <span className=\"font-medium text-fg\">{total}</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <label className=\"flex items-center gap-1.5\">\n <span className=\"text-xs text-fg-muted\">{t(\"common.perPage\")}</span>\n <select\n value={pageSize}\n onChange={(e) => setPageSize(Number(e.target.value))}\n className=\"h-8 rounded-md bg-surface px-2 text-sm text-fg ring-1 ring-line transition-all focus:outline-none focus:ring-2 focus:ring-brand/30\"\n >\n {PAGE_SIZE_OPTIONS.map((n) => (\n <option key={n} value={n}>{n}</option>\n ))}\n </select>\n </label>\n <button\n onClick={() => setPage(Math.max(0, page - 1))}\n disabled={page === 0}\n className=\"rounded-md bg-surface px-3 py-1 text-sm text-fg ring-1 ring-line transition-colors hover:bg-surface-subtle disabled:cursor-not-allowed disabled:opacity-40\"\n >\n {t(\"common.prev\")}\n </button>\n <span className=\"flex items-center gap-1 text-xs\">\n {t(\"common.page\")}\n <input\n aria-label={t(\"common.page\")}\n inputMode=\"numeric\"\n value={pageInput}\n onChange={(e) => setPageInput(e.target.value.replace(/[^0-9]/g, \"\"))}\n onBlur={commit}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") e.currentTarget.blur();\n }}\n className=\"h-7 w-12 rounded-md bg-surface px-1 text-center text-sm font-medium text-fg ring-1 ring-line focus:outline-none focus:ring-2 focus:ring-brand/30\"\n />\n {t(\"common.of\")} <span className=\"font-medium text-fg\">{totalPages}</span>\n </span>\n <button\n onClick={() => setPage(Math.min(totalPages - 1, page + 1))}\n disabled={page >= totalPages - 1}\n className=\"rounded-md bg-surface px-3 py-1 text-sm text-fg ring-1 ring-line transition-colors hover:bg-surface-subtle disabled:cursor-not-allowed disabled:opacity-40\"\n >\n {t(\"common.next\")}\n </button>\n </div>\n </div>\n );\n}\n\nexport default function DocumentListPage() {\n const { t } = useTranslation();\n // Rows without a per-document currency (Stock Entry, …) hold base-currency\n // values — format them with the company currency, not a hardcoded USD.\n const baseCurrency = useBaseCurrency();\n const { doctype } = useParams<{ doctype: string }>();\n const config = getDoctypeConfig(doctype ?? \"\");\n const location = useLocation();\n\n // Config-driven filter dropdowns (opt-in via config.listFilters). Their values\n // live in the URL like every other filter; read them generically since the\n // field names are dynamic. Each names a select field whose options drive the\n // dropdown; the selection is sent as a plain column filter.\n const configFilters = config?.listFilters ?? [];\n const filterValues = useMemo(() => {\n const params = new URLSearchParams(location.search);\n const out: Record<string, string> = {};\n for (const f of configFilters) out[f] = params.get(f) ?? \"\";\n return out;\n }, [location.search, configFilters]);\n\n // All user-facing filter state lives in the URL. The param names are the\n // short human-readable form (`from` / `to` / `per_page`); the backend still\n // wants `from_date` / `to_date` / `limit` / `offset`, translated below.\n const [status] = useUrlState<string>(\"status\", \"All\");\n const [fromDate] = useUrlState<string>(\"from\", \"\");\n const [toDate] = useUrlState<string>(\"to\", \"\");\n const [showDiscarded] = useUrlState<string>(\"discarded\", \"\");\n const [pageSize] = useUrlState<number>(\"per_page\", 50);\n // Free-text search (opt-in via config.searchFields). The committed query lives\n // in the URL (`q`); a local input debounces into it so we don't refetch on\n // every keystroke.\n const searchFields = config?.searchFields ?? [];\n const [urlQ] = useUrlState<string>(\"q\", \"\");\n const [searchInput, setSearchInput] = useState(urlQ);\n // URL is human-friendly 1-indexed; internal state stays 0-indexed for\n // offset calculation. setPage accepts the 0-indexed value.\n const [urlPage] = useUrlState<number>(\"page\", 1);\n const page = urlPage - 1;\n const patchUrl = useUrlPatch();\n\n // All writes go through one atomic patch so multiple params update together\n // — calling two individual setters in the same handler races (react-router\n // caches the previous searchParams, so the last call wins).\n const setPage = (p: number) => patchUrl({ page: p === 0 ? null : p + 1 });\n const setStatus = (s: string) => patchUrl({ status: s === \"All\" ? null : s, page: null });\n const setFromDate = (s: string) => patchUrl({ from: s || null, page: null });\n const setToDate = (s: string) => patchUrl({ to: s || null, page: null });\n const setShowDiscarded = (on: boolean) => patchUrl({ discarded: on ? \"1\" : null, page: null });\n const setPageSize = (n: number) => patchUrl({ per_page: n, page: null });\n\n // Keep the box in sync when `q` changes from outside typing (back/forward, a\n // cleared filter), then debounce local edits back into the URL after a pause.\n useEffect(() => { setSearchInput(urlQ); }, [urlQ]);\n useEffect(() => {\n if (searchInput === urlQ) return; // idle — nothing to commit, no timer\n const t = setTimeout(() => patchUrl({ q: searchInput || null, page: null }), 300);\n return () => clearTimeout(t);\n }, [searchInput, urlQ]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const filters = useMemo(() => {\n const f: Record<string, string | number | undefined> = {};\n // The default status dropdown is hidden when a doctype opts into its own\n // filters, so only apply it in that default case.\n if (configFilters.length === 0 && status !== \"All\") f.status = status;\n if (fromDate) f.from_date = fromDate;\n if (toDate) f.to_date = toDate;\n // Tell the backend which column the date range filters on. Without this the\n // server only knows the built-in core doctypes; plugin doctypes' date\n // pickers would be silently ignored.\n if (config?.dateField) f.date_field = config.dateField;\n for (const key of configFilters) {\n if (filterValues[key]) f[key] = filterValues[key];\n }\n // Free-text search across the config's searchFields (the committed URL `q`).\n if (searchFields.length > 0 && urlQ) {\n f.search = urlQ;\n f.search_fields = searchFields.join(\",\");\n }\n if (showDiscarded) f.include_discarded = \"true\";\n f.limit = pageSize;\n f.offset = page * pageSize;\n return f;\n }, [status, fromDate, toDate, showDiscarded, pageSize, page, config?.dateField, configFilters, filterValues, searchFields, urlQ]);\n\n const { data, isLoading } = useDocumentList(doctype ?? \"\", filters);\n const rows = data?.rows ?? [];\n const total = data?.total ?? 0;\n\n // Remember this list's filters + URL so a detail page's prev/next (DocPager)\n // follows it, and \"back to list\" returns here. Pagination is dropped — it's\n // not a record filter.\n useEffect(() => {\n const { limit, offset, ...ctxFilters } = filters;\n setListContext(doctype ?? \"\", { filters: ctxFilters, search: location.search });\n }, [doctype, filters, location.search]);\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n const rangeStart = total === 0 ? 0 : page * pageSize + 1;\n const rangeEnd = Math.min(total, (page + 1) * pageSize);\n\n const columns = useMemo<ColumnDef<any, any>[]>(() => {\n if (!config) return [];\n const helper = createColumnHelper<any>();\n // Title-case a column slug, then translate it (English title-case is the\n // fallback when a field has no translation yet).\n const headerLabel = (c: string) => {\n const titleCased = c\n .split(\"_\")\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(\" \");\n return t(`fields.${titleCased}`, { defaultValue: titleCased });\n };\n\n return config.listColumns.map((col) => {\n if (col === \"name\") {\n return helper.accessor(\"name\", {\n header: t(\"fields.Name\", { defaultValue: \"Name\" }),\n cell: (info) => (\n <Link\n to={`/app/${config.slug}/${info.getValue()}`}\n className=\"font-medium text-brand transition-colors hover:text-brand/80\"\n >\n {info.getValue()}\n </Link>\n ),\n });\n }\n\n if (col === \"status\") {\n return helper.accessor(\"status\", {\n header: t(\"fields.Status\", { defaultValue: \"Status\" }),\n cell: (info) => <StatusBadge status={info.getValue()} />,\n });\n }\n\n if (CURRENCY_FIELDS.has(col)) {\n return helper.accessor(col, {\n header: headerLabel(col),\n cell: (info) => formatCurrency(info.getValue(), (info.row.original as any)?.currency || baseCurrency),\n });\n }\n\n if (col === \"party\") {\n return helper.accessor(\"party\", {\n header: t(\"fields.Party\", { defaultValue: \"Party\" }),\n cell: (info) => {\n const value = info.getValue();\n if (!value) return \"-\";\n const masterType = partyMasterType(info.row.original.party_type);\n const href = masterType ? linkRefHref(masterType, String(value)) : null;\n if (!href) return String(value);\n return (\n <Link\n to={href}\n onClick={(e) => e.stopPropagation()}\n className=\"text-brand transition-colors hover:text-brand/80 hover:underline\"\n >\n {value}\n </Link>\n );\n },\n });\n }\n\n if (MASTER_REF_FIELDS[col]) {\n const masterType = MASTER_REF_FIELDS[col];\n return helper.accessor(col, {\n header: headerLabel(col),\n cell: (info) => {\n const value = info.getValue();\n if (!value) return \"-\";\n const href = linkRefHref(masterType, String(value));\n if (!href) return String(value);\n return (\n <Link\n to={href}\n onClick={(e) => e.stopPropagation()}\n className=\"text-brand transition-colors hover:text-brand/80 hover:underline\"\n >\n {value}\n </Link>\n );\n },\n });\n }\n\n if (DATE_FIELDS.has(col)) {\n return helper.accessor(col, {\n header: headerLabel(col),\n cell: (info) => formatDate(info.getValue()),\n });\n }\n\n return helper.accessor(col, {\n header: headerLabel(col),\n });\n });\n }, [config, t, baseCurrency]);\n\n const table = useReactTable({\n data: rows,\n columns,\n getCoreRowModel: getCoreRowModel(),\n });\n\n if (!config) {\n return (\n <p className=\"text-fg-muted\">\n Unknown document type: {doctype}\n </p>\n );\n }\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-end\">\n <Link to={`/app/${config.slug}/new`}>\n <Button>{t(\"common.new\")}</Button>\n </Link>\n </div>\n\n <div className=\"flex flex-wrap items-end gap-4\">\n {searchFields.length > 0 && (\n <Input\n label={t(\"common.search\", { defaultValue: \"Search\" })}\n type=\"search\"\n placeholder={t(\"common.searchPlaceholder\", { defaultValue: \"Search…\" })}\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n className=\"min-w-[16rem]\"\n />\n )}\n {configFilters.length === 0 ? (\n <Select\n label={t(\"fields.Status\", { defaultValue: \"Status\" })}\n options={STATUS_OPTIONS.map((s) => ({\n value: s,\n label: s === \"All\" ? t(\"common.all\") : t(`status.${s}`, { defaultValue: s }),\n }))}\n value={status}\n onChange={(e) => setStatus(e.target.value)}\n />\n ) : (\n configFilters.map((key) => {\n const field = config.fields.find((f) => f.name === key);\n const opts = (field?.options ?? []).map((o) =>\n typeof o === \"string\" ? { value: o, label: o } : o,\n );\n return (\n <Select\n key={key}\n label={t(`fields.${field?.label ?? key}`, { defaultValue: field?.label ?? key })}\n options={[{ value: \"\", label: t(\"common.all\") }, ...opts]}\n value={filterValues[key]}\n onChange={(e) => patchUrl({ [key]: e.target.value || null, page: null })}\n />\n );\n })\n )}\n <Input\n label={t(\"fields.From Date\", { defaultValue: \"From Date\" })}\n type=\"date\"\n value={fromDate}\n onChange={(e) => setFromDate(e.target.value)}\n />\n <Input\n label={t(\"fields.To Date\", { defaultValue: \"To Date\" })}\n type=\"date\"\n value={toDate}\n onChange={(e) => setToDate(e.target.value)}\n />\n <label className=\"flex h-10 items-center gap-2 text-sm text-fg-muted\">\n <input\n type=\"checkbox\"\n className=\"h-4 w-4 rounded border-line text-brand focus:ring-brand/30\"\n checked={!!showDiscarded}\n onChange={(e) => setShowDiscarded(e.target.checked)}\n />\n {t(\"common.showDiscarded\")}\n </label>\n </div>\n <DateRangePresets onSelect={(from, to) => patchUrl({ from, to, page: null })} />\n\n {isLoading ? (\n <p className=\"text-fg-muted\">{t(\"common.loading\")}</p>\n ) : rows.length === 0 ? (\n <p className=\"py-8 text-center text-fg-muted\">{t(\"reports.noDocuments\")}</p>\n ) : (\n <>\n <ListPager\n page={page}\n totalPages={totalPages}\n pageSize={pageSize}\n total={total}\n rangeStart={rangeStart}\n rangeEnd={rangeEnd}\n setPage={setPage}\n setPageSize={setPageSize}\n />\n <div className=\"overflow-x-auto rounded-xl bg-surface ring-1 ring-line shadow-card\">\n <table className=\"min-w-full divide-y divide-line text-sm\">\n <thead className=\"bg-surface-subtle\">\n {table.getHeaderGroups().map((headerGroup) => (\n <tr key={headerGroup.id}>\n {headerGroup.headers.map((header) => (\n <th\n key={header.id}\n className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-fg-muted\"\n >\n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n </th>\n ))}\n </tr>\n ))}\n </thead>\n <tbody className=\"divide-y divide-line\">\n {table.getRowModel().rows.map((row) => (\n <tr key={row.id} className=\"transition-colors hover:bg-surface-subtle\">\n {row.getVisibleCells().map((cell) => (\n <td key={cell.id} className=\"px-4 py-2.5 text-fg\">\n {flexRender(\n cell.column.columnDef.cell,\n cell.getContext(),\n )}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n\n <ListPager\n page={page}\n totalPages={totalPages}\n pageSize={pageSize}\n total={total}\n rangeStart={rangeStart}\n rangeEnd={rangeEnd}\n setPage={setPage}\n setPageSize={setPageSize}\n />\n </>\n )}\n </div>\n );\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { api } from \"@/api/client\";\nimport { cn } from \"@/lib/utils\";\n\ninterface LinkFieldProps {\n label: string;\n value: string;\n onChange: (value: string) => void;\n linkDoctype: string;\n readOnly: boolean;\n}\n\nexport function LinkField({\n label,\n value,\n onChange,\n linkDoctype,\n readOnly,\n}: LinkFieldProps) {\n const [query, setQuery] = useState(value ?? \"\");\n const [results, setResults] = useState<any[]>([]);\n const [open, setOpen] = useState(false);\n const [loading, setLoading] = useState(false);\n const [dropdownStyle, setDropdownStyle] = useState<React.CSSProperties>({});\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const selectingRef = useRef(false);\n\n // Sync external value changes\n useEffect(() => {\n setQuery(value ?? \"\");\n }, [value]);\n\n const updateDropdownPosition = useCallback(() => {\n if (inputRef.current) {\n const rect = inputRef.current.getBoundingClientRect();\n setDropdownStyle({\n position: \"fixed\",\n top: rect.bottom + 4,\n left: rect.left,\n width: rect.width,\n zIndex: 9999,\n });\n }\n }, []);\n\n const search = useCallback(\n (q: string) => {\n if (debounceRef.current) clearTimeout(debounceRef.current);\n debounceRef.current = setTimeout(async () => {\n setLoading(true);\n try {\n const data = await api.searchLink(linkDoctype, q);\n setResults(data);\n setOpen(true);\n } catch {\n setResults([]);\n } finally {\n setLoading(false);\n }\n }, 300);\n },\n [linkDoctype],\n );\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const q = e.target.value;\n setQuery(q);\n search(q);\n };\n\n const handleSelect = (item: any) => {\n const name = item.name ?? item.id ?? String(item);\n setQuery(name);\n onChange(name);\n setOpen(false);\n setResults([]);\n };\n\n const handleBlur = () => {\n setTimeout(() => {\n if (selectingRef.current) {\n selectingRef.current = false;\n return;\n }\n setOpen(false);\n if (query !== value) {\n onChange(query);\n }\n }, 150);\n };\n\n // Close dropdown on outside click (check both container and portal dropdown)\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n const target = e.target as Node;\n if (containerRef.current?.contains(target)) return;\n if (dropdownRef.current?.contains(target)) return;\n setOpen(false);\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, []);\n\n if (readOnly) {\n return (\n <div>\n {label && (\n <span className=\"mb-1.5 block text-sm font-medium text-fg\">\n {label}\n </span>\n )}\n <span className=\"text-sm text-fg\">{value || \"\\u2014\"}</span>\n </div>\n );\n }\n\n return (\n <div ref={containerRef} className=\"relative\">\n {label && (\n <label className=\"mb-1.5 block text-sm font-medium text-fg\">\n {label}\n </label>\n )}\n <input\n ref={inputRef}\n type=\"text\"\n value={query}\n onChange={handleInputChange}\n onFocus={() => {\n updateDropdownPosition();\n search(query);\n }}\n onBlur={handleBlur}\n placeholder={`Search ${linkDoctype}...`}\n className={cn(\n \"block h-9 w-full rounded-lg bg-surface px-3 text-sm text-fg ring-1 ring-line transition-all placeholder:text-fg-muted/70 focus:outline-none focus:ring-2 focus:ring-brand/30\",\n loading && \"bg-surface-subtle\",\n )}\n />\n {open && results.length > 0 && createPortal(\n <div ref={dropdownRef} style={dropdownStyle} className=\"max-h-48 overflow-y-auto rounded-lg bg-surface ring-1 ring-line shadow-card-hover\">\n {results.map((item, i) => {\n const name = item.name ?? item.id ?? String(item);\n return (\n <button\n key={i}\n type=\"button\"\n onMouseDown={() => { selectingRef.current = true; }}\n onClick={() => handleSelect(item)}\n className=\"block w-full px-3 py-1.5 text-left text-sm text-fg transition-colors hover:bg-surface-subtle\"\n >\n {name}\n </button>\n );\n })}\n </div>,\n document.body,\n )}\n </div>\n );\n}\n","import { useState, useEffect, useRef } from \"react\";\nimport { useParams, useNavigate } from \"react-router-dom\";\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { useTranslation } from \"react-i18next\";\nimport { api } from \"@/api/client\";\nimport { LinkField } from \"@/components/document/link-field\";\nimport { Button } from \"@/components/ui/button\";\nimport { useConfirm } from \"@/components/ui/dialog\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\n\n// A Proposal (Sammelofferte) bundles several independent quotations into one\n// branded PDF. It is print-only: nothing here touches the quotations' own\n// lifecycle. Saving lets the user reopen/duplicate so cover text isn't retyped.\n\ninterface PositionRow {\n quotation: string;\n position_title: string;\n position_blurb: string;\n is_recommended: number;\n}\n\nconst blankRow = (): PositionRow => ({\n quotation: \"\",\n position_title: \"\",\n position_blurb: \"\",\n is_recommended: 0,\n});\n\nconst LETTERS = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n\nexport default function ProposalForm() {\n const { name } = useParams<{ name: string }>();\n const isNew = !name;\n const navigate = useNavigate();\n const qc = useQueryClient();\n const { t } = useTranslation();\n const tr = (k: string, dflt: string) => t(k, { defaultValue: dflt });\n const confirm = useConfirm();\n\n const [form, setForm] = useState<Record<string, string>>({\n title: \"Offerte\",\n customer: \"\",\n company: \"\",\n proposal_date: new Date().toISOString().slice(0, 10),\n partner_name: \"\",\n partner_email: \"\",\n cover_letter: \"\",\n });\n const [rows, setRows] = useState<PositionRow[]>([blankRow()]);\n const [appendix, setAppendix] = useState<string | null>(null);\n const [appendixBusy, setAppendixBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const fileRef = useRef<HTMLInputElement>(null);\n\n const set = (k: string, v: string) => setForm((f) => ({ ...f, [k]: v }));\n\n // Load an existing proposal.\n const { data: existing } = useQuery({\n queryKey: [\"document\", \"proposal\", name],\n queryFn: () => api.getDocument(\"proposal\", name!),\n enabled: !isNew,\n });\n\n useEffect(() => {\n if (!existing) return;\n setForm({\n title: existing.title ?? \"Offerte\",\n customer: existing.customer ?? \"\",\n company: existing.company ?? \"\",\n proposal_date: existing.proposal_date ?? \"\",\n partner_name: existing.partner_name ?? \"\",\n partner_email: existing.partner_email ?? \"\",\n cover_letter: existing.cover_letter ?? \"\",\n });\n const qs = (existing.quotations ?? []) as PositionRow[];\n setRows(qs.length ? qs.map((r) => ({ ...blankRow(), ...r })) : [blankRow()]);\n setAppendix(existing.appendix_filename ?? null);\n }, [existing]);\n\n // Pre-fill the cover letter from the company template once a customer is\n // chosen on a NEW proposal and the letter is still empty — so the salutation\n // and intro aren't retyped. Never clobbers text the user has entered.\n const loadCoverDefault = async () => {\n try {\n const { cover_letter } = await api.getProposalCoverDefault(form.company, form.customer);\n if (cover_letter) set(\"cover_letter\", cover_letter);\n } catch {\n /* a missing template is fine */\n }\n };\n useEffect(() => {\n if (isNew && form.customer && !form.cover_letter) loadCoverDefault();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [form.customer, form.company]);\n\n const payload = () => ({\n ...form,\n quotations: rows\n .filter((r) => r.quotation)\n .map((r, i) => ({ ...r, idx: i + 1, is_recommended: r.is_recommended ? 1 : 0 })),\n });\n\n const saveMut = useMutation({\n mutationFn: async () => {\n if (isNew) return api.createDocument(\"proposal\", payload());\n return api.updateDocument(\"proposal\", name!, payload());\n },\n onSuccess: (res) => {\n setError(null);\n qc.invalidateQueries({ queryKey: [\"documents\", \"proposal\"] });\n qc.invalidateQueries({ queryKey: [\"document\", \"proposal\", res.name] });\n if (isNew) navigate(`/app/proposal/${encodeURIComponent(res.name)}`);\n },\n onError: (e: any) => setError(e?.message ?? \"Save failed\"),\n });\n\n const discardMut = useMutation({\n mutationFn: () => api.discardDocument(\"proposal\", name!),\n onSuccess: () => {\n qc.invalidateQueries({ queryKey: [\"documents\", \"proposal\"] });\n navigate(\"/app/proposal\");\n },\n onError: (e: any) => setError(e?.message ?? \"Discard failed\"),\n });\n\n // --- Position rows ---\n const updateRow = (i: number, patch: Partial<PositionRow>) =>\n setRows((rs) => rs.map((r, j) => (j === i ? { ...r, ...patch } : r)));\n const addRow = () => setRows((rs) => [...rs, blankRow()]);\n const removeRow = (i: number) => setRows((rs) => (rs.length > 1 ? rs.filter((_, j) => j !== i) : rs));\n const moveRow = (i: number, dir: -1 | 1) =>\n setRows((rs) => {\n const j = i + dir;\n if (j < 0 || j >= rs.length) return rs;\n const next = [...rs];\n [next[i], next[j]] = [next[j], next[i]];\n return next;\n });\n\n // --- Appendix ---\n const onPickAppendix = async (e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n e.target.value = \"\";\n if (!file || isNew) return;\n setAppendixBusy(true);\n setError(null);\n try {\n const res = await api.uploadProposalAppendix(name!, file);\n setAppendix(res.appendix_filename);\n qc.invalidateQueries({ queryKey: [\"document\", \"proposal\", name] });\n } catch (err: any) {\n setError(err?.message ?? \"Upload failed\");\n } finally {\n setAppendixBusy(false);\n }\n };\n const removeAppendix = async () => {\n if (isNew) return;\n setAppendixBusy(true);\n try {\n await api.deleteProposalAppendix(name!);\n setAppendix(null);\n } catch (err: any) {\n setError(err?.message ?? \"Failed\");\n } finally {\n setAppendixBusy(false);\n }\n };\n\n return (\n <div className=\"mx-auto max-w-4xl space-y-5 pb-16\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-xl font-semibold text-fg\">\n {isNew ? tr(\"proposal.new\", \"New Proposal\") : (form.title || tr(\"proposal.title\", \"Proposal\"))}\n </h1>\n {!isNew && <p className=\"text-sm text-fg-muted\">{name}</p>}\n </div>\n <div className=\"flex gap-2\">\n {!isNew && (\n <Button\n variant=\"danger\"\n disabled={discardMut.isPending}\n onClick={async () => {\n if (await confirm({\n title: tr(\"proposal.discardConfirm\", \"Discard this proposal? It will be hidden from the list.\"),\n confirmLabel: tr(\"common.discard\", \"Discard\"),\n danger: true,\n })) {\n discardMut.mutate();\n }\n }}\n >\n {discardMut.isPending ? tr(\"common.discarding\", \"Discarding…\") : tr(\"common.discard\", \"Discard\")}\n </Button>\n )}\n {!isNew && (\n <Button variant=\"secondary\" onClick={() => window.open(api.proposalPdfUrl(name!), \"_blank\")}>\n {tr(\"common.pdf\", \"PDF\")}\n </Button>\n )}\n <Button onClick={() => saveMut.mutate()} disabled={saveMut.isPending}>\n {saveMut.isPending ? tr(\"common.saving\", \"Saving…\") : tr(\"common.save\", \"Save\")}\n </Button>\n </div>\n </div>\n\n {error && (\n <div className=\"rounded-lg bg-red-50 px-4 py-2 text-sm text-red-700 ring-1 ring-red-200\">{error}</div>\n )}\n\n {/* Header fields */}\n <Card className=\"space-y-4 p-5\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <Input label={tr(\"fields.Title\", \"Title\")} value={form.title} onChange={(e) => set(\"title\", e.target.value)} />\n <Input label={tr(\"fields.Date\", \"Date\")} type=\"date\" value={form.proposal_date} onChange={(e) => set(\"proposal_date\", e.target.value)} />\n <LinkField label={tr(\"fields.Customer\", \"Customer\")} value={form.customer} onChange={(v) => set(\"customer\", v)} linkDoctype=\"customer\" readOnly={false} />\n <LinkField label={tr(\"fields.Company\", \"Company\")} value={form.company} onChange={(v) => set(\"company\", v)} linkDoctype=\"company\" readOnly={false} />\n <Input label={tr(\"fields.Partner\", \"Account Manager\")} value={form.partner_name} onChange={(e) => set(\"partner_name\", e.target.value)} />\n <Input label={tr(\"fields.Partner Email\", \"Account Manager Email\")} value={form.partner_email} onChange={(e) => set(\"partner_email\", e.target.value)} />\n </div>\n <div>\n <div className=\"mb-1.5 flex items-center justify-between\">\n <label className=\"block text-sm font-medium text-fg\">{tr(\"proposal.coverLetter\", \"Cover letter\")}</label>\n <button type=\"button\" onClick={loadCoverDefault} className=\"text-xs text-brand hover:underline\">\n {tr(\"proposal.loadTemplate\", \"Load from template\")}\n </button>\n </div>\n <textarea\n value={form.cover_letter}\n onChange={(e) => set(\"cover_letter\", e.target.value)}\n rows={5}\n className=\"block w-full rounded-lg bg-surface px-3 py-2 text-sm text-fg ring-1 ring-line focus:outline-none focus:ring-2 focus:ring-brand/30\"\n />\n </div>\n </Card>\n\n {/* Positions */}\n <Card className=\"space-y-4 p-5\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"font-semibold text-fg\">{tr(\"proposal.offers\", \"Offers\")}</h2>\n <Button size=\"sm\" variant=\"secondary\" onClick={addRow}>\n {tr(\"proposal.addOffer\", \"Add offer\")}\n </Button>\n </div>\n {rows.map((row, i) => (\n <div key={i} className=\"rounded-lg p-3 ring-1 ring-line\">\n <div className=\"mb-2 flex items-center gap-2\">\n <span className=\"flex h-6 w-6 items-center justify-center rounded-full bg-brand/10 text-sm font-bold text-brand\">\n {LETTERS[i] ?? i + 1}\n </span>\n <div className=\"flex-1\">\n <LinkField label=\"\" value={row.quotation} onChange={(v) => updateRow(i, { quotation: v })} linkDoctype=\"quotation\" readOnly={false} />\n </div>\n <button type=\"button\" onClick={() => moveRow(i, -1)} disabled={i === 0} className=\"px-1 text-fg-muted disabled:opacity-30\">↑</button>\n <button type=\"button\" onClick={() => moveRow(i, 1)} disabled={i === rows.length - 1} className=\"px-1 text-fg-muted disabled:opacity-30\">↓</button>\n <button type=\"button\" onClick={() => removeRow(i)} className=\"px-1 text-red-500 hover:text-red-700\">✕</button>\n </div>\n <div className=\"grid grid-cols-1 gap-2 pl-8 sm:grid-cols-2\">\n <Input label={tr(\"proposal.positionTitle\", \"Position title\")} value={row.position_title} onChange={(e) => updateRow(i, { position_title: e.target.value })} placeholder={tr(\"proposal.positionTitleHint\", \"defaults to the offer's first item\")} />\n <label className=\"flex items-center gap-2 self-end pb-2 text-sm text-fg\">\n <input type=\"checkbox\" checked={!!row.is_recommended} onChange={(e) => updateRow(i, { is_recommended: e.target.checked ? 1 : 0 })} />\n {tr(\"proposal.recommended\", \"Mark as recommendation\")}\n </label>\n <div className=\"sm:col-span-2\">\n <Input label={tr(\"proposal.blurb\", \"Description\")} value={row.position_blurb} onChange={(e) => updateRow(i, { position_blurb: e.target.value })} placeholder={tr(\"proposal.blurbHint\", \"defaults to the offer's notes\")} />\n </div>\n </div>\n </div>\n ))}\n </Card>\n\n {/* Appendix */}\n <Card className=\"space-y-3 p-5\">\n <h2 className=\"font-semibold text-fg\">{tr(\"proposal.appendix\", \"Appendix PDF\")}</h2>\n {isNew ? (\n <p className=\"text-sm text-fg-muted\">{tr(\"proposal.saveFirst\", \"Save the proposal first to attach an appendix.\")}</p>\n ) : appendix ? (\n <div className=\"flex items-center gap-3 text-sm\">\n <span className=\"text-fg\">📎 {appendix}</span>\n <button type=\"button\" onClick={removeAppendix} disabled={appendixBusy} className=\"text-red-500 hover:underline\">\n {tr(\"common.remove\", \"Remove\")}\n </button>\n </div>\n ) : (\n <div>\n <input ref={fileRef} type=\"file\" accept=\"application/pdf\" onChange={onPickAppendix} className=\"hidden\" />\n <Button size=\"sm\" variant=\"secondary\" disabled={appendixBusy} onClick={() => fileRef.current?.click()}>\n {appendixBusy ? tr(\"common.uploading\", \"Uploading…\") : tr(\"proposal.uploadAppendix\", \"Upload appendix PDF\")}\n </Button>\n <p className=\"mt-1 text-xs text-fg-muted\">{tr(\"proposal.appendixHint\", \"Appended after the offers — e.g. a price overview.\")}</p>\n </div>\n )}\n </Card>\n </div>\n );\n}\n","import { useEffect, useMemo } from \"react\";\nimport { Link, useParams, useNavigate, useLocation } from \"react-router-dom\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { useUrlState, useUrlPatch } from \"@/hooks/use-url-state\";\nimport {\n useReactTable,\n getCoreRowModel,\n flexRender,\n createColumnHelper,\n type ColumnDef,\n} from \"@tanstack/react-table\";\nimport { api } from \"@/api/client\";\nimport { setListContext } from \"@/lib/doc-list-context\";\nimport { Button } from \"@/components/ui/button\";\n\nconst TYPE_LABELS: Record<string, string> = {\n customer: \"Customer\",\n supplier: \"Supplier\",\n item: \"Item\",\n warehouse: \"Warehouse\",\n company: \"Company\",\n};\n\nconst PAGE_SIZE_OPTIONS = [\"25\", \"50\", \"100\", \"200\"];\n\nexport default function MasterListPage() {\n const { type } = useParams<{ type: string }>();\n const navigate = useNavigate();\n const location = useLocation();\n const label = TYPE_LABELS[type ?? \"\"] ?? type ?? \"\";\n const notice = (location.state as { notice?: string } | null)?.notice;\n\n // Stash the list URL so the detail page's DocPager can come \"back\" to this\n // exact page (Esc/u). Masters have no filter UI, so filters stays empty.\n useEffect(() => {\n if (type) setListContext(`master:${type}`, { filters: {}, search: location.search });\n }, [type, location.search]);\n\n const [pageSize] = useUrlState<number>(\"per_page\", 50);\n // URL page is 1-indexed; internal 0-indexed for offset math.\n const [urlPage] = useUrlState<number>(\"page\", 1);\n const page = urlPage - 1;\n const patchUrl = useUrlPatch();\n const setPage = (p: number) => patchUrl({ page: p === 0 ? null : p + 1 });\n const setPageSize = (n: number) => patchUrl({ per_page: n, page: null });\n\n const { data, isLoading } = useQuery({\n queryKey: [\"masters\", type, page, pageSize],\n queryFn: () => api.listMasters(type!, {\n include_disabled: 1,\n limit: pageSize,\n offset: page * pageSize,\n }),\n enabled: !!type,\n });\n\n const rows = data?.rows ?? [];\n const total = data?.total ?? 0;\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n const rangeStart = total === 0 ? 0 : page * pageSize + 1;\n const rangeEnd = Math.min(total, (page + 1) * pageSize);\n\n const columns = useMemo<ColumnDef<any, any>[]>(() => {\n if (!rows || rows.length === 0) return [];\n const helper = createColumnHelper<any>();\n const keys = Object.keys(rows[0]);\n\n return keys.map((key) =>\n helper.accessor(key, {\n header: key\n .split(\"_\")\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(\" \"),\n cell: (info) => {\n const val = info.getValue();\n if (key === \"name\") {\n const isDisabled = info.row.original.disabled === 1;\n return (\n <Link\n to={`/masters/${type}/${val}`}\n className={isDisabled ? \"font-medium text-fg-muted\" : \"font-medium text-brand transition-colors hover:text-brand/80\"}\n >\n {val}\n </Link>\n );\n }\n if (key === \"disabled\") {\n return val === 1 ? \"Disabled\" : \"Active\";\n }\n return val ?? \"-\";\n },\n }),\n );\n }, [rows, type]);\n\n const table = useReactTable({\n data: rows,\n columns,\n getCoreRowModel: getCoreRowModel(),\n });\n\n return (\n <div className=\"space-y-4\">\n {notice && (\n <div className=\"rounded-md bg-amber-50 px-4 py-3 text-sm text-amber-800\">\n {notice}\n </div>\n )}\n <div className=\"flex items-center justify-end\">\n <Link to={`/masters/${type}/new`}>\n <Button>New</Button>\n </Link>\n </div>\n\n {isLoading ? (\n <p className=\"text-fg-muted\">Loading...</p>\n ) : rows.length === 0 ? (\n <p className=\"py-8 text-center text-fg-muted\">No records found</p>\n ) : (\n <>\n <div className=\"overflow-x-auto rounded-xl bg-surface ring-1 ring-line shadow-card\">\n <table className=\"min-w-full divide-y divide-line text-sm\">\n <thead className=\"bg-surface-subtle\">\n {table.getHeaderGroups().map((headerGroup) => (\n <tr key={headerGroup.id}>\n {headerGroup.headers.map((header) => (\n <th\n key={header.id}\n className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-fg-muted\"\n >\n {header.isPlaceholder\n ? null\n : flexRender(\n header.column.columnDef.header,\n header.getContext(),\n )}\n </th>\n ))}\n </tr>\n ))}\n </thead>\n <tbody className=\"divide-y divide-line\">\n {table.getRowModel().rows.map((row) => (\n <tr\n key={row.id}\n className={\n row.original.disabled === 1\n ? \"cursor-pointer bg-surface-subtle text-fg-muted transition-colors hover:bg-surface-subtle/80\"\n : \"cursor-pointer text-fg transition-colors hover:bg-surface-subtle\"\n }\n onClick={() =>\n navigate(`/masters/${type}/${row.original.name}`)\n }\n >\n {row.getVisibleCells().map((cell) => (\n <td key={cell.id} className=\"px-4 py-2.5\">\n {flexRender(\n cell.column.columnDef.cell,\n cell.getContext(),\n )}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n\n <div className=\"flex flex-wrap items-center justify-between gap-3 text-sm text-fg-muted\">\n <div>\n Showing <span className=\"font-medium text-fg\">{rangeStart}–{rangeEnd}</span>{\" \"}\n of <span className=\"font-medium text-fg\">{total}</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <label className=\"flex items-center gap-1.5\">\n <span className=\"text-xs text-fg-muted\">Per page</span>\n <select\n value={pageSize}\n onChange={(e) => setPageSize(Number(e.target.value))}\n className=\"h-8 rounded-md bg-surface px-2 text-sm text-fg ring-1 ring-line transition-all focus:outline-none focus:ring-2 focus:ring-brand/30\"\n >\n {PAGE_SIZE_OPTIONS.map((n) => (\n <option key={n} value={n}>{n}</option>\n ))}\n </select>\n </label>\n <button\n onClick={() => setPage(Math.max(0, page - 1))}\n disabled={page === 0}\n className=\"rounded-md bg-surface px-3 py-1 text-sm text-fg ring-1 ring-line transition-colors hover:bg-surface-subtle disabled:cursor-not-allowed disabled:opacity-40\"\n >\n Prev\n </button>\n <span className=\"text-xs\">\n Page <span className=\"font-medium text-fg\">{page + 1}</span> of{\" \"}\n <span className=\"font-medium text-fg\">{totalPages}</span>\n </span>\n <button\n onClick={() => setPage(Math.min(totalPages - 1, page + 1))}\n disabled={page >= totalPages - 1}\n className=\"rounded-md bg-surface px-3 py-1 text-sm text-fg ring-1 ring-line transition-colors hover:bg-surface-subtle disabled:cursor-not-allowed disabled:opacity-40\"\n >\n Next\n </button>\n </div>\n </div>\n </>\n )}\n </div>\n );\n}\n","import { useState, useEffect } from \"react\";\nimport { useParams, useNavigate } from \"react-router-dom\";\nimport { useTranslation } from \"react-i18next\";\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { api } from \"@/api/client\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\nimport { Button } from \"@/components/ui/button\";\nimport { useConfirm } from \"@/components/ui/dialog\";\nimport { DocPager } from \"@/components/document/doc-pager\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Select } from \"@/components/ui/select\";\nimport type { FieldDef } from \"@/lib/doctypes\";\n\n// ---------------------------------------------------------------------------\n// Field registry per master type\n// ---------------------------------------------------------------------------\n\nconst MASTER_FIELDS: Record<string, FieldDef[]> = {\n customer: [\n { name: \"name\", label: \"ID\", type: \"text\", required: true },\n { name: \"customer_name\", label: \"Customer Name\", type: \"text\", required: true },\n { name: \"customer_group\", label: \"Customer Group\", type: \"select\", options: [\"Individual\", \"Commercial\", \"Government\", \"Non-Profit\", \"Premium\"] },\n { name: \"territory\", label: \"Territory\", type: \"text\" },\n { name: \"default_currency\", label: \"Currency\", type: \"select\", options: [\"\", \"USD\", \"EUR\", \"GBP\", \"CHF\", \"JPY\", \"CAD\", \"AUD\", \"CNY\", \"INR\"] },\n { name: \"credit_limit\", label: \"Credit Limit\", type: \"currency\" },\n { name: \"email\", label: \"Email\", type: \"text\" },\n { name: \"phone\", label: \"Phone\", type: \"text\" },\n { name: \"address\", label: \"Address\", type: \"textarea\" },\n { name: \"city\", label: \"City\", type: \"text\" },\n { name: \"zip_code\", label: \"Zip Code\", type: \"text\" },\n { name: \"country\", label: \"Country\", type: \"text\" },\n { name: \"tax_id\", label: \"Tax ID\", type: \"text\" },\n { name: \"contact_person\", label: \"Contact Person\", type: \"text\" },\n { name: \"contact_email\", label: \"Contact Email\", type: \"text\" },\n { name: \"contact_phone\", label: \"Contact Phone\", type: \"text\" },\n ],\n supplier: [\n { name: \"name\", label: \"ID\", type: \"text\", required: true },\n { name: \"supplier_name\", label: \"Supplier Name\", type: \"text\", required: true },\n { name: \"supplier_group\", label: \"Supplier Group\", type: \"select\", options: [\"Local\", \"Distributor\", \"Services\", \"Raw Materials\"] },\n { name: \"default_currency\", label: \"Currency\", type: \"select\", options: [\"\", \"USD\", \"EUR\", \"GBP\", \"CHF\", \"JPY\", \"CAD\", \"AUD\", \"CNY\", \"INR\"] },\n { name: \"email\", label: \"Email\", type: \"text\" },\n { name: \"phone\", label: \"Phone\", type: \"text\" },\n { name: \"address\", label: \"Address\", type: \"textarea\" },\n { name: \"city\", label: \"City\", type: \"text\" },\n { name: \"zip_code\", label: \"Zip Code\", type: \"text\" },\n { name: \"country\", label: \"Country\", type: \"text\" },\n { name: \"tax_id\", label: \"Tax ID\", type: \"text\" },\n ],\n item: [\n { name: \"name\", label: \"Item Code\", type: \"text\", required: true },\n { name: \"item_name\", label: \"Item Name\", type: \"text\", required: true },\n { name: \"item_group\", label: \"Item Group\", type: \"select\", options: [\"Products\", \"Raw Material\", \"Services\", \"Consumable\"] },\n { name: \"stock_uom\", label: \"Stock UOM\", type: \"select\", options: [\"Nos\", \"Kg\", \"Ltr\", \"Mtr\", \"Box\", \"Set\"] },\n { name: \"standard_rate\", label: \"Standard Rate\", type: \"currency\" },\n { name: \"description\", label: \"Description\", type: \"textarea\" },\n ],\n warehouse: [\n { name: \"warehouse_name\", label: \"Warehouse Name\", type: \"text\", required: true },\n { name: \"warehouse_type\", label: \"Type\", type: \"select\", options: [\"Stores\", \"Manufacturing\", \"Transit\", \"Rejected\"] },\n { name: \"company\", label: \"Company\", type: \"text\" },\n { name: \"address\", label: \"Address\", type: \"textarea\" },\n { name: \"city\", label: \"City\", type: \"text\" },\n { name: \"zip_code\", label: \"Zip Code\", type: \"text\" },\n { name: \"country\", label: \"Country\", type: \"text\" },\n ],\n company: [\n { name: \"company_name\", label: \"Company Name\", type: \"text\", required: true },\n // No static default — a new record's currency is pre-filled with the\n // company base currency by the effect in the form component below.\n { name: \"default_currency\", label: \"Currency\", type: \"text\" },\n { name: \"email\", label: \"Email\", type: \"text\" },\n { name: \"phone\", label: \"Phone\", type: \"text\" },\n { name: \"address\", label: \"Address\", type: \"textarea\" },\n { name: \"city\", label: \"City\", type: \"text\" },\n { name: \"zip_code\", label: \"Zip Code\", type: \"text\" },\n { name: \"country\", label: \"Country\", type: \"text\" },\n { name: \"tax_id\", label: \"Tax ID\", type: \"text\" },\n { name: \"iban\", label: \"IBAN\", type: \"text\" },\n ],\n};\n\nconst TYPE_LABELS: Record<string, string> = {\n customer: \"Customer\",\n supplier: \"Supplier\",\n item: \"Item\",\n warehouse: \"Warehouse\",\n company: \"Company\",\n};\n\nconst AUTO_NAME_TYPES = new Set([\"customer\", \"supplier\", \"item\", \"warehouse\"]);\n\n// ---------------------------------------------------------------------------\n// MasterFormPage\n// ---------------------------------------------------------------------------\n\nexport default function MasterFormPage() {\n const { type, name } = useParams<{ type: string; name: string }>();\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n const { t } = useTranslation();\n const isNew = !name || name === \"new\";\n const label = TYPE_LABELS[type ?? \"\"] ?? type ?? \"\";\n const labelTr = t(`masters.${type}.one`, { defaultValue: label });\n const fields = MASTER_FIELDS[type ?? \"\"] ?? [];\n const fieldLabel = (f: FieldDef) => t(`fields.${f.label}`, { defaultValue: f.label });\n\n const [formData, setFormData] = useState<Record<string, any>>({});\n\n // Fetch existing record\n const { data: existing, isLoading } = useQuery({\n queryKey: [\"master\", type, name],\n queryFn: () => api.getMaster(type!, name!),\n enabled: !!type && !!name && !isNew,\n });\n\n useEffect(() => {\n if (isNew) {\n const defaults: Record<string, any> = {};\n fields.forEach((f) => {\n defaults[f.name] = f.default ?? \"\";\n });\n setFormData(defaults);\n } else if (existing) {\n setFormData(existing);\n }\n }, [isNew, existing, fields]);\n\n // New masters with a default_currency field are pre-filled with the COMPANY\n // base currency (a hardcoded \"USD\" default gave new customers USD in a CHF\n // shop). Separate effect so the base-currency query resolving doesn't wipe\n // other fields the user already typed; it only fills an untouched currency.\n const companyCurrency = useBaseCurrency();\n useEffect(() => {\n if (!isNew || !companyCurrency) return;\n if (!fields.some((f) => f.name === \"default_currency\")) return;\n setFormData((prev: Record<string, any>) => {\n const current = prev.default_currency;\n if (current && current !== \"USD\") return prev; // user already chose one\n if (current === companyCurrency) return prev;\n return { ...prev, default_currency: companyCurrency };\n });\n }, [isNew, fields, companyCurrency]);\n\n // Mutations\n const createMut = useMutation({\n mutationFn: (data: any) => api.createMaster(type!, data),\n onSuccess: (result) => {\n queryClient.invalidateQueries({ queryKey: [\"masters\", type] });\n navigate(`/masters/${type}/${result.name}`, { replace: true });\n },\n });\n\n const updateMut = useMutation({\n mutationFn: (data: any) => api.updateMaster(type!, name!, data),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [\"master\", type, name] });\n queryClient.invalidateQueries({ queryKey: [\"masters\", type] });\n },\n });\n\n const deleteMut = useMutation({\n mutationFn: () => api.deleteMaster(type!, name!),\n onSuccess: (result) => {\n queryClient.invalidateQueries({ queryKey: [\"masters\", type] });\n if (result?.status === \"disabled\") {\n navigate(`/masters/${type}`, {\n replace: true,\n state: {\n notice: t(\"masterForm.disabledOnDelete\", {\n label: labelTr,\n name,\n reason: result.reason ?? \"other records\",\n }),\n },\n });\n return;\n }\n navigate(`/masters/${type}`, { replace: true });\n },\n });\n\n const handleSave = () => {\n if (missingRequiredFields.length > 0) return;\n const payload =\n type === \"company\" && !formData.name\n ? { ...formData, name: formData.company_name }\n : formData;\n if (isNew) {\n createMut.mutate(payload);\n } else {\n updateMut.mutate(payload);\n }\n };\n\n const confirm = useConfirm();\n const handleDelete = async () => {\n if (await confirm({\n title: t(\"masterForm.deleteConfirm\", { label: labelTr }),\n confirmLabel: t(\"common.delete\", { defaultValue: \"Delete\" }),\n danger: true,\n })) {\n deleteMut.mutate();\n }\n };\n\n const setField = (fieldName: string, value: any) => {\n setFormData((prev) => ({ ...prev, [fieldName]: value }));\n };\n\n if (!isNew && isLoading) {\n return <p className=\"text-fg-muted\">{t(\"common.loading\")}</p>;\n }\n\n const saving = createMut.isPending || updateMut.isPending;\n const missingRequiredFields = fields.filter((field) => {\n if (!field.required || field.readOnly) return false;\n if (isNew && field.name === \"name\" && AUTO_NAME_TYPES.has(type ?? \"\")) return false;\n const value = formData[field.name];\n return value === undefined || value === null || String(value).trim() === \"\";\n });\n\n return (\n <div className=\"space-y-6\">\n {/* Header: prev/next through the master list on the left, actions right */}\n <div className=\"flex items-center justify-between\">\n {!isNew ? (\n <DocPager kind=\"master\" slug={type!} name={name!} onSave={handleSave} />\n ) : (\n <div />\n )}\n <div className=\"flex gap-2\">\n <Button onClick={handleSave} disabled={saving || missingRequiredFields.length > 0}>\n {saving ? t(\"common.saving\") : t(\"common.save\")}\n </Button>\n {!isNew && (\n <Button\n variant=\"danger\"\n onClick={handleDelete}\n disabled={deleteMut.isPending}\n >\n {t(\"common.delete\")}\n </Button>\n )}\n </div>\n </div>\n\n {/* Error display */}\n {(createMut.error || updateMut.error || deleteMut.error) && (\n <div className=\"rounded-lg bg-rose-50 p-4 text-sm text-rose-700 ring-1 ring-rose-200\">\n {(createMut.error ?? updateMut.error ?? deleteMut.error)?.message ??\n t(\"common.errorOccurred\")}\n </div>\n )}\n {missingRequiredFields.length > 0 && (\n <div className=\"rounded-lg bg-amber-50 p-4 text-sm text-amber-800 ring-1 ring-amber-200\">\n {t(\"masterForm.required\", { fields: missingRequiredFields.map(fieldLabel).join(\", \") })}\n </div>\n )}\n {formData.disabled === 1 && (\n <div className=\"rounded-lg bg-amber-50 p-4 text-sm text-amber-800 ring-1 ring-amber-200\">\n {t(\"masterForm.disabledNotice\", { label: labelTr })}\n </div>\n )}\n\n {/* Form fields */}\n <Card>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n {fields.map((field) => {\n // Name field is read-only on edit\n const isNameField = field.name === \"name\" && !isNew;\n const isReadOnly = isNameField || field.readOnly;\n const isRequired = field.required && !(isNew && field.name === \"name\" && AUTO_NAME_TYPES.has(type ?? \"\"));\n\n if (field.type === \"select\" && field.options) {\n // A value saved through the API/chat can lie outside the hardcoded\n // option list (e.g. stock_uom \"Stück\") — a controlled <select> would\n // then silently render the \"Select...\" placeholder as if the field\n // were unset. Surface the stored value as an extra option so the GUI\n // shows what the backend actually holds.\n const current = formData[field.name];\n const options =\n typeof current === \"string\" && current !== \"\" && !field.options.includes(current)\n ? [...field.options, current]\n : field.options;\n return (\n <div key={field.name}>\n <Select\n label={fieldLabel(field)}\n options={options}\n value={formData[field.name] ?? \"\"}\n required={isRequired}\n disabled={isReadOnly}\n onChange={(e) => setField(field.name, e.target.value)}\n />\n </div>\n );\n }\n\n if (field.type === \"textarea\") {\n return (\n <div key={field.name} className=\"sm:col-span-2\">\n <label className=\"mb-1.5 block text-sm font-medium text-fg\">\n {fieldLabel(field)}\n </label>\n <textarea\n className=\"block w-full rounded-lg bg-surface px-3 py-2 text-sm text-fg ring-1 ring-line transition-all placeholder:text-fg-muted/70 focus:outline-none focus:ring-2 focus:ring-brand/30 disabled:bg-surface-subtle disabled:text-fg-muted\"\n rows={3}\n value={formData[field.name] ?? \"\"}\n required={isRequired}\n readOnly={isReadOnly}\n disabled={isReadOnly}\n onChange={(e) => setField(field.name, e.target.value)}\n />\n </div>\n );\n }\n\n const inputType =\n field.type === \"number\" || field.type === \"currency\"\n ? \"number\"\n : field.type === \"date\"\n ? \"date\"\n : \"text\";\n\n return (\n <Input\n key={field.name}\n label={fieldLabel(field)}\n type={inputType}\n step={field.type === \"currency\" ? \"0.01\" : undefined}\n required={isRequired}\n readOnly={isReadOnly}\n disabled={isReadOnly}\n value={formData[field.name] ?? \"\"}\n onChange={(e) =>\n setField(\n field.name,\n inputType === \"number\"\n ? parseFloat(e.target.value) || 0\n : e.target.value,\n )\n }\n />\n );\n })}\n </div>\n </Card>\n </div>\n );\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { api } from \"@/api/client\";\n\nexport function useTrialBalance(params?: Record<string, string>) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"trial-balance\", params],\n queryFn: () => api.trialBalance(params),\n });\n return { data, isLoading, error, refetch };\n}\n\nexport function useChartOfAccounts(params?: Record<string, string>) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"chart-of-accounts\", params],\n queryFn: () => api.chartOfAccounts(params),\n });\n return { data, isLoading, error, refetch };\n}\n\nexport function useGeneralLedger(params?: Record<string, string>) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"general-ledger\", params],\n queryFn: () => api.generalLedger(params),\n });\n return { data, isLoading, error, refetch };\n}\n\nexport function useStockBalance(params?: Record<string, string>) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"stock-balance\", params],\n queryFn: () => api.stockBalance(params),\n });\n return { data, isLoading, error, refetch };\n}\n\nexport function useProfitAndLoss(params?: Record<string, string>) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"profit-and-loss\", params],\n queryFn: () => api.profitAndLoss(params),\n });\n return { data, isLoading, error, refetch };\n}\n\nexport function useBalanceSheet(params?: Record<string, string>) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"balance-sheet\", params],\n queryFn: () => api.balanceSheet(params),\n });\n return { data, isLoading, error, refetch };\n}\n\nexport function useArAging(params?: Record<string, string>) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"ar-aging\", params],\n queryFn: () => api.arAging(params),\n });\n return { data, isLoading, error, refetch };\n}\n\nexport function useApAging(params?: Record<string, string>) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"ap-aging\", params],\n queryFn: () => api.apAging(params),\n });\n return { data, isLoading, error, refetch };\n}\n\nexport function useAnalyticsMetrics() {\n const { data, isLoading } = useQuery({\n queryKey: [\"analytics-metrics\"],\n queryFn: () => api.analyticsMetrics(),\n staleTime: 60_000,\n });\n return { data, isLoading };\n}\n\nexport function useAnalytics(params?: Record<string, string>) {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"analytics\", params],\n queryFn: () => api.analytics(params!),\n enabled: Boolean(params?.metric && params?.group_by),\n });\n return { data, isLoading, error, refetch };\n}\n\nexport function useRuntimeDatasets() {\n const { data, isLoading, error, refetch } = useQuery({\n queryKey: [\"report\", \"runtime-datasets\"],\n queryFn: () => api.runtimeDatasets(),\n staleTime: 60_000,\n });\n return { data, isLoading, error, refetch };\n}\n","import { useState, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useTrialBalance } from \"@/hooks/use-report\";\nimport { useUrlState, useUrlPatch } from \"@/hooks/use-url-state\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { LinkField } from \"@/components/document/link-field\";\nimport { DateRangePresets } from \"@/components/ui/date-range-presets\";\nimport { formatCurrency as fmtCurrency } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\n\nexport default function TrialBalancePage() {\n const { t } = useTranslation();\n const [urlCompany] = useUrlState<string>(\"company\", \"\");\n const [urlFromDate] = useUrlState<string>(\"from\", \"\");\n const [urlToDate] = useUrlState<string>(\"to\", \"\");\n const patchUrl = useUrlPatch();\n\n const [company, setCompany] = useState(urlCompany);\n const [fromDate, setFromDate] = useState(urlFromDate);\n const [toDate, setToDate] = useState(urlToDate);\n const baseCurrency = useBaseCurrency(company);\n const formatCurrency = (v: number | null | undefined) => fmtCurrency(v, baseCurrency);\n\n const filters = useMemo(() => {\n const f: Record<string, string> = {};\n if (urlCompany) f.company = urlCompany;\n if (urlFromDate) f.from_date = urlFromDate;\n if (urlToDate) f.to_date = urlToDate;\n return f;\n }, [urlCompany, urlFromDate, urlToDate]);\n\n const { data, isLoading, refetch } = useTrialBalance(filters);\n\n const handleApply = () => {\n patchUrl({\n company: company || null,\n from: fromDate || null,\n to: toDate || null,\n });\n refetch();\n };\n\n const isBalanced = data ? data.difference === 0 : false;\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <LinkField\n label={t(\"fields.Company\", { defaultValue: \"Company\" })}\n value={company}\n onChange={setCompany}\n linkDoctype=\"company\"\n readOnly={false}\n />\n <Input\n label={t(\"fields.From Date\", { defaultValue: \"From Date\" })}\n type=\"date\"\n value={fromDate}\n onChange={(e) => setFromDate(e.target.value)}\n />\n <Input\n label={t(\"fields.To Date\", { defaultValue: \"To Date\" })}\n type=\"date\"\n value={toDate}\n onChange={(e) => setToDate(e.target.value)}\n />\n <Button onClick={handleApply}>{t(\"common.apply\")}</Button>\n </div>\n <DateRangePresets onSelect={(from, to) => {\n setFromDate(from);\n setToDate(to);\n patchUrl({ from, to });\n }} />\n\n {isLoading ? (\n <p className=\"text-fg-muted\">{t(\"common.loading\")}</p>\n ) : !data || !data.rows || data.rows.length === 0 ? (\n <p className=\"py-8 text-center text-fg-muted\">{t(\"reports.noData\")}</p>\n ) : (\n <Card>\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full divide-y divide-line text-sm\">\n <thead className=\"bg-surface-subtle\">\n <tr>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wide text-fg-muted\">\n {t(\"fields.Account\", { defaultValue: \"Account\" })}\n </th>\n <th className=\"px-4 py-3 text-right text-xs font-medium uppercase tracking-wide text-fg-muted\">\n {t(\"fields.Debit\", { defaultValue: \"Debit\" })}\n </th>\n <th className=\"px-4 py-3 text-right text-xs font-medium uppercase tracking-wide text-fg-muted\">\n {t(\"fields.Credit\", { defaultValue: \"Credit\" })}\n </th>\n <th className=\"px-4 py-3 text-right text-xs font-medium uppercase tracking-wide text-fg-muted\">\n {t(\"fields.Balance\", { defaultValue: \"Balance\" })}\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-line\">\n {data.rows.map((row: any, idx: number) => (\n <tr key={idx} className=\"transition-colors hover:bg-surface-subtle\">\n <td className=\"px-4 py-2 text-fg\">{row.account}</td>\n <td className=\"px-4 py-2 text-right tabular-nums text-fg\">\n {formatCurrency(row.debit)}\n </td>\n <td className=\"px-4 py-2 text-right tabular-nums text-fg\">\n {formatCurrency(row.credit)}\n </td>\n <td className=\"px-4 py-2 text-right font-medium tabular-nums text-fg\">\n {formatCurrency(row.balance)}\n </td>\n </tr>\n ))}\n </tbody>\n <tfoot className=\"border-t border-line bg-surface-subtle font-semibold\">\n <tr>\n <td className=\"px-4 py-3 text-fg\">{t(\"common.total\")}</td>\n <td className=\"px-4 py-3 text-right tabular-nums text-fg\">\n {formatCurrency(data.total_debit)}\n </td>\n <td className=\"px-4 py-3 text-right tabular-nums text-fg\">\n {formatCurrency(data.total_credit)}\n </td>\n <td className=\"px-4 py-3 text-right tabular-nums text-fg\">\n {formatCurrency(data.difference)}\n </td>\n </tr>\n </tfoot>\n </table>\n </div>\n\n <div className=\"mt-4 text-center\">\n {isBalanced ? (\n <span className=\"inline-flex items-center gap-1.5 rounded-full bg-emerald-50 px-4 py-1.5 text-sm font-semibold text-emerald-700 ring-1 ring-emerald-200\">\n <span className=\"h-1.5 w-1.5 rounded-full bg-emerald-500\" />\n {t(\"reports.balanced\")}\n </span>\n ) : (\n <span className=\"inline-flex items-center gap-1.5 rounded-full bg-rose-50 px-4 py-1.5 text-sm font-semibold text-rose-700 ring-1 ring-rose-200\">\n <span className=\"h-1.5 w-1.5 rounded-full bg-rose-500\" />\n {t(\"reports.imbalanced\")}\n </span>\n )}\n </div>\n </Card>\n )}\n </div>\n );\n}\n","import { useMemo, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Link } from \"react-router-dom\";\nimport { ChevronDown, ChevronRight } from \"lucide-react\";\nimport { useChartOfAccounts } from \"@/hooks/use-report\";\nimport { Card } from \"@/components/ui/card\";\nimport { Select } from \"@/components/ui/select\";\nimport { formatCurrency as fmtCurrency } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\n\n// The account tree grouped by root type, with period balances. Each leaf links\n// to the General Ledger pre-filtered to that account + period — the GL page is\n// URL-backed (?account=&from=&to=), so the drill-down needs no extra plumbing.\n\ninterface CoaRow {\n name: string;\n account_name: string | null;\n parent_account: string | null;\n root_type: string | null;\n account_type: string | null;\n is_group: boolean;\n disabled: boolean;\n balance: number;\n has_entries: boolean;\n}\n\nconst ROOT_ORDER = [\"Asset\", \"Liability\", \"Equity\", \"Income\", \"Expense\"];\n\nexport default function ChartOfAccountsPage() {\n const { t } = useTranslation();\n const currentYear = new Date().getFullYear();\n const [year, setYear] = useState(String(currentYear));\n const [collapsed, setCollapsed] = useState<Set<string>>(new Set());\n\n const yearOptions = useMemo(() => {\n const opts: { value: string; label: string }[] = [];\n for (let y = currentYear; y >= currentYear - 6; y--) {\n opts.push({ value: String(y), label: String(y) });\n }\n opts.push({ value: \"all\", label: t(\"coa.allTime\", { defaultValue: \"All time\" }) });\n return opts;\n }, [currentYear, t]);\n\n const filters = useMemo(() => {\n const f: Record<string, string> = {};\n if (year !== \"all\") {\n f.from_date = `${year}-01-01`;\n f.to_date = `${year}-12-31`;\n }\n return f;\n }, [year]);\n\n const { data, isLoading } = useChartOfAccounts(filters);\n const baseCurrency = useBaseCurrency(\"\");\n const fmt = (v: number) => fmtCurrency(v, baseCurrency);\n\n const accounts: CoaRow[] = data?.accounts ?? [];\n\n // parent -> children, and the roots of each root_type section. An account\n // whose parent is missing from the result set is treated as a root.\n const { childrenOf, rootsByType } = useMemo(() => {\n const byName = new Map(accounts.map((a) => [a.name, a]));\n const childrenOf = new Map<string, CoaRow[]>();\n const rootsByType = new Map<string, CoaRow[]>();\n for (const acc of accounts) {\n if (acc.parent_account && byName.has(acc.parent_account)) {\n const list = childrenOf.get(acc.parent_account) ?? [];\n list.push(acc);\n childrenOf.set(acc.parent_account, list);\n } else {\n const key = acc.root_type ?? \"Other\";\n const list = rootsByType.get(key) ?? [];\n list.push(acc);\n rootsByType.set(key, list);\n }\n }\n return { childrenOf, rootsByType };\n }, [accounts]);\n\n const toggle = (name: string) => {\n setCollapsed((prev) => {\n const next = new Set(prev);\n if (next.has(name)) next.delete(name);\n else next.add(name);\n return next;\n });\n };\n\n const glLink = (name: string) => {\n const params = new URLSearchParams({ account: name });\n if (year !== \"all\") {\n params.set(\"from\", `${year}-01-01`);\n params.set(\"to\", `${year}-12-31`);\n }\n return `/reports/general-ledger?${params.toString()}`;\n };\n\n const renderRow = (acc: CoaRow, depth: number): React.ReactNode => {\n const kids = childrenOf.get(acc.name) ?? [];\n const isCollapsed = collapsed.has(acc.name);\n const dim = !acc.has_entries || acc.disabled;\n return (\n <div key={acc.name}>\n <div\n className={`flex items-center gap-2 rounded px-2 py-1.5 text-sm hover:bg-surface-subtle ${dim ? \"text-fg-muted\" : \"text-fg\"}`}\n style={{ paddingLeft: `${8 + depth * 20}px` }}\n >\n {kids.length > 0 ? (\n <button\n type=\"button\"\n onClick={() => toggle(acc.name)}\n className=\"shrink-0 text-fg-muted transition-colors hover:text-fg\"\n >\n {isCollapsed ? <ChevronRight className=\"h-3.5 w-3.5\" /> : <ChevronDown className=\"h-3.5 w-3.5\" />}\n </button>\n ) : (\n <span className=\"w-3.5 shrink-0\" />\n )}\n <span className={`min-w-0 flex-1 truncate ${acc.is_group ? \"font-medium\" : \"\"}`}>\n {acc.is_group ? (\n <>{acc.account_name || acc.name}</>\n ) : (\n <Link to={glLink(acc.name)} className=\"hover:text-brand hover:underline\">\n <span className=\"font-mono text-xs text-fg-muted\">{acc.name}</span>{\" \"}\n {acc.account_name || acc.name}\n </Link>\n )}\n {acc.disabled && (\n <span className=\"ml-2 text-xs text-fg-muted\">\n {t(\"coa.disabled\", { defaultValue: \"disabled\" })}\n </span>\n )}\n </span>\n {acc.account_type && (\n <span className=\"hidden shrink-0 text-xs text-fg-muted sm:inline\">{acc.account_type}</span>\n )}\n <span className=\"w-32 shrink-0 text-right font-mono text-sm tabular-nums\">\n {acc.has_entries || acc.is_group ? fmt(acc.balance) : \"—\"}\n </span>\n </div>\n {!isCollapsed && kids.map((kid) => renderRow(kid, depth + 1))}\n </div>\n );\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <div className=\"w-40\">\n <Select\n label={t(\"coa.period\", { defaultValue: \"Period\" })}\n options={yearOptions}\n value={year}\n onChange={(e) => setYear(e.target.value)}\n />\n </div>\n <p className=\"pb-2 text-xs text-fg-muted\">\n {t(\"coa.semantics\", {\n defaultValue:\n \"Balance-sheet accounts: closing balance at period end. P&L accounts: movement within the period. Click an account for its ledger.\",\n })}\n </p>\n </div>\n\n {isLoading && (\n <Card>\n <p className=\"text-sm text-fg-muted\">{t(\"common.loading\", { defaultValue: \"Loading…\" })}</p>\n </Card>\n )}\n\n {!isLoading && accounts.length === 0 && (\n <Card>\n <p className=\"text-sm text-fg-muted\">\n {t(\"coa.empty\", { defaultValue: \"No accounts found. Complete the company setup first.\" })}\n </p>\n </Card>\n )}\n\n {!isLoading &&\n ROOT_ORDER.filter((rt) => (rootsByType.get(rt) ?? []).length > 0).map((rootType) => (\n <Card key={rootType}>\n <h3 className=\"mb-2 px-2 text-xs font-semibold uppercase tracking-wider text-fg-muted\">\n {t(`coa.rootType.${rootType}`, { defaultValue: rootType })}\n </h3>\n <div>{(rootsByType.get(rootType) ?? []).map((acc) => renderRow(acc, 0))}</div>\n </Card>\n ))}\n </div>\n );\n}\n","import { useState, useMemo } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { useTranslation } from \"react-i18next\";\nimport { useGeneralLedger } from \"@/hooks/use-report\";\nimport { useUrlState, useUrlPatch } from \"@/hooks/use-url-state\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { LinkField } from \"@/components/document/link-field\";\nimport { DateRangePresets } from \"@/components/ui/date-range-presets\";\nimport { formatCurrency as fmtCurrency, formatDate } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\n\n/** Convert a voucher type like \"Sales Invoice\" to a URL slug \"sales-invoice\". */\nfunction toSlug(voucherType: string): string {\n return voucherType.toLowerCase().replace(/\\s+/g, \"-\");\n}\n\nconst PAGE_SIZE_OPTIONS = [\"25\", \"50\", \"100\", \"200\"];\n\nexport default function GeneralLedgerPage() {\n const { t } = useTranslation();\n // URL-backed filter and pagination state. Param names match the backend\n // where it's natural (account, party) and use human-friendly short forms\n // for pagination and dates (page, per_page, from, to).\n const [urlAccount] = useUrlState<string>(\"account\", \"\");\n const [urlParty] = useUrlState<string>(\"party\", \"\");\n const [urlFromDate] = useUrlState<string>(\"from\", \"\");\n const [urlToDate] = useUrlState<string>(\"to\", \"\");\n const [pageSize] = useUrlState<number>(\"per_page\", 50);\n const [urlPage] = useUrlState<number>(\"page\", 1);\n const page = urlPage - 1;\n const patchUrl = useUrlPatch();\n const setPage = (p: number) => patchUrl({ page: p === 0 ? null : p + 1 });\n const setPageSize = (n: number) => patchUrl({ per_page: n, page: null });\n\n // The input fields let the user type/pick without firing the query on\n // every keystroke — they only flush on Apply / preset click. Seed from the\n // URL so a cold open with filters pre-populates the inputs too.\n const [account, setAccount] = useState(urlAccount);\n const [party, setParty] = useState(urlParty);\n const [fromDate, setFromDate] = useState(urlFromDate);\n const [toDate, setToDate] = useState(urlToDate);\n const baseCurrency = useBaseCurrency();\n const formatCurrency = (v: number | null | undefined) => fmtCurrency(v, baseCurrency);\n\n const filters = useMemo(() => {\n const f: Record<string, string> = {};\n if (urlAccount) f.account = urlAccount;\n if (urlParty) f.party = urlParty;\n if (urlFromDate) f.from_date = urlFromDate;\n if (urlToDate) f.to_date = urlToDate;\n f.limit = String(pageSize);\n f.offset = String(page * pageSize);\n return f;\n }, [urlAccount, urlParty, urlFromDate, urlToDate, pageSize, page]);\n\n const { data, isLoading, refetch } = useGeneralLedger(filters);\n\n const rows = data?.rows ?? [];\n const total = data?.total ?? 0;\n const totalPages = Math.max(1, Math.ceil(total / pageSize));\n const rangeStart = total === 0 ? 0 : page * pageSize + 1;\n const rangeEnd = Math.min(total, (page + 1) * pageSize);\n\n const handleApply = () => {\n patchUrl({\n account: account || null,\n party: party || null,\n from: fromDate || null,\n to: toDate || null,\n page: null,\n });\n refetch();\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <LinkField\n label={t(\"fields.Account\", { defaultValue: \"Account\" })}\n value={account}\n onChange={setAccount}\n linkDoctype=\"account\"\n readOnly={false}\n />\n <LinkField\n label={t(\"fields.Party\", { defaultValue: \"Party\" })}\n value={party}\n onChange={setParty}\n linkDoctype=\"customer\"\n readOnly={false}\n />\n <Input\n label={t(\"fields.From Date\", { defaultValue: \"From Date\" })}\n type=\"date\"\n value={fromDate}\n onChange={(e) => setFromDate(e.target.value)}\n />\n <Input\n label={t(\"fields.To Date\", { defaultValue: \"To Date\" })}\n type=\"date\"\n value={toDate}\n onChange={(e) => setToDate(e.target.value)}\n />\n <Button onClick={handleApply}>{t(\"common.apply\")}</Button>\n </div>\n <DateRangePresets onSelect={(from, to) => {\n setFromDate(from);\n setToDate(to);\n patchUrl({ from, to, page: null });\n }} />\n\n {isLoading ? (\n <p className=\"text-gray-500\">{t(\"common.loading\")}</p>\n ) : rows.length === 0 ? (\n <p className=\"py-8 text-center text-gray-400\">{t(\"reports.noEntries\")}</p>\n ) : (\n <>\n <Card>\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">\n {t(\"fields.Date\", { defaultValue: \"Date\" })}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">\n {t(\"fields.Account\", { defaultValue: \"Account\" })}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">\n {t(\"fields.Party\", { defaultValue: \"Party\" })}\n </th>\n <th className=\"px-4 py-3 text-right font-medium text-gray-500\">\n {t(\"fields.Debit\", { defaultValue: \"Debit\" })}\n </th>\n <th className=\"px-4 py-3 text-right font-medium text-gray-500\">\n {t(\"fields.Credit\", { defaultValue: \"Credit\" })}\n </th>\n <th className=\"px-4 py-3 text-right font-medium text-gray-500\">\n {t(\"fields.Balance\", { defaultValue: \"Balance\" })}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">\n {t(\"fields.Voucher Type\", { defaultValue: \"Voucher Type\" })}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">\n {t(\"fields.Voucher No\", { defaultValue: \"Voucher No\" })}\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {rows.map((row: any, idx: number) => (\n <tr key={idx} className=\"hover:bg-gray-50\">\n <td className=\"px-4 py-2 text-gray-500\">\n {formatDate(row.posting_date ?? row.date)}\n </td>\n <td className=\"px-4 py-2 text-gray-900\">{row.account}</td>\n <td className=\"px-4 py-2 text-gray-700\">\n {row.party ?? \"-\"}\n </td>\n <td className=\"px-4 py-2 text-right\">\n {formatCurrency(row.debit)}\n </td>\n <td className=\"px-4 py-2 text-right\">\n {formatCurrency(row.credit)}\n </td>\n <td className=\"px-4 py-2 text-right font-medium\">\n {formatCurrency(row.balance)}\n </td>\n <td className=\"px-4 py-2 text-gray-700\">\n {row.voucher_type ?? \"-\"}\n </td>\n <td className=\"px-4 py-2\">\n {row.voucher_type && row.voucher_no ? (\n <Link\n to={`/app/${toSlug(row.voucher_type)}/${row.voucher_no}`}\n className=\"font-medium text-blue-600 hover:text-blue-800\"\n >\n {row.voucher_no}\n </Link>\n ) : (\n row.voucher_no ?? \"-\"\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </Card>\n\n <div className=\"flex flex-wrap items-center justify-between gap-3 text-sm text-gray-600\">\n <div>\n {t(\"common.showing\")} <span className=\"font-medium text-gray-900\">{rangeStart}–{rangeEnd}</span>{\" \"}\n {t(\"common.of\")} <span className=\"font-medium text-gray-900\">{total}</span>\n </div>\n <div className=\"flex items-center gap-2\">\n <label className=\"flex items-center gap-1.5\">\n <span className=\"text-xs text-gray-500\">{t(\"common.perPage\")}</span>\n <select\n value={pageSize}\n onChange={(e) => setPageSize(Number(e.target.value))}\n className=\"rounded border border-gray-300 bg-white px-2 py-1 text-sm\"\n >\n {PAGE_SIZE_OPTIONS.map((n) => (\n <option key={n} value={n}>{n}</option>\n ))}\n </select>\n </label>\n <button\n onClick={() => setPage(Math.max(0, page - 1))}\n disabled={page === 0}\n className=\"rounded border border-gray-300 bg-white px-3 py-1 text-sm text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-40\"\n >\n {t(\"common.prev\")}\n </button>\n <span className=\"text-xs\">\n {t(\"common.page\")} <span className=\"font-medium text-gray-900\">{page + 1}</span> {t(\"common.of\")}{\" \"}\n <span className=\"font-medium text-gray-900\">{totalPages}</span>\n </span>\n <button\n onClick={() => setPage(Math.min(totalPages - 1, page + 1))}\n disabled={page >= totalPages - 1}\n className=\"rounded border border-gray-300 bg-white px-3 py-1 text-sm text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-40\"\n >\n {t(\"common.next\")}\n </button>\n </div>\n </div>\n </>\n )}\n </div>\n );\n}\n","import { useState, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useStockBalance } from \"@/hooks/use-report\";\nimport { useUrlState, useUrlPatch } from \"@/hooks/use-url-state\";\nimport { Card } from \"@/components/ui/card\";\nimport { Button } from \"@/components/ui/button\";\nimport { LinkField } from \"@/components/document/link-field\";\nimport { formatCurrency as fmtCurrency, formatNumber } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\n\nexport default function StockBalancePage() {\n const { t } = useTranslation();\n const [urlItemCode] = useUrlState<string>(\"item_code\", \"\");\n const [urlWarehouse] = useUrlState<string>(\"warehouse\", \"\");\n const patchUrl = useUrlPatch();\n\n const [itemCode, setItemCode] = useState(urlItemCode);\n const [warehouse, setWarehouse] = useState(urlWarehouse);\n const baseCurrency = useBaseCurrency();\n const formatCurrency = (v: number | null | undefined) => fmtCurrency(v, baseCurrency);\n\n const filters = useMemo(() => {\n const f: Record<string, string> = {};\n if (urlItemCode) f.item_code = urlItemCode;\n if (urlWarehouse) f.warehouse = urlWarehouse;\n return f;\n }, [urlItemCode, urlWarehouse]);\n\n const { data, isLoading, refetch } = useStockBalance(filters);\n\n const handleApply = () => {\n patchUrl({\n item_code: itemCode || null,\n warehouse: warehouse || null,\n });\n refetch();\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <LinkField\n label={t(\"fields.Item Code\", { defaultValue: \"Item Code\" })}\n value={itemCode}\n onChange={setItemCode}\n linkDoctype=\"item\"\n readOnly={false}\n />\n <LinkField\n label={t(\"fields.Warehouse\", { defaultValue: \"Warehouse\" })}\n value={warehouse}\n onChange={setWarehouse}\n linkDoctype=\"warehouse\"\n readOnly={false}\n />\n <Button onClick={handleApply}>{t(\"common.apply\")}</Button>\n </div>\n\n {isLoading ? (\n <p className=\"text-gray-500\">{t(\"common.loading\")}</p>\n ) : !data || !data.rows || data.rows.length === 0 ? (\n <p className=\"py-8 text-center text-gray-400\">{t(\"reports.noStockData\")}</p>\n ) : (\n <Card>\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">\n {t(\"fields.Item Code\", { defaultValue: \"Item Code\" })}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">\n {t(\"fields.Item Name\", { defaultValue: \"Item Name\" })}\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">\n {t(\"fields.Warehouse\", { defaultValue: \"Warehouse\" })}\n </th>\n <th className=\"px-4 py-3 text-right font-medium text-gray-500\">\n {t(\"fields.Qty\", { defaultValue: \"Qty\" })}\n </th>\n <th className=\"px-4 py-3 text-right font-medium text-gray-500\">\n {t(\"fields.Valuation Rate\", { defaultValue: \"Valuation Rate\" })}\n </th>\n <th className=\"px-4 py-3 text-right font-medium text-gray-500\">\n {t(\"fields.Stock Value\", { defaultValue: \"Stock Value\" })}\n </th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {data.rows.map((row: any, idx: number) => (\n <tr key={idx} className=\"hover:bg-gray-50\">\n <td className=\"px-4 py-2 font-medium text-gray-900\">\n {row.item_code}\n </td>\n <td className=\"px-4 py-2 text-gray-700\">\n {row.item_name}\n </td>\n <td className=\"px-4 py-2 text-gray-700\">\n {row.warehouse}\n </td>\n <td className=\"px-4 py-2 text-right\">\n {formatNumber(row.actual_qty)}\n </td>\n <td className=\"px-4 py-2 text-right\">\n {formatCurrency(row.valuation_rate)}\n </td>\n <td className=\"px-4 py-2 text-right font-medium\">\n {formatCurrency(row.stock_value)}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </Card>\n )}\n </div>\n );\n}\n","import { useState, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useProfitAndLoss } from \"@/hooks/use-report\";\nimport { useUrlState, useUrlPatch } from \"@/hooks/use-url-state\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { LinkField } from \"@/components/document/link-field\";\nimport { DateRangePresets } from \"@/components/ui/date-range-presets\";\nimport { formatCurrency as fmtCurrency } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\n\nexport default function ProfitLossPage() {\n const { t } = useTranslation();\n const [urlCompany] = useUrlState<string>(\"company\", \"\");\n const [urlFromDate] = useUrlState<string>(\"from\", \"\");\n const [urlToDate] = useUrlState<string>(\"to\", \"\");\n const patchUrl = useUrlPatch();\n\n const [company, setCompany] = useState(urlCompany);\n const baseCurrency = useBaseCurrency(company);\n const formatCurrency = (v: number | null | undefined) => fmtCurrency(v, baseCurrency);\n const [fromDate, setFromDate] = useState(urlFromDate);\n const [toDate, setToDate] = useState(urlToDate);\n\n const filters = useMemo(() => {\n const f: Record<string, string> = {};\n if (urlCompany) f.company = urlCompany;\n if (urlFromDate) f.from_date = urlFromDate;\n if (urlToDate) f.to_date = urlToDate;\n return f;\n }, [urlCompany, urlFromDate, urlToDate]);\n\n const { data, isLoading, refetch } = useProfitAndLoss(filters);\n\n const handleApply = () => {\n patchUrl({\n company: company || null,\n from: fromDate || null,\n to: toDate || null,\n });\n refetch();\n };\n\n const hasData = data && ((data.income && data.income.length > 0) || (data.expense && data.expense.length > 0));\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <LinkField label={t(\"fields.Company\", { defaultValue: \"Company\" })} value={company} onChange={setCompany} linkDoctype=\"company\" readOnly={false} />\n <Input label={t(\"fields.From Date\", { defaultValue: \"From Date\" })} type=\"date\" value={fromDate} onChange={(e) => setFromDate(e.target.value)} />\n <Input label={t(\"fields.To Date\", { defaultValue: \"To Date\" })} type=\"date\" value={toDate} onChange={(e) => setToDate(e.target.value)} />\n <Button onClick={handleApply}>{t(\"common.apply\")}</Button>\n </div>\n <DateRangePresets onSelect={(from, to) => {\n setFromDate(from);\n setToDate(to);\n patchUrl({ from, to });\n }} />\n\n {isLoading ? (\n <p className=\"text-gray-500\">{t(\"common.loading\")}</p>\n ) : !hasData ? (\n <p className=\"py-8 text-center text-gray-400\">{t(\"reports.noData\")}</p>\n ) : (\n <div className=\"space-y-4\">\n <Card>\n <h3 className=\"mb-3 text-base font-semibold text-gray-800\">{t(\"reports.income\")}</h3>\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">{t(\"fields.Account\", { defaultValue: \"Account\" })}</th>\n <th className=\"px-4 py-3 text-right font-medium text-gray-500\">{t(\"fields.Amount\", { defaultValue: \"Amount\" })}</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {(data.income || []).map((row: any, idx: number) => (\n <tr key={idx} className=\"hover:bg-gray-50\">\n <td className=\"px-4 py-2 text-gray-900\">{row.account}</td>\n <td className=\"px-4 py-2 text-right\">{formatCurrency(row.amount)}</td>\n </tr>\n ))}\n </tbody>\n <tfoot className=\"border-t-2 border-gray-300 bg-gray-50 font-semibold\">\n <tr>\n <td className=\"px-4 py-3 text-gray-900\">{t(\"reports.totalIncome\")}</td>\n <td className=\"px-4 py-3 text-right\">{formatCurrency(data.total_income)}</td>\n </tr>\n </tfoot>\n </table>\n </Card>\n\n <Card>\n <h3 className=\"mb-3 text-base font-semibold text-gray-800\">{t(\"reports.expenses\")}</h3>\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">{t(\"fields.Account\", { defaultValue: \"Account\" })}</th>\n <th className=\"px-4 py-3 text-right font-medium text-gray-500\">{t(\"fields.Amount\", { defaultValue: \"Amount\" })}</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {(data.expense || []).map((row: any, idx: number) => (\n <tr key={idx} className=\"hover:bg-gray-50\">\n <td className=\"px-4 py-2 text-gray-900\">{row.account}</td>\n <td className=\"px-4 py-2 text-right\">{formatCurrency(row.amount)}</td>\n </tr>\n ))}\n </tbody>\n <tfoot className=\"border-t-2 border-gray-300 bg-gray-50 font-semibold\">\n <tr>\n <td className=\"px-4 py-3 text-gray-900\">{t(\"reports.totalExpenses\")}</td>\n <td className=\"px-4 py-3 text-right\">{formatCurrency(data.total_expense)}</td>\n </tr>\n </tfoot>\n </table>\n </Card>\n\n <div className=\"text-center\">\n <span className={`inline-flex items-center rounded-full px-5 py-2 text-sm font-semibold ${data.net_profit >= 0 ? \"bg-green-100 text-green-800\" : \"bg-red-100 text-red-800\"}`}>\n {data.net_profit >= 0 ? t(\"reports.netProfit\") : t(\"reports.netLoss\")}: {formatCurrency(Math.abs(data.net_profit))}\n </span>\n </div>\n </div>\n )}\n </div>\n );\n}\n","import { useState, useMemo } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { useBalanceSheet } from \"@/hooks/use-report\";\nimport { useUrlState, useUrlPatch } from \"@/hooks/use-url-state\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { LinkField } from \"@/components/document/link-field\";\nimport { SingleDatePresets } from \"@/components/ui/date-range-presets\";\nimport { formatCurrency as fmtCurrency } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\n\nfunction SectionTable({ title, rows, total, totalLabel, currency }: { title: string; rows: any[]; total: number; totalLabel: string; currency: string }) {\n const { t } = useTranslation();\n const formatCurrency = (v: number | null | undefined) => fmtCurrency(v, currency);\n return (\n <Card>\n <h3 className=\"mb-3 text-base font-semibold text-gray-800\">{title}</h3>\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-4 py-3 text-left font-medium text-gray-500\">{t(\"fields.Account\", { defaultValue: \"Account\" })}</th>\n <th className=\"px-4 py-3 text-right font-medium text-gray-500\">{t(\"fields.Balance\", { defaultValue: \"Balance\" })}</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {rows.map((row: any, idx: number) => (\n <tr key={idx} className=\"hover:bg-gray-50\">\n <td className=\"px-4 py-2 text-gray-900\">{row.account}</td>\n <td className=\"px-4 py-2 text-right\">{formatCurrency(row.balance)}</td>\n </tr>\n ))}\n </tbody>\n <tfoot className=\"border-t-2 border-gray-300 bg-gray-50 font-semibold\">\n <tr>\n <td className=\"px-4 py-3 text-gray-900\">{totalLabel}</td>\n <td className=\"px-4 py-3 text-right\">{formatCurrency(total)}</td>\n </tr>\n </tfoot>\n </table>\n </Card>\n );\n}\n\nexport default function BalanceSheetPage() {\n const { t } = useTranslation();\n const [urlCompany] = useUrlState<string>(\"company\", \"\");\n const [urlAsOfDate] = useUrlState<string>(\"as_of_date\", \"\");\n const patchUrl = useUrlPatch();\n\n const [company, setCompany] = useState(urlCompany);\n const [asOfDate, setAsOfDate] = useState(urlAsOfDate);\n const baseCurrency = useBaseCurrency(company);\n const formatCurrency = (v: number | null | undefined) => fmtCurrency(v, baseCurrency);\n\n const filters = useMemo(() => {\n const f: Record<string, string> = {};\n if (urlCompany) f.company = urlCompany;\n if (urlAsOfDate) f.as_of_date = urlAsOfDate;\n return f;\n }, [urlCompany, urlAsOfDate]);\n\n const { data, isLoading, refetch } = useBalanceSheet(filters);\n\n const handleApply = () => {\n patchUrl({ company: company || null, as_of_date: asOfDate || null });\n refetch();\n };\n\n const hasData = data && ((data.assets?.length > 0) || (data.liabilities?.length > 0) || (data.equity?.length > 0));\n const isBalanced = data ? Math.abs(data.total_assets - data.total_liabilities_and_equity) < 0.01 : false;\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <LinkField label={t(\"fields.Company\", { defaultValue: \"Company\" })} value={company} onChange={setCompany} linkDoctype=\"company\" readOnly={false} />\n <Input label={t(\"fields.As of Date\", { defaultValue: \"As of Date\" })} type=\"date\" value={asOfDate} onChange={(e) => setAsOfDate(e.target.value)} />\n <Button onClick={handleApply}>{t(\"common.apply\")}</Button>\n </div>\n <SingleDatePresets onSelect={(date) => {\n setAsOfDate(date);\n patchUrl({ as_of_date: date });\n }} />\n\n {isLoading ? (\n <p className=\"text-gray-500\">{t(\"common.loading\")}</p>\n ) : !hasData ? (\n <p className=\"py-8 text-center text-gray-400\">{t(\"reports.noData\")}</p>\n ) : (\n <div className=\"space-y-4\">\n <SectionTable title={t(\"reports.assets\")} rows={data.assets || []} total={data.total_assets} totalLabel={t(\"reports.totalAssets\")} currency={baseCurrency} />\n <SectionTable title={t(\"reports.liabilities\")} rows={data.liabilities || []} total={data.total_liabilities} totalLabel={t(\"reports.totalLiabilities\")} currency={baseCurrency} />\n <SectionTable title={t(\"reports.equity\")} rows={data.equity || []} total={data.total_equity} totalLabel={t(\"reports.totalEquity\")} currency={baseCurrency} />\n\n <Card>\n <div className=\"flex items-center justify-between\">\n <div className=\"text-sm\">\n <div className=\"text-gray-500\">{t(\"reports.totalAssets\")}: <span className=\"font-semibold text-gray-900\">{formatCurrency(data.total_assets)}</span></div>\n <div className=\"text-gray-500\">{t(\"reports.totalLiabilitiesEquity\")}: <span className=\"font-semibold text-gray-900\">{formatCurrency(data.total_liabilities_and_equity)}</span></div>\n </div>\n {isBalanced ? (\n <span className=\"inline-flex items-center rounded-full bg-green-100 px-4 py-1.5 text-sm font-semibold text-green-800\">{t(\"reports.balanced\")}</span>\n ) : (\n <span className=\"inline-flex items-center rounded-full bg-red-100 px-4 py-1.5 text-sm font-semibold text-red-800\">{t(\"reports.imbalanced\")}</span>\n )}\n </div>\n </Card>\n </div>\n )}\n </div>\n );\n}\n","import { useState, useMemo } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { useTranslation } from \"react-i18next\";\nimport { useArAging } from \"@/hooks/use-report\";\nimport { useUrlState, useUrlPatch } from \"@/hooks/use-url-state\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { LinkField } from \"@/components/document/link-field\";\nimport { SingleDatePresets } from \"@/components/ui/date-range-presets\";\nimport { formatCurrency as fmtCurrency } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\n\nexport default function ArAgingPage() {\n const { t } = useTranslation();\n const [urlCompany] = useUrlState<string>(\"company\", \"\");\n const [urlAsOfDate] = useUrlState<string>(\"as_of_date\", \"\");\n const patchUrl = useUrlPatch();\n\n const [company, setCompany] = useState(urlCompany);\n const [asOfDate, setAsOfDate] = useState(urlAsOfDate);\n const baseCurrency = useBaseCurrency(company);\n const formatCurrency = (v: number | null | undefined) => fmtCurrency(v, baseCurrency);\n\n const filters = useMemo(() => {\n const f: Record<string, string> = {};\n if (urlCompany) f.company = urlCompany;\n if (urlAsOfDate) f.as_of_date = urlAsOfDate;\n return f;\n }, [urlCompany, urlAsOfDate]);\n\n const { data, isLoading, refetch } = useArAging(filters);\n\n const handleApply = () => {\n patchUrl({ company: company || null, as_of_date: asOfDate || null });\n refetch();\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <LinkField label={t(\"fields.Company\", { defaultValue: \"Company\" })} value={company} onChange={setCompany} linkDoctype=\"company\" readOnly={false} />\n <Input label={t(\"fields.As of Date\", { defaultValue: \"As of Date\" })} type=\"date\" value={asOfDate} onChange={(e) => setAsOfDate(e.target.value)} />\n <Button onClick={handleApply}>{t(\"common.apply\")}</Button>\n </div>\n <SingleDatePresets onSelect={(date) => {\n setAsOfDate(date);\n patchUrl({ as_of_date: date });\n }} />\n\n {isLoading ? (\n <p className=\"text-gray-500\">{t(\"common.loading\")}</p>\n ) : !data || !data.rows || data.rows.length === 0 ? (\n <p className=\"py-8 text-center text-gray-400\">{t(\"reports.noReceivables\")}</p>\n ) : (\n <Card>\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-3 py-3 text-left font-medium text-gray-500\">{t(\"fields.Invoice\", { defaultValue: \"Invoice\" })}</th>\n <th className=\"px-3 py-3 text-left font-medium text-gray-500\">{t(\"fields.Customer\", { defaultValue: \"Customer\" })}</th>\n <th className=\"px-3 py-3 text-left font-medium text-gray-500\">{t(\"fields.Due Date\", { defaultValue: \"Due Date\" })}</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">{t(\"fields.Outstanding\", { defaultValue: \"Outstanding\" })}</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">{t(\"reports.current\")}</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">1-30</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">31-60</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">61-90</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">90+</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {data.rows.map((row: any, idx: number) => (\n <tr key={idx} className=\"hover:bg-gray-50\">\n <td className=\"px-3 py-2\">\n <Link\n to={`/app/sales-invoice/${encodeURIComponent(row.invoice)}`}\n className=\"font-medium text-blue-600 hover:text-blue-800\"\n >\n {row.invoice}\n </Link>\n </td>\n <td className=\"px-3 py-2 text-gray-900\">{row.customer_name}</td>\n <td className=\"px-3 py-2 text-gray-600\">{row.due_date}</td>\n <td className=\"px-3 py-2 text-right font-medium\">{formatCurrency(row.outstanding)}</td>\n <td className=\"px-3 py-2 text-right\">{row.current ? formatCurrency(row.current) : \"\"}</td>\n <td className=\"px-3 py-2 text-right\">{row.b1_30 ? formatCurrency(row.b1_30) : \"\"}</td>\n <td className=\"px-3 py-2 text-right\">{row.b31_60 ? formatCurrency(row.b31_60) : \"\"}</td>\n <td className=\"px-3 py-2 text-right\">{row.b61_90 ? formatCurrency(row.b61_90) : \"\"}</td>\n <td className=\"px-3 py-2 text-right text-red-600\">{row.b90_plus ? formatCurrency(row.b90_plus) : \"\"}</td>\n </tr>\n ))}\n </tbody>\n <tfoot className=\"border-t-2 border-gray-300 bg-gray-50 font-semibold\">\n <tr>\n <td className=\"px-3 py-3\" colSpan={3}>{t(\"common.total\")}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.outstanding)}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.current)}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.b1_30)}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.b31_60)}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.b61_90)}</td>\n <td className=\"px-3 py-3 text-right text-red-600\">{formatCurrency(data.totals.b90_plus)}</td>\n </tr>\n </tfoot>\n </table>\n </div>\n </Card>\n )}\n </div>\n );\n}\n","import { useState, useMemo } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { useTranslation } from \"react-i18next\";\nimport { useApAging } from \"@/hooks/use-report\";\nimport { useUrlState, useUrlPatch } from \"@/hooks/use-url-state\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { LinkField } from \"@/components/document/link-field\";\nimport { SingleDatePresets } from \"@/components/ui/date-range-presets\";\nimport { formatCurrency as fmtCurrency } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\n\nexport default function ApAgingPage() {\n const { t } = useTranslation();\n const [urlCompany] = useUrlState<string>(\"company\", \"\");\n const [urlAsOfDate] = useUrlState<string>(\"as_of_date\", \"\");\n const patchUrl = useUrlPatch();\n\n const [company, setCompany] = useState(urlCompany);\n const [asOfDate, setAsOfDate] = useState(urlAsOfDate);\n const baseCurrency = useBaseCurrency(company);\n const formatCurrency = (v: number | null | undefined) => fmtCurrency(v, baseCurrency);\n\n const filters = useMemo(() => {\n const f: Record<string, string> = {};\n if (urlCompany) f.company = urlCompany;\n if (urlAsOfDate) f.as_of_date = urlAsOfDate;\n return f;\n }, [urlCompany, urlAsOfDate]);\n\n const { data, isLoading, refetch } = useApAging(filters);\n\n const handleApply = () => {\n patchUrl({ company: company || null, as_of_date: asOfDate || null });\n refetch();\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <LinkField label={t(\"fields.Company\", { defaultValue: \"Company\" })} value={company} onChange={setCompany} linkDoctype=\"company\" readOnly={false} />\n <Input label={t(\"fields.As of Date\", { defaultValue: \"As of Date\" })} type=\"date\" value={asOfDate} onChange={(e) => setAsOfDate(e.target.value)} />\n <Button onClick={handleApply}>{t(\"common.apply\")}</Button>\n </div>\n <SingleDatePresets onSelect={(date) => {\n setAsOfDate(date);\n patchUrl({ as_of_date: date });\n }} />\n\n {isLoading ? (\n <p className=\"text-gray-500\">{t(\"common.loading\")}</p>\n ) : !data || !data.rows || data.rows.length === 0 ? (\n <p className=\"py-8 text-center text-gray-400\">{t(\"reports.noPayables\")}</p>\n ) : (\n <Card>\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-3 py-3 text-left font-medium text-gray-500\">{t(\"fields.Invoice\", { defaultValue: \"Invoice\" })}</th>\n <th className=\"px-3 py-3 text-left font-medium text-gray-500\">{t(\"fields.Supplier\", { defaultValue: \"Supplier\" })}</th>\n <th className=\"px-3 py-3 text-left font-medium text-gray-500\">{t(\"fields.Due Date\", { defaultValue: \"Due Date\" })}</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">{t(\"fields.Outstanding\", { defaultValue: \"Outstanding\" })}</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">{t(\"reports.current\")}</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">1-30</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">31-60</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">61-90</th>\n <th className=\"px-3 py-3 text-right font-medium text-gray-500\">90+</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {data.rows.map((row: any, idx: number) => (\n <tr key={idx} className=\"hover:bg-gray-50\">\n <td className=\"px-3 py-2\">\n <Link\n to={`/app/purchase-invoice/${encodeURIComponent(row.invoice)}`}\n className=\"font-medium text-blue-600 hover:text-blue-800\"\n >\n {row.invoice}\n </Link>\n </td>\n <td className=\"px-3 py-2 text-gray-900\">{row.supplier_name}</td>\n <td className=\"px-3 py-2 text-gray-600\">{row.due_date}</td>\n <td className=\"px-3 py-2 text-right font-medium\">{formatCurrency(row.outstanding)}</td>\n <td className=\"px-3 py-2 text-right\">{row.current ? formatCurrency(row.current) : \"\"}</td>\n <td className=\"px-3 py-2 text-right\">{row.b1_30 ? formatCurrency(row.b1_30) : \"\"}</td>\n <td className=\"px-3 py-2 text-right\">{row.b31_60 ? formatCurrency(row.b31_60) : \"\"}</td>\n <td className=\"px-3 py-2 text-right\">{row.b61_90 ? formatCurrency(row.b61_90) : \"\"}</td>\n <td className=\"px-3 py-2 text-right text-red-600\">{row.b90_plus ? formatCurrency(row.b90_plus) : \"\"}</td>\n </tr>\n ))}\n </tbody>\n <tfoot className=\"border-t-2 border-gray-300 bg-gray-50 font-semibold\">\n <tr>\n <td className=\"px-3 py-3\" colSpan={3}>{t(\"common.total\")}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.outstanding)}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.current)}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.b1_30)}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.b31_60)}</td>\n <td className=\"px-3 py-3 text-right\">{formatCurrency(data.totals.b61_90)}</td>\n <td className=\"px-3 py-3 text-right text-red-600\">{formatCurrency(data.totals.b90_plus)}</td>\n </tr>\n </tfoot>\n </table>\n </div>\n </Card>\n )}\n </div>\n );\n}\n","import { useEffect, useMemo, useRef, useState } from \"react\";\nimport { useNavigate } from \"react-router-dom\";\nimport {\n Bar,\n BarChart,\n CartesianGrid,\n Cell,\n Line,\n LineChart,\n Pie,\n PieChart,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from \"recharts\";\nimport { useUrlState } from \"@/hooks/use-url-state\";\nimport { Card } from \"@/components/ui/card\";\nimport { Button } from \"@/components/ui/button\";\nimport { useChat } from \"@/components/chat/chat-provider\";\n// Inlined (?worker&inline) so the published library bundle carries the worker\n// as an embedded blob rather than an external /assets/*.js reference. A bare\n// `new Worker(new URL(...))` makes Vite emit an absolute /assets URL that a\n// downstream consumer's build resolves against its own public/ dir and fails\n// to find. Inlining keeps the package consumer-buildable.\nimport ReportRuntimeWorker from \"@/workers/report-runtime.worker.ts?worker&inline\";\nimport { flt, formatCurrency, formatDate, formatNumber } from \"@/lib/utils\";\nimport { useBaseCurrency } from \"@/hooks/use-base-currency\";\nimport { api } from \"@/api/client\";\n\ntype RuntimeDatasetResult = {\n name: string;\n dataset: string;\n rows: Array<Record<string, unknown>>;\n fields: Record<string, string>;\n row_count: number;\n truncated: boolean;\n limit: number;\n};\n\ntype RuntimeReportOutput = {\n title?: string;\n summary?: string;\n kpis?: Array<{ label: string; value: number | string; format?: \"currency\" | \"percent\" | \"number\" | \"date\" }>;\n tables?: Array<{\n id?: string;\n title: string;\n columns: Array<{ key: string; label: string; type?: string; format?: string }>;\n rows: Array<Record<string, unknown>>;\n }>;\n charts?: Array<{\n id?: string;\n title: string;\n type: \"bar\" | \"line\" | \"pie\";\n dataTable?: string;\n data?: Array<Record<string, unknown>>;\n x: string;\n y: string;\n }>;\n};\n\ntype RuntimeReportTable = NonNullable<RuntimeReportOutput[\"tables\"]>[number];\n\nfunction buildExampleCustomReport(): string {\n // Rolling 12-month window ending today — no hardcoded company so this works\n // on any tenant's data out of the box.\n const today = new Date();\n const to = today.toISOString().slice(0, 10);\n const start = new Date(today);\n start.setMonth(start.getMonth() - 12);\n const from = start.toISOString().slice(0, 10);\n\n return JSON.stringify(\n {\n title: \"Top Customers by Revenue — Last 12 Months\",\n description: \"Top customers ranked by net sales revenue over the past 12 months.\",\n data_requests: [\n {\n name: \"sales\",\n dataset: \"sales_invoices\",\n fields: [\n \"posting_date\",\n \"customer\",\n \"customer_name\",\n \"net_total\",\n \"is_return\",\n ],\n filters: {\n posting_date: { from, to },\n is_return: 0,\n },\n },\n ],\n transform_js: `const grouped = helpers.group(sales, ['customer', 'customer_name'], {\n revenue: ['sum', 'net_total'],\n invoice_count: ['count', 'net_total'],\n});\nconst sorted = helpers.sortBy(grouped, 'revenue', 'desc');\nconst top = helpers.topN(sorted, 10);\nconst totalRevenue = helpers.sum(grouped, 'revenue');\n\nreturn {\n title: 'Top Customers by Revenue — Last 12 Months',\n kpis: [\n { label: 'Total Revenue', value: totalRevenue, format: 'currency' },\n { label: 'Top 10 Revenue', value: helpers.sum(top, 'revenue'), format: 'currency' },\n { label: 'Customers Shown', value: top.length, format: 'number' },\n ],\n tables: [\n {\n title: 'Top Customers by Revenue',\n columns: [\n { key: 'customer_name', label: 'Customer', type: 'string' },\n { key: 'invoice_count', label: 'Invoices', type: 'number' },\n { key: 'revenue', label: 'Revenue', type: 'currency' },\n ],\n rows: top.map(function(r) { return {\n customer: r.customer,\n customer_name: r.customer_name || r.customer,\n invoice_count: r.invoice_count,\n revenue: r.revenue,\n }; }),\n },\n ],\n charts: [\n {\n title: 'Top Customers by Revenue',\n type: 'bar',\n x: 'customer_name',\n y: 'revenue',\n dataTable: 'Top Customers by Revenue',\n },\n ],\n};`,\n },\n null,\n 2,\n );\n}\n\nconst EXAMPLE_CUSTOM_REPORT = buildExampleCustomReport();\n\nexport default function AnalyticsPage() {\n const navigate = useNavigate();\n const { sessions, createSession } = useChat();\n\n const [reportId] = useUrlState<string>(\"report_id\", \"\");\n const [metric] = useUrlState<string>(\"metric\", \"\");\n const [groupBy] = useUrlState<string>(\"group_by\", \"\");\n const [urlFrom] = useUrlState<string>(\"from\", \"\");\n const [urlTo] = useUrlState<string>(\"to\", \"\");\n const [urlCompany] = useUrlState<string>(\"company\", \"\");\n const [customSpec, setCustomSpec] = useState(EXAMPLE_CUSTOM_REPORT);\n const [runtimeData, setRuntimeData] = useState<RuntimeDatasetResult[]>([]);\n const [runtimeOutput, setRuntimeOutput] = useState<RuntimeReportOutput | null>(null);\n const [runtimeError, setRuntimeError] = useState(\"\");\n const [running, setRunning] = useState(false);\n const [loadingDraft, setLoadingDraft] = useState(false);\n const [sourceChatSessionId, setSourceChatSessionId] = useState(\"\");\n const workerRef = useRef<Worker | null>(null);\n const loadedDraftRef = useRef<string>(\"\");\n const loadedSpecRef = useRef<string>(\"\");\n // Monotonic counter so stale runs (e.g. superseded by a StrictMode\n // double-invoke) can be ignored when their timers or messages fire late.\n const runIdRef = useRef(0);\n\n const legacySpecText = useMemo(() => {\n if (!metric || !groupBy) return \"\";\n return JSON.stringify(buildLegacyRuntimeSpec({\n metric,\n groupBy,\n fromDate: urlFrom || undefined,\n toDate: urlTo || undefined,\n company: urlCompany || undefined,\n }), null, 2);\n }, [metric, groupBy, urlFrom, urlTo, urlCompany]);\n\n const onRunCustom = async (specText?: string) => {\n const runId = ++runIdRef.current;\n const isCurrent = () => runIdRef.current === runId;\n setRuntimeError(\"\");\n setRunning(true);\n try {\n const source = specText ?? customSpec;\n const spec = JSON.parse(source);\n const dataResponse = await api.runtimeData({ requests: spec.data_requests || [] });\n if (!isCurrent()) return;\n setRuntimeData(dataResponse.datasets);\n\n workerRef.current?.terminate();\n const worker = new ReportRuntimeWorker();\n workerRef.current = worker;\n\n const result = await new Promise<RuntimeReportOutput>((resolve, reject) => {\n const timer = window.setTimeout(() => {\n worker.terminate();\n reject(new Error(\"Report runtime exceeded 4 seconds\"));\n }, 4000);\n worker.onmessage = (event) => {\n window.clearTimeout(timer);\n worker.terminate();\n if (workerRef.current === worker) workerRef.current = null;\n if (event.data?.ok) {\n resolve(event.data.output);\n } else {\n reject(new Error(event.data?.error || \"Runtime failed\"));\n }\n };\n worker.postMessage({\n datasets: dataResponse.datasets,\n params: {},\n transformJs: spec.transform_js || \"return {};\",\n });\n });\n\n if (!isCurrent()) return;\n setRuntimeOutput(result);\n } catch (error) {\n if (!isCurrent()) return;\n setRuntimeOutput(null);\n setRuntimeError(error instanceof Error ? error.message : String(error));\n } finally {\n if (isCurrent()) setRunning(false);\n }\n };\n\n useEffect(() => {\n let cancelled = false;\n if (reportId) {\n if (loadedDraftRef.current === reportId) return;\n setLoadingDraft(true);\n setRuntimeError(\"\");\n api.getRuntimeDraft(reportId)\n .then((draft) => {\n if (cancelled) return;\n const nextSpec = JSON.stringify(draft.definition, null, 2);\n loadedDraftRef.current = reportId;\n loadedSpecRef.current = nextSpec;\n setSourceChatSessionId(draft.source_chat_session_id || \"\");\n setCustomSpec(nextSpec);\n return onRunCustom(nextSpec);\n })\n .catch((error) => {\n if (!cancelled) {\n setRuntimeOutput(null);\n setRuntimeError(error instanceof Error ? error.message : String(error));\n }\n })\n .finally(() => {\n if (!cancelled) setLoadingDraft(false);\n });\n return () => {\n cancelled = true;\n };\n }\n\n loadedDraftRef.current = \"\";\n loadedSpecRef.current = \"\";\n setSourceChatSessionId(\"\");\n if (legacySpecText) {\n loadedSpecRef.current = legacySpecText;\n setCustomSpec(legacySpecText);\n void onRunCustom(legacySpecText);\n }\n return () => {\n cancelled = true;\n };\n }, [reportId, legacySpecText]);\n\n const showLegacyBanner = Boolean(!reportId && legacySpecText);\n const renderIssues = useMemo(() => describeRuntimeOutputIssues(runtimeOutput), [runtimeOutput]);\n\n const onFixInChat = async () => {\n const isDirty = customSpec.trim() !== loadedSpecRef.current.trim();\n const reportLabel = reportId || \"unsaved-runtime-report\";\n const preview = runtimeData.map((dataset) => ({\n name: dataset.name,\n dataset: dataset.dataset,\n row_count: dataset.row_count,\n sample_rows: dataset.rows.slice(0, 3),\n }));\n const parts = [\n \"This custom analytics report does not work yet. Please repair the existing report draft instead of creating a new one.\",\n \"\",\n `Report ID: ${reportLabel}`,\n \"\",\n \"Current issue summary:\",\n runtimeError || renderIssues.join(\"\\n\") || \"No runtime error captured; please review and improve the report definition.\",\n ];\n\n if (isDirty) {\n parts.push(\n \"\",\n \"The analytics editor contains unsaved local changes. Use this JSON as the source of truth when repairing the draft:\",\n \"```json\",\n customSpec,\n \"```\",\n );\n } else {\n parts.push(\n \"\",\n \"Load the current saved draft with `get_custom_analytics_report` before making changes.\",\n );\n }\n\n if (preview.length > 0) {\n parts.push(\n \"\",\n \"Fetched dataset preview:\",\n \"```json\",\n JSON.stringify(preview, null, 2),\n \"```\",\n );\n }\n\n const message = parts.join(\"\\n\");\n\n let targetSessionId = sourceChatSessionId;\n if (!targetSessionId) {\n targetSessionId = sessions[0]?.id || \"\";\n }\n if (!targetSessionId) {\n const created = await createSession();\n targetSessionId = created.id;\n }\n navigate(`/chat/${targetSessionId}`, { state: { prefillMessage: message } });\n };\n\n return (\n <div className=\"space-y-4\">\n <Card>\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <div>\n <h2 className=\"text-lg font-semibold text-gray-900\">Analytics</h2>\n <p className=\"text-sm text-gray-600\">\n All analytics now run through the custom runtime and semantic datasets.\n </p>\n </div>\n <div className=\"flex items-center gap-3\">\n {reportId ? (\n <div className=\"text-xs text-gray-500\">Loaded draft: {reportId}</div>\n ) : showLegacyBanner ? (\n <div className=\"text-xs text-gray-500\">Loaded runtime report from legacy URL filters.</div>\n ) : null}\n {reportId ? (\n <Button variant=\"secondary\" onClick={() => void onFixInChat()}>\n Fix In Chat\n </Button>\n ) : null}\n <Button onClick={() => void onRunCustom()} disabled={running}>\n {running ? \"Running...\" : \"Run Report\"}\n </Button>\n </div>\n </div>\n </Card>\n\n {loadingDraft ? (\n <Card>\n <p className=\"text-sm text-gray-600\">Loading draft...</p>\n </Card>\n ) : runtimeError ? (\n <Card>\n <p className=\"text-sm text-red-600\">{runtimeError}</p>\n </Card>\n ) : runtimeOutput ? (\n <RuntimeReportRenderer output={runtimeOutput} />\n ) : (\n <Card>\n <p className=\"text-sm text-gray-600\">\n Edit the runtime JSON below or open a draft from chat, then run the report.\n </p>\n </Card>\n )}\n\n {runtimeData.length > 0 && (\n <Card title=\"Fetched Datasets\">\n <div className=\"space-y-4\">\n {runtimeData.map((dataset) => (\n <div key={dataset.name} className=\"rounded-md border border-gray-200 p-4\">\n <div className=\"flex items-baseline justify-between gap-4\">\n <div>\n <div className=\"font-medium text-gray-900\">{dataset.name}</div>\n <div className=\"text-xs text-gray-500\">{dataset.dataset}</div>\n </div>\n <div className=\"text-xs text-gray-500\">\n {dataset.row_count} rows\n {dataset.truncated ? ` (truncated at ${dataset.limit})` : \"\"}\n </div>\n </div>\n <pre className=\"mt-3 overflow-x-auto rounded bg-gray-50 p-3 text-xs text-gray-700\">\n {JSON.stringify(dataset.rows.slice(0, 5), null, 2)}\n </pre>\n </div>\n ))}\n </div>\n </Card>\n )}\n\n <Card>\n <label className=\"mb-2 block text-sm font-medium text-gray-700\">Report Definition JSON</label>\n <textarea\n className=\"min-h-[520px] w-full rounded-md border border-gray-300 p-3 font-mono text-xs text-gray-900 outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500\"\n value={customSpec}\n onChange={(e) => setCustomSpec(e.target.value)}\n spellCheck={false}\n />\n </Card>\n </div>\n );\n}\n\nfunction RuntimeReportRenderer({ output }: { output: RuntimeReportOutput }) {\n // Custom-report currency values are base-currency numbers; format them with\n // the company currency instead of the util's hardcoded USD default.\n const baseCurrency = useBaseCurrency();\n const tables = (output.tables ?? []).map((table, idx) => ({\n ...table,\n id: table.id || `table_${idx + 1}`,\n }));\n const chartTables = buildChartTableIndex(tables);\n return (\n <div className=\"space-y-4\">\n <Card>\n <div className=\"flex items-baseline justify-between gap-4\">\n <div>\n <h3 className=\"text-lg font-semibold text-gray-900\">{output.title || \"Custom Report\"}</h3>\n {output.summary && <p className=\"mt-1 text-sm text-gray-600\">{output.summary}</p>}\n </div>\n </div>\n {output.kpis?.length ? (\n <div className=\"mt-4 grid gap-4 md:grid-cols-2 xl:grid-cols-4\">\n {output.kpis.map((kpi, idx) => (\n <div key={`${kpi.label}-${idx}`} className=\"rounded-md border border-gray-200 p-4\">\n <div className=\"text-sm text-gray-500\">{kpi.label}</div>\n <div className=\"mt-1 text-2xl font-semibold text-gray-900\">\n {formatRuntimeValue(kpi.value, kpi.format, baseCurrency)}\n </div>\n </div>\n ))}\n </div>\n ) : null}\n </Card>\n\n {output.charts?.map((chart, idx) => {\n const table = chart.dataTable ? chartTables.get(chart.dataTable) : undefined;\n const rows = chart.data ?? table?.rows ?? [];\n if (!rows.length) {\n return (\n <Card key={chart.id || `chart_${idx + 1}`} title={chart.title}>\n <p className=\"text-sm text-red-600\">Chart has no usable data.</p>\n </Card>\n );\n }\n const xLabels = chart.type === \"pie\"\n ? []\n : rows.map((row) => String(row[chart.x] ?? \"\"));\n const layout = computeAxisLayout(xLabels);\n const containerHeight = Math.max(320, 200 + layout.axisHeight);\n return (\n <Card key={chart.id || `chart_${idx + 1}`}>\n <div className=\"pb-3 text-sm font-semibold text-gray-700\">{chart.title}</div>\n <div style={{ height: containerHeight }} className=\"w-full\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n {chart.type === \"line\" ? (\n <LineChart data={rows} margin={{ top: 10, right: 20, left: 0, bottom: 0 }}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"#f3f4f6\" />\n <XAxis\n dataKey={chart.x}\n tick={{ fill: \"#6b7280\", fontSize: 12 }}\n interval={0}\n angle={layout.angle}\n textAnchor={layout.angle === 0 ? \"middle\" : \"end\"}\n height={layout.axisHeight}\n />\n <YAxis tick={{ fill: \"#6b7280\", fontSize: 12 }} tickFormatter={shortNum} />\n <Tooltip formatter={(v) => formatRuntimeValue(v, inferFormat(table, chart.y), baseCurrency)} />\n <Line type=\"monotone\" dataKey={chart.y} stroke=\"#3b82f6\" strokeWidth={2} dot={{ r: 3 }} />\n </LineChart>\n ) : chart.type === \"pie\" ? (\n <PieChart>\n <Tooltip formatter={(v) => formatRuntimeValue(v, inferFormat(table, chart.y), baseCurrency)} />\n <Pie data={rows} dataKey={chart.y} nameKey={chart.x} outerRadius={110}>\n {rows.map((_, rowIdx) => (\n <Cell key={rowIdx} fill={PIE_COLORS[rowIdx % PIE_COLORS.length]} />\n ))}\n </Pie>\n </PieChart>\n ) : (\n <BarChart data={rows} margin={{ top: 10, right: 20, left: 0, bottom: 0 }}>\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"#f3f4f6\" />\n <XAxis\n dataKey={chart.x}\n tick={{ fill: \"#6b7280\", fontSize: 12 }}\n interval={0}\n angle={layout.angle}\n textAnchor={layout.angle === 0 ? \"middle\" : \"end\"}\n height={layout.axisHeight}\n />\n <YAxis tick={{ fill: \"#6b7280\", fontSize: 12 }} tickFormatter={shortNum} />\n <Tooltip formatter={(v) => formatRuntimeValue(v, inferFormat(table, chart.y), baseCurrency)} />\n <Bar dataKey={chart.y} fill=\"#3b82f6\" radius={[4, 4, 0, 0]} />\n </BarChart>\n )}\n </ResponsiveContainer>\n </div>\n </Card>\n );\n })}\n\n {tables.map((table) => (\n <Card key={table.id} title={table.title}>\n <div className=\"overflow-x-auto\">\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n {table.columns.map((column) => (\n <th key={column.key} className=\"px-4 py-2 text-left font-medium text-gray-500\">\n {column.label}\n </th>\n ))}\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {table.rows.map((row, idx) => (\n <tr key={idx} className=\"hover:bg-gray-50\">\n {table.columns.map((column) => (\n <td key={column.key} className=\"px-4 py-1.5 text-gray-900\">\n {formatRuntimeValue(row[column.key], column.type, baseCurrency)}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </Card>\n ))}\n </div>\n );\n}\n\nfunction labelFor(groupBy: string): string {\n return groupBy\n .replace(/_/g, \" \")\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n}\n\nfunction buildChartTableIndex<T extends { id: string; title?: string }>(\n tables: T[],\n): Map<string, T> {\n // Charts can reference a table by either its id or its title. Build a\n // lookup map keyed by both so the specialist model — which naturally\n // reaches for \"<table title>\" — gets a match.\n const map = new Map<string, T>();\n for (const table of tables) {\n map.set(table.id, table);\n if (table.title) map.set(table.title, table);\n }\n return map;\n}\n\nfunction describeRuntimeOutputIssues(output: RuntimeReportOutput | null): string[] {\n if (!output) return [];\n const tables = (output.tables ?? []).map((table, idx) => ({\n ...table,\n id: table.id || `table_${idx + 1}`,\n }));\n const chartTables = buildChartTableIndex(tables);\n const issues: string[] = [];\n\n for (const chart of output.charts ?? []) {\n const table = chart.dataTable ? chartTables.get(chart.dataTable) : undefined;\n const rows = chart.data ?? table?.rows ?? [];\n if (!rows.length) {\n issues.push(`Chart \"${chart.title}\" has no usable data.`);\n continue;\n }\n if (typeof chart.y !== \"string\" || !chart.y) {\n issues.push(`Chart \"${chart.title}\" has an invalid y field; expected a single string field name.`);\n } else if (!rows.some((row) => row[chart.y] != null)) {\n issues.push(`Chart \"${chart.title}\" does not have any values for y=\"${chart.y}\".`);\n }\n if (!chart.x || !rows.some((row) => row[chart.x] != null)) {\n issues.push(`Chart \"${chart.title}\" does not have any values for x=\"${chart.x}\".`);\n }\n if (chart.dataTable && !table) {\n issues.push(`Chart \"${chart.title}\" references missing table \"${chart.dataTable}\".`);\n }\n }\n\n return issues;\n}\n\nfunction buildLegacyRuntimeSpec(args: {\n metric: string;\n groupBy: string;\n fromDate?: string;\n toDate?: string;\n company?: string;\n}) {\n const title = `${legacyMetricLabel(args.metric)} by ${labelFor(args.groupBy)}`;\n const timeBucket = args.groupBy === \"month\" ? \"helpers.monthKey\" : args.groupBy === \"quarter\" ? \"helpers.quarterKey\" : \"helpers.yearKey\";\n\n if (args.metric === \"sales_revenue\") {\n return buildGroupedAmountSpec({\n title,\n dataset: args.groupBy === \"item\" ? \"sales_invoice_lines\" : \"sales_invoices\",\n requestName: \"rows\",\n keyField: args.groupBy === \"item\" ? \"item_code\" : args.groupBy === \"customer\" ? \"customer\" : \"posting_date\",\n valueField: args.groupBy === \"item\" ? \"net_amount\" : \"grand_total\",\n groupBy: args.groupBy,\n timeBucket,\n filters: {\n company: args.company,\n posting_date: args.fromDate || args.toDate ? { from: args.fromDate, to: args.toDate } : undefined,\n is_return: 0,\n },\n fields: args.groupBy === \"item\"\n ? [\"posting_date\", \"item_code\", \"net_amount\"]\n : [\"posting_date\", \"customer\", \"grand_total\"],\n chartType: args.groupBy === \"customer\" || args.groupBy === \"item\" ? \"bar\" : \"line\",\n });\n }\n\n if (args.metric === \"sales_returns\") {\n return buildGroupedAmountSpec({\n title,\n dataset: \"sales_invoices\",\n requestName: \"rows\",\n keyField: args.groupBy === \"customer\" ? \"customer\" : \"posting_date\",\n valueField: \"grand_total\",\n groupBy: args.groupBy,\n timeBucket,\n filters: {\n company: args.company,\n posting_date: args.fromDate || args.toDate ? { from: args.fromDate, to: args.toDate } : undefined,\n is_return: 1,\n },\n fields: [\"posting_date\", \"customer\", \"grand_total\"],\n chartType: args.groupBy === \"customer\" ? \"bar\" : \"line\",\n });\n }\n\n if (args.metric === \"purchases\") {\n return buildGroupedAmountSpec({\n title,\n dataset: args.groupBy === \"item\" ? \"purchase_invoice_lines\" : \"purchase_invoices\",\n requestName: \"rows\",\n keyField: args.groupBy === \"item\" ? \"item_code\" : args.groupBy === \"supplier\" ? \"supplier\" : \"posting_date\",\n valueField: args.groupBy === \"item\" ? \"net_amount\" : \"grand_total\",\n groupBy: args.groupBy,\n timeBucket,\n filters: {\n company: args.company,\n posting_date: args.fromDate || args.toDate ? { from: args.fromDate, to: args.toDate } : undefined,\n is_return: 0,\n },\n fields: args.groupBy === \"item\"\n ? [\"posting_date\", \"item_code\", \"net_amount\"]\n : [\"posting_date\", \"supplier\", \"grand_total\"],\n chartType: args.groupBy === \"supplier\" || args.groupBy === \"item\" ? \"bar\" : \"line\",\n });\n }\n\n if (args.metric === \"payments_received\" || args.metric === \"payments_made\") {\n const isReceived = args.metric === \"payments_received\";\n return buildGroupedAmountSpec({\n title,\n dataset: \"payments\",\n requestName: \"rows\",\n keyField: args.groupBy === (isReceived ? \"customer\" : \"supplier\") ? \"party\" : \"posting_date\",\n valueField: isReceived ? \"received_amount\" : \"paid_amount\",\n groupBy: args.groupBy,\n timeBucket,\n filters: {\n company: args.company,\n posting_date: args.fromDate || args.toDate ? { from: args.fromDate, to: args.toDate } : undefined,\n payment_type: isReceived ? \"Receive\" : \"Pay\",\n party_type: isReceived ? \"Customer\" : \"Supplier\",\n },\n fields: [\"posting_date\", \"party\", isReceived ? \"received_amount\" : \"paid_amount\"],\n chartType: args.groupBy === (isReceived ? \"customer\" : \"supplier\") ? \"bar\" : \"line\",\n });\n }\n\n if (args.metric === \"outstanding_ar\" || args.metric === \"outstanding_ap\") {\n const isAr = args.metric === \"outstanding_ar\";\n const dataset = isAr ? \"ar_open_items\" : \"ap_open_items\";\n const partyField = isAr ? \"customer\" : \"supplier\";\n const amountField = \"outstanding_amount\";\n return buildGroupedAmountSpec({\n title,\n dataset,\n requestName: \"rows\",\n keyField: partyField,\n valueField: amountField,\n groupBy: partyField,\n timeBucket,\n filters: {\n company: args.company,\n posting_date: args.fromDate || args.toDate ? { from: args.fromDate, to: args.toDate } : undefined,\n },\n fields: [\"posting_date\", partyField, amountField],\n chartType: \"bar\",\n });\n }\n\n if (args.metric === \"stock_value\") {\n return buildGroupedAmountSpec({\n title,\n dataset: \"stock_balances\",\n requestName: \"rows\",\n keyField: args.groupBy === \"warehouse\" ? \"warehouse\" : \"item_code\",\n valueField: \"stock_value\",\n groupBy: args.groupBy,\n timeBucket,\n filters: {\n company: args.company,\n },\n fields: [args.groupBy === \"warehouse\" ? \"warehouse\" : \"item_code\", \"stock_value\"],\n chartType: \"bar\",\n });\n }\n\n return JSON.parse(EXAMPLE_CUSTOM_REPORT);\n}\n\nfunction buildGroupedAmountSpec(args: {\n title: string;\n dataset: string;\n requestName: string;\n keyField: string;\n valueField: string;\n groupBy: string;\n timeBucket: string;\n filters: Record<string, unknown>;\n fields: string[];\n chartType: \"bar\" | \"line\";\n}) {\n const filters = Object.fromEntries(Object.entries(args.filters).filter(([, value]) => value !== undefined));\n const bucketExpr = [\"month\", \"quarter\", \"year\"].includes(args.groupBy)\n ? `${args.timeBucket}(row.${args.keyField})`\n : `row.${args.keyField} || \"—\"`;\n return {\n title: args.title,\n data_requests: [\n {\n name: args.requestName,\n dataset: args.dataset,\n fields: args.fields,\n filters,\n limit: 5000,\n },\n ],\n transform_js: `const grouped = helpers.group(\n datasets.${args.requestName}.map((row) => ({\n bucket: ${bucketExpr},\n amount: helpers.flt(row.${args.valueField}),\n })),\n [\"bucket\"],\n { value: [\"sum\", \"amount\"] },\n);\n\nconst ordered = helpers.sortBy(grouped, ${[\"month\", \"quarter\", \"year\"].includes(args.groupBy) ? `\"bucket\", \"asc\"` : `\"value\", \"desc\"`});\n\nreturn {\n title: ${JSON.stringify(args.title)},\n kpis: [\n { label: \"Rows\", value: ordered.length, format: \"number\" },\n { label: \"Total\", value: helpers.sum(ordered, \"value\"), format: \"currency\" }\n ],\n tables: [\n {\n id: \"main\",\n title: ${JSON.stringify(args.title)},\n columns: [\n { key: \"bucket\", label: \"Bucket\", type: \"string\" },\n { key: \"value\", label: \"Value\", type: \"currency\" }\n ],\n rows: ordered\n }\n ],\n charts: [\n {\n id: \"main_chart\",\n title: ${JSON.stringify(args.title)},\n type: ${JSON.stringify(args.chartType)},\n dataTable: \"main\",\n x: \"bucket\",\n y: \"value\"\n }\n ]\n};`,\n };\n}\n\nfunction legacyMetricLabel(metric: string) {\n const labels: Record<string, string> = {\n sales_revenue: \"Sales Revenue\",\n sales_returns: \"Sales Returns\",\n purchases: \"Purchases\",\n payments_received: \"Payments Received\",\n payments_made: \"Payments Made\",\n outstanding_ar: \"Outstanding AR\",\n outstanding_ap: \"Outstanding AP\",\n stock_value: \"Stock Value\",\n };\n return labels[metric] || \"Analytics\";\n}\n\nfunction inferFormat(table: RuntimeReportTable | undefined, key: string) {\n return table?.columns.find((column) => column.key === key)?.type || table?.columns.find((column) => column.key === key)?.format;\n}\n\nfunction formatRuntimeValue(value: unknown, type?: string, currency?: string) {\n if (type === \"currency\") return formatCurrency(flt(value), currency);\n if (type === \"percent\") return `${(flt(value) * 100).toFixed(1)}%`;\n if (type === \"number\") return formatNumber(flt(value));\n if (type === \"date\") return formatDate(String(value ?? \"\"));\n if (typeof value === \"number\") return formatNumber(value);\n return String(value ?? \"\");\n}\n\nfunction shortNum(n: number): string {\n const abs = Math.abs(n);\n if (abs >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (abs >= 1_000) return `${(n / 1_000).toFixed(0)}k`;\n return String(n);\n}\n\nconst PIE_COLORS = [\"#3b82f6\", \"#10b981\", \"#f59e0b\", \"#ef4444\", \"#8b5cf6\", \"#06b6d4\"];\n\n// -----------------------------------------------------------------------------\n// X-axis auto-fit\n//\n// Use Canvas 2d's measureText to get the actual rendered pixel width of each\n// tick label at the same font used by recharts ticks. From there we pick an\n// angle and axis height that accommodates the longest label without the\n// letters getting clipped against the card edge.\n// -----------------------------------------------------------------------------\n\nconst AXIS_TICK_FONT = '12px -apple-system, system-ui, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif';\n\nlet _measureCanvas: HTMLCanvasElement | null = null;\nfunction measureTextWidth(text: string, font: string = AXIS_TICK_FONT): number {\n if (typeof document === \"undefined\") return text.length * 7;\n if (!_measureCanvas) _measureCanvas = document.createElement(\"canvas\");\n const ctx = _measureCanvas.getContext(\"2d\");\n if (!ctx) return text.length * 7;\n ctx.font = font;\n return ctx.measureText(text).width;\n}\n\nfunction computeAxisLayout(labels: string[]): { angle: number; axisHeight: number; maxWidth: number } {\n if (!labels.length) return { angle: 0, axisHeight: 30, maxWidth: 0 };\n const widths = labels.map((label) => measureTextWidth(label));\n const maxWidth = Math.max(1, ...widths);\n let angle = 0;\n if (maxWidth > 55) angle = -30;\n if (maxWidth > 110) angle = -45;\n if (maxWidth > 200) angle = -60;\n if (maxWidth > 300) angle = -90;\n const radians = (Math.abs(angle) * Math.PI) / 180;\n const projected =\n angle === 0 ? 20 : Math.abs(angle) === 90 ? maxWidth : Math.ceil(maxWidth * Math.sin(radians));\n // Pad by ~18px for tick marks, font descenders, and a little breathing room.\n const axisHeight = Math.min(280, Math.max(30, projected + 18));\n return { angle, axisHeight, maxWidth };\n}\n","import { useState } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { api } from \"@/api/client\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Select } from \"@/components/ui/select\";\nimport { Button } from \"@/components/ui/button\";\n\nconst CURRENCY_OPTIONS = [\"USD\", \"EUR\", \"GBP\", \"CHF\", \"JPY\", \"CAD\", \"AUD\", \"CNY\", \"INR\"];\n\ntype SeedMode = \"none\" | \"quick\" | \"history\";\n\nexport default function SetupPage() {\n const queryClient = useQueryClient();\n\n const { data: status, isLoading } = useQuery({\n queryKey: [\"setup-status\"],\n queryFn: () => api.setupStatus(),\n });\n\n const [companyName, setCompanyName] = useState(\"\");\n const [currency, setCurrency] = useState(\"USD\");\n const [details, setDetails] = useState({\n address: \"\",\n city: \"\",\n zip_code: \"\",\n country: \"\",\n email: \"\",\n phone: \"\",\n tax_id: \"\",\n });\n const setDetail = (key: keyof typeof details) => (e: { target: { value: string } }) =>\n setDetails((d) => ({ ...d, [key]: e.target.value }));\n const [seedMode, setSeedMode] = useState<SeedMode>(\"quick\");\n const [success, setSuccess] = useState(false);\n const [historyStats, setHistoryStats] = useState<Record<string, number> | null>(null);\n\n const createCompanyMut = useMutation({\n mutationFn: () => api.createCompany({ name: companyName, currency, ...details }),\n });\n\n const seedDemoMut = useMutation({\n mutationFn: () => api.seedDemo(),\n });\n\n const seedHistoryMut = useMutation({\n mutationFn: () => api.seedHistory(),\n });\n\n const handleSetup = async () => {\n if (!companyName.trim()) return;\n try {\n await createCompanyMut.mutateAsync();\n if (seedMode === \"history\") {\n const res = await seedHistoryMut.mutateAsync();\n setHistoryStats(res.stats);\n } else if (seedMode === \"quick\") {\n await seedDemoMut.mutateAsync();\n }\n // seedMode === \"none\": create the company only, seed nothing.\n queryClient.invalidateQueries({ queryKey: [\"setup-status\"] });\n setSuccess(true);\n } catch {\n // errors handled by mutation state\n }\n };\n\n if (isLoading) {\n return <p className=\"text-gray-500\">Loading...</p>;\n }\n\n // Setup already complete -- show existing companies\n if (status?.setup_complete && !success) {\n return (\n <div className=\"space-y-6\">\n <Card title=\"Companies\">\n {status.companies && status.companies.length > 0 ? (\n <ul className=\"divide-y divide-gray-100\">\n {status.companies.map((company: any, idx: number) => (\n <li key={idx} className=\"py-3\">\n <CompanyRow company={company} />\n </li>\n ))}\n </ul>\n ) : (\n <p className=\"text-gray-400\">No companies found</p>\n )}\n </Card>\n <Link to=\"/\" className=\"text-blue-600 hover:text-blue-800 text-sm font-medium\">\n Go to Dashboard\n </Link>\n </div>\n );\n }\n\n // Success state after setup\n if (success) {\n return (\n <div className=\"space-y-6\">\n <Card>\n <div className=\"py-8 text-center\">\n <p className=\"text-lg font-semibold text-green-700\">\n Setup complete!\n </p>\n <p className=\"mt-2 text-sm text-gray-500\">\n {seedMode === \"history\"\n ? \"Your company has been created and three years of history has been simulated.\"\n : seedMode === \"quick\"\n ? \"Your company has been created and demo data has been seeded.\"\n : \"Your company has been created. No demo data was added.\"}\n </p>\n {historyStats && (\n <div className=\"mx-auto mt-6 max-w-sm text-left\">\n <p className=\"mb-2 text-sm font-medium text-gray-700\">Generated documents:</p>\n <ul className=\"divide-y divide-gray-100 text-sm\">\n {Object.entries(historyStats)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([k, v]) => (\n <li key={k} className=\"flex justify-between py-1\">\n <span className=\"text-gray-600\">{k.replace(/_/g, \" \")}</span>\n <span className=\"font-mono text-gray-900\">{v.toLocaleString()}</span>\n </li>\n ))}\n </ul>\n </div>\n )}\n <div className=\"mt-6\">\n <Link to=\"/\">\n <Button>Go to Dashboard</Button>\n </Link>\n </div>\n </div>\n </Card>\n </div>\n );\n }\n\n // First-run setup form\n const isPending =\n createCompanyMut.isPending || seedDemoMut.isPending || seedHistoryMut.isPending;\n const error = createCompanyMut.error ?? seedDemoMut.error ?? seedHistoryMut.error;\n\n return (\n <div className=\"mx-auto max-w-lg space-y-6\">\n <p className=\"text-sm text-gray-500\">\n Set up your first company to get started.\n </p>\n\n {error && (\n <div className=\"rounded-md bg-red-50 p-4 text-sm text-red-700\">\n {error.message ?? \"An error occurred during setup\"}\n </div>\n )}\n\n <Card>\n <div className=\"space-y-4\">\n <Input\n label=\"Company Name\"\n value={companyName}\n onChange={(e) => setCompanyName(e.target.value)}\n placeholder=\"e.g. My Company Ltd\"\n required\n />\n <Select\n label=\"Currency\"\n options={CURRENCY_OPTIONS}\n value={currency}\n onChange={(e) => setCurrency(e.target.value)}\n />\n\n <fieldset className=\"space-y-3\">\n <legend className=\"mb-1 text-sm font-medium text-gray-700\">\n Company details\n </legend>\n <p className=\"text-xs text-gray-500\">\n These appear on your invoices and other PDFs. Optional now — you can\n fill or change them later under Masters → Company.\n </p>\n <Input label=\"Address\" value={details.address} onChange={setDetail(\"address\")}\n placeholder=\"e.g. 42 Market Street\" />\n <div className=\"grid grid-cols-2 gap-3\">\n <Input label=\"City\" value={details.city} onChange={setDetail(\"city\")} />\n <Input label=\"ZIP / Postal code\" value={details.zip_code} onChange={setDetail(\"zip_code\")} />\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <Input label=\"Country\" value={details.country} onChange={setDetail(\"country\")} />\n <Input label=\"Tax ID / VAT\" value={details.tax_id} onChange={setDetail(\"tax_id\")} />\n </div>\n <div className=\"grid grid-cols-2 gap-3\">\n <Input label=\"Email\" value={details.email} onChange={setDetail(\"email\")} />\n <Input label=\"Phone\" value={details.phone} onChange={setDetail(\"phone\")} />\n </div>\n </fieldset>\n\n <fieldset className=\"space-y-2\">\n <legend className=\"mb-1 text-sm font-medium text-gray-700\">\n Seed data\n </legend>\n <label className=\"flex cursor-pointer items-start gap-3 rounded-md border border-gray-200 p-3 hover:bg-gray-50\">\n <input\n type=\"radio\"\n name=\"seed-mode\"\n value=\"quick\"\n checked={seedMode === \"quick\"}\n onChange={() => setSeedMode(\"quick\")}\n className=\"mt-1\"\n />\n <div>\n <div className=\"text-sm font-medium text-gray-900\">Quick demo</div>\n <div className=\"text-xs text-gray-500\">\n Customers, suppliers, items, one warehouse. No transactions.\n </div>\n </div>\n </label>\n <label className=\"flex cursor-pointer items-start gap-3 rounded-md border border-gray-200 p-3 hover:bg-gray-50\">\n <input\n type=\"radio\"\n name=\"seed-mode\"\n value=\"history\"\n checked={seedMode === \"history\"}\n onChange={() => setSeedMode(\"history\")}\n className=\"mt-1\"\n />\n <div>\n <div className=\"text-sm font-medium text-gray-900\">\n Simulate 3 years of history\n </div>\n <div className=\"text-xs text-gray-500\">\n Walks business days (skips weekends + US holidays) and generates\n quotations, orders, deliveries, invoices, payments, and\n reorder-driven purchasing. Seasonality + YoY growth baked in.\n Takes ~3 minutes.\n </div>\n </div>\n </label>\n <label className=\"flex cursor-pointer items-start gap-3 rounded-md border border-gray-200 p-3 hover:bg-gray-50\">\n <input\n type=\"radio\"\n name=\"seed-mode\"\n value=\"none\"\n checked={seedMode === \"none\"}\n onChange={() => setSeedMode(\"none\")}\n className=\"mt-1\"\n />\n <div>\n <div className=\"text-sm font-medium text-gray-900\">\n Create empty company, no demo data\n </div>\n <div className=\"text-xs text-gray-500\">\n Just the company and its chart of accounts. Add your own\n customers, suppliers, items, and transactions from scratch.\n </div>\n </div>\n </label>\n </fieldset>\n\n <div className=\"pt-2\">\n <Button\n onClick={handleSetup}\n disabled={isPending || !companyName.trim()}\n >\n {isPending\n ? seedMode === \"history\"\n ? \"Simulating three years...\"\n : \"Setting up...\"\n : seedMode === \"history\"\n ? \"Create Company & Simulate History\"\n : seedMode === \"quick\"\n ? \"Create Company & Seed Demo Data\"\n : \"Create Company\"}\n </Button>\n </div>\n </div>\n </Card>\n </div>\n );\n}\n\nfunction CompanyRow({ company }: { company: Record<string, any> }) {\n const cityCountry = [\n [company.city, company.zip_code].filter(Boolean).join(\" \"),\n company.country,\n ].filter(Boolean).join(\", \");\n return (\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0 space-y-1\">\n <div className=\"font-medium text-gray-900\">\n {company.company_name || company.name}\n </div>\n <dl className=\"grid grid-cols-[auto,1fr] gap-x-3 gap-y-0.5 text-xs text-gray-500\">\n {company.address && (\n <>\n <dt className=\"text-gray-400\">Address</dt>\n <dd className=\"text-gray-700\">{company.address}</dd>\n </>\n )}\n {cityCountry && (\n <>\n <dt className=\"text-gray-400\">Location</dt>\n <dd className=\"text-gray-700\">{cityCountry}</dd>\n </>\n )}\n {company.email && (\n <>\n <dt className=\"text-gray-400\">Email</dt>\n <dd className=\"truncate text-gray-700\">\n <a\n href={`mailto:${company.email}`}\n className=\"text-blue-600 hover:text-blue-800\"\n >\n {company.email}\n </a>\n </dd>\n </>\n )}\n {company.phone && (\n <>\n <dt className=\"text-gray-400\">Phone</dt>\n <dd className=\"text-gray-700\">{company.phone}</dd>\n </>\n )}\n {company.tax_id && (\n <>\n <dt className=\"text-gray-400\">Tax ID</dt>\n <dd className=\"font-mono text-gray-700\">{company.tax_id}</dd>\n </>\n )}\n </dl>\n </div>\n {company.default_currency && (\n <span className=\"shrink-0 rounded-full bg-gray-100 px-2 py-0.5 text-xs font-medium text-gray-600\">\n {company.default_currency}\n </span>\n )}\n </div>\n );\n}\n","import { Link, useNavigate } from \"react-router-dom\";\nimport { useTranslation } from \"react-i18next\";\nimport { Card } from \"@/components/ui/card\";\nimport { useChat } from \"@/components/chat/chat-provider\";\n\ninterface StepLink {\n to: string;\n label: string;\n}\n\ninterface Step {\n number: number;\n title: string;\n description: string;\n tip?: string;\n link?: string;\n linkLabel?: string;\n links?: StepLink[];\n}\n\nconst STEPS: Step[] = [\n {\n number: 1,\n title: \"Set Up Your Company\",\n description:\n \"Create a company with a base currency. This generates your Chart of Accounts (30 standard accounts across Assets, Liabilities, Equity, Income, and Expenses) and a default Cost Center. You can also seed demo data with sample customers, suppliers, and items to get started quickly.\",\n link: \"/setup\",\n linkLabel: \"Go to Setup\",\n },\n {\n number: 2,\n title: \"Create Master Data\",\n description:\n \"Before you can transact, you need master records. Create at least one Customer, one Supplier, one Item (with a standard rate), and one Warehouse. If you seeded demo data in Step 1, these already exist.\",\n tip: \"Items have a standard rate that auto-fills when you add them to documents. You can always override the rate per transaction.\",\n links: [\n { to: \"/masters/customer\", label: \"Customers\" },\n { to: \"/masters/supplier\", label: \"Suppliers\" },\n { to: \"/masters/item\", label: \"Items\" },\n { to: \"/masters/warehouse\", label: \"Warehouses\" },\n ],\n },\n {\n number: 3,\n title: \"Create a Quotation\",\n description:\n \"A Quotation is a non-binding offer to a customer. Select a customer, add line items with quantities and rates, optionally add tax rows, then save. Quotations have no financial impact \\u2014 they don't create accounting or stock entries. Set a validity date so the offer expires automatically.\",\n link: \"/app/quotation/new\",\n linkLabel: \"New Quotation\",\n },\n {\n number: 4,\n title: \"Submit and Convert to Sales Order\",\n description:\n \"Open your saved Quotation and click Submit to confirm it. Then click \\u201cCreate Sales Order\\u201d to convert it. The Sales Order represents a confirmed commitment from the customer. It still has no financial impact, but it reserves stock for planning purposes.\",\n tip: \"Only submitted documents can be converted to the next step. Draft \\u2192 Submit \\u2192 Convert is the standard flow. For quick deals, you can skip the Sales Order and go directly from Quotation to Sales Invoice or Delivery Note.\",\n link: \"/app/quotation\",\n linkLabel: \"View Quotations\",\n },\n {\n number: 5,\n title: \"Check Stock Before Fulfilling\",\n description:\n \"Before you can deliver, check if you actually have the item in stock. Go to the Stock Balance report and look up the item. If your warehouse has zero quantity, you\\u2019ll need to bring stock in first \\u2014 either through a Purchase Order (buying from a supplier) or a Stock Entry (manual receipt).\",\n tip: \"This is a common real-world scenario: you sell something, then realize you need to buy it first. The ERP handles both flows.\",\n link: \"/reports/stock-balance\",\n linkLabel: \"Stock Balance\",\n },\n {\n number: 6,\n title: \"Purchase Cycle: Buy Stock from a Supplier\",\n description:\n \"If you need to buy stock, you have two valid paths. The standard path is Purchase Order -> Purchase Receipt -> Purchase Invoice: use this when goods arrive before or separately from the supplier bill. If the bill and receipt happen together, you can create the Purchase Invoice directly and enable Update Stock so the same document both receives inventory and records Accounts Payable.\",\n tip: \"Use Purchase Receipt first when receiving goods separately. Use Purchase Invoice with Update Stock when one step should both receive stock and book the supplier bill. In that direct path, set a warehouse on each stock item row.\",\n links: [\n { to: \"/app/purchase-order/new\", label: \"New Purchase Order\" },\n { to: \"/app/purchase-receipt\", label: \"Purchase Receipts\" },\n { to: \"/app/purchase-invoice\", label: \"Purchase Invoices\" },\n ],\n },\n {\n number: 7,\n title: \"Create a Delivery Note\",\n description:\n \"Now that you have stock, go back to your submitted Sales Order and click \\u201cCreate Delivery Note.\\u201d Set the warehouse on each item row (where the goods ship from), then submit. This moves inventory out of the warehouse \\u2014 your stock balance decreases.\",\n tip: \"The Delivery Note is the shipping document. It reduces stock but doesn\\u2019t create an invoice. You can deliver and invoice separately.\",\n link: \"/app/delivery-note\",\n linkLabel: \"Delivery Notes\",\n },\n {\n number: 8,\n title: \"Create and Submit the Sales Invoice\",\n description:\n \"From the submitted Sales Order, create a Sales Invoice. When you submit the invoice, GL entries are posted: Accounts Receivable is debited (the customer owes you) and Sales Revenue is credited (income earned). If taxes are configured, Tax Payable is also credited. The outstanding amount shows what the customer still owes.\",\n link: \"/app/sales-invoice\",\n linkLabel: \"Sales Invoices\",\n },\n {\n number: 9,\n title: \"Record Customer Payments\",\n description:\n \"Create a Payment Entry to record money received from the customer. Set the payment type to \\u201cReceive,\\u201d select the customer, specify the amount, and allocate it against the Sales Invoice. You can make partial payments \\u2014 the invoice\\u2019s outstanding amount updates accordingly. Create additional Payment Entries until the invoice is fully paid.\",\n tip: \"Partial payments are common. A 10,000 invoice might be paid as 3,000 now and 7,000 later. Each Payment Entry reduces the outstanding amount.\",\n link: \"/app/payment-entry/new\",\n linkLabel: \"New Payment Entry\",\n },\n {\n number: 10,\n title: \"Stock Entries (Manual Inventory)\",\n description:\n \"Use Stock Entries for inventory movements that aren\\u2019t tied to purchases or sales. Material Receipt adds stock (opening balances, adjustments). Material Issue removes stock (write-offs, internal consumption). Material Transfer moves stock between warehouses. Each entry updates the stock ledger with moving-average valuation.\",\n tip: \"For purchased goods, use Purchase Receipts instead of Stock Entries \\u2014 they link to the Purchase Order and give you a proper audit trail.\",\n link: \"/app/stock-entry/new\",\n linkLabel: \"New Stock Entry\",\n },\n {\n number: 11,\n title: \"Journal Entries\",\n description:\n \"Journal Entries are manual accounting adjustments \\u2014 expense accruals, corrections, reclassifications, opening balances. Each entry must have balanced debits and credits (total debit = total credit). Use these when no other document type fits.\",\n link: \"/app/journal-entry/new\",\n linkLabel: \"New Journal Entry\",\n },\n {\n number: 12,\n title: \"Salary Payments\",\n description:\n \"Lambda ERP handles salaries through the existing accounting tools. First, accrue the salary expense: create a Journal Entry that debits Salary Expense and credits Salary Payable for the total payroll amount. Then pay the employees: create another Journal Entry (or Payment Entry) that debits Salary Payable and credits your bank account. This two-step process keeps your books accurate \\u2014 the expense is recorded in the right period, and the cash outflow is tracked separately.\",\n tip: \"You can ask the AI assistant to do this for you: \\u201cAccrue 15,000 in salaries for April\\u201d followed by \\u201cPay the April salaries from bank.\\u201d It will create the right journal entries automatically.\",\n link: \"/app/journal-entry/new\",\n linkLabel: \"New Journal Entry\",\n },\n {\n number: 13,\n title: \"Returns and Credit Notes\",\n description:\n \"When a customer returns goods or you need to issue a credit, create a return. Returns use the same document type with negative quantities. Open a submitted Sales Invoice and create a Credit Note (Sales Invoice return) \\u2014 this reverses the GL entries and reduces the original invoice\\u2019s outstanding amount. For stock, create a Delivery Note return to bring goods back into the warehouse. On the buying side, create a Debit Note (Purchase Invoice return) to reverse a supplier bill, or a Purchase Receipt return to send goods back.\",\n tip: \"A Credit Note is just a Sales Invoice with is_return=1 and negative quantities. The same GL logic runs \\u2014 negative amounts automatically flip to the correct debit/credit sides. For a full sales return, you need both a Credit Note (financials) and a Delivery Note return (stock).\",\n links: [\n { to: \"/app/sales-invoice\", label: \"Sales Invoices\" },\n { to: \"/app/delivery-note\", label: \"Delivery Notes\" },\n { to: \"/app/purchase-invoice\", label: \"Purchase Invoices\" },\n ],\n },\n {\n number: 14,\n title: \"Run Reports\",\n description:\n \"Check your books. The Profit & Loss shows income vs expenses and net profit for a period. The Balance Sheet shows your financial position (assets = liabilities + equity). AR Aging shows who owes you money and how overdue it is. AP Aging shows what you owe suppliers. The Trial Balance verifies double-entry integrity. The General Ledger shows every individual posting. Stock Balance shows current inventory.\",\n links: [\n { to: \"/reports/profit-and-loss\", label: \"Profit & Loss\" },\n { to: \"/reports/balance-sheet\", label: \"Balance Sheet\" },\n { to: \"/reports/ar-aging\", label: \"AR Aging\" },\n { to: \"/reports/ap-aging\", label: \"AP Aging\" },\n { to: \"/reports/trial-balance\", label: \"Trial Balance\" },\n { to: \"/reports/general-ledger\", label: \"General Ledger\" },\n { to: \"/reports/stock-balance\", label: \"Stock Balance\" },\n ],\n },\n {\n number: 15,\n title: \"Working in Foreign Currencies\",\n description:\n \"Your books are kept in a single base currency (chosen at company setup), but you can transact in any currency. Set a currency on an invoice or bill — or give a customer or supplier a default currency — and the exchange rate for that date is looked up automatically and stored on the document. The document keeps its amounts in its own currency, while the General Ledger always posts in your base currency. When you later collect or pay at a different rate, the realized exchange gain or loss is booked automatically to an Exchange Gain/Loss account. You can even hold a foreign-currency bank balance and convert it later at your bank’s rate — the difference versus its carried value is realized then. At month end you can revalue open foreign balances to the closing rate (an unrealized gain/loss that reverses next period), and you can view any financial statement translated into another currency for display.\",\n tip: \"This is easiest through the AI chat — try “Create a sales invoice for Lumiere Audio in EUR,” “Show me the balance sheet in EUR,” or “What’s our unrealized FX exposure at month end?” The seeded demo already includes a EUR customer (Lumiere Audio SARL) whose invoice was collected at a different rate, plus an open EUR supplier bill — open the General Ledger to see the realized FX postings.\",\n links: [\n { to: \"/chat\", label: \"Open AI Chat\" },\n { to: \"/app/sales-invoice\", label: \"Sales Invoices\" },\n { to: \"/reports/general-ledger\", label: \"General Ledger\" },\n ],\n },\n];\n\n// Launch the chat with a prefilled message (reuses an existing session or\n// creates one), mirroring the analytics \"try in chat\" flow.\nfunction useTryInChat() {\n const navigate = useNavigate();\n const { sessions, createSession } = useChat();\n return async (prefill: string) => {\n let targetSessionId = sessions[0]?.id || \"\";\n if (!targetSessionId) {\n try {\n const created = await createSession();\n targetSessionId = created.id;\n } catch {\n navigate(\"/chat\");\n return;\n }\n }\n navigate(`/chat/${targetSessionId}`, { state: { prefillMessage: prefill } });\n };\n}\n\nfunction CompanySetupHighlight() {\n const { t } = useTranslation();\n const tryInChat = useTryInChat();\n\n return (\n <Card className=\"border-emerald-200 bg-gradient-to-br from-emerald-50 to-white\">\n <div className=\"flex flex-col gap-4 md:flex-row md:items-start\">\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-emerald-100 text-lg font-bold text-emerald-700\">\n ▶\n </div>\n <div className=\"flex-1 space-y-3\">\n <div>\n <p className=\"text-xs uppercase tracking-wider text-emerald-700\">\n {t(\"tutorial.setupBadge\")}\n </p>\n <h3 className=\"mt-0.5 text-lg font-semibold text-gray-900\">\n {t(\"tutorial.setupTitle\")}\n </h3>\n </div>\n <p className=\"text-sm leading-relaxed text-gray-700\">\n {t(\"tutorial.setupBody\")}\n </p>\n <p className=\"text-xs leading-relaxed text-gray-500\">\n {t(\"tutorial.setupSectors\")}\n </p>\n <div className=\"flex flex-wrap items-center gap-4 pt-1\">\n <button\n type=\"button\"\n onClick={() => tryInChat(t(\"tutorial.setupPrompt\"))}\n className=\"inline-flex items-center gap-2 rounded-lg bg-emerald-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-emerald-700\"\n >\n {t(\"tutorial.setupGetStarted\")} →\n </button>\n <span className=\"text-xs text-gray-500\">\n {t(\"tutorial.setupManual\")}{\" \"}\n <Link to=\"/setup\" className=\"font-medium text-emerald-700 hover:text-emerald-900\">\n {t(\"tutorial.setupManualLink\")} →\n </Link>\n </span>\n </div>\n </div>\n </div>\n </Card>\n );\n}\n\nfunction CustomAnalyticsHighlight() {\n const { t } = useTranslation();\n const tryInChat = useTryInChat();\n\n const samplePrompts = [\n t(\"tutorial.caPrompt1\"),\n t(\"tutorial.caPrompt2\"),\n t(\"tutorial.caPrompt3\"),\n t(\"tutorial.caPrompt4\"),\n ];\n\n return (\n <Card className=\"border-indigo-200 bg-gradient-to-br from-indigo-50 to-white\">\n <div className=\"flex flex-col gap-4 md:flex-row md:items-start\">\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-indigo-100 text-lg font-bold text-indigo-700\">\n ★\n </div>\n <div className=\"flex-1 space-y-3\">\n <div>\n <h3 className=\"text-base font-semibold text-gray-900\">\n {t(\"tutorial.caTitle\")}\n </h3>\n <p className=\"mt-1 text-xs uppercase tracking-wider text-indigo-700\">\n {t(\"tutorial.caBadge\")}\n </p>\n </div>\n <p className=\"text-sm leading-relaxed text-gray-700\">\n {t(\"tutorial.caBody\")}\n </p>\n <div className=\"rounded-md border border-indigo-100 bg-white px-3 py-2 text-xs text-gray-600\">\n <div className=\"mb-1 font-medium text-gray-800\">{t(\"tutorial.caTryAsking\")}</div>\n <ul className=\"space-y-0.5\">\n {samplePrompts.map((prompt) => (\n <li key={prompt}>\n <button\n type=\"button\"\n onClick={() => tryInChat(prompt)}\n className=\"text-left text-indigo-700 hover:text-indigo-900 hover:underline\"\n >\n “{prompt}”\n </button>\n </li>\n ))}\n </ul>\n </div>\n <div className=\"flex flex-wrap gap-3 pt-1\">\n <button\n type=\"button\"\n onClick={() => tryInChat(samplePrompts[2])}\n className=\"text-sm font-medium text-indigo-700 hover:text-indigo-900\"\n >\n {t(\"tutorial.caTryInChat\")} →\n </button>\n <Link\n to=\"/reports/analytics\"\n className=\"text-sm font-medium text-indigo-700 hover:text-indigo-900\"\n >\n {t(\"tutorial.caOpenWorkspace\")} →\n </Link>\n </div>\n </div>\n </div>\n </Card>\n );\n}\n\nfunction FlowDiagram() {\n const { t } = useTranslation();\n const chip = (k: string) => t(`tutorial.chips.${k}`, { defaultValue: k });\n return (\n <Card>\n <h3 className=\"text-base font-semibold text-gray-900 mb-3\">\n {t(\"tutorial.flowTitle\")}\n </h3>\n <div className=\"space-y-4 text-sm text-gray-600\">\n <div>\n <div className=\"font-medium text-gray-800 mb-1\">{t(\"tutorial.salesCycle\")}</div>\n <div className=\"flex flex-wrap items-center gap-1 font-mono text-xs\">\n <span className=\"rounded bg-blue-50 px-2 py-0.5 text-blue-700\">{chip(\"Quotation\")}</span>\n <span className=\"text-gray-400\">→</span>\n <span className=\"rounded bg-blue-50 px-2 py-0.5 text-blue-700\">{chip(\"Sales Order\")}</span>\n <span className=\"text-gray-400\">→</span>\n <span className=\"rounded bg-green-50 px-2 py-0.5 text-green-700\">{chip(\"Delivery Note\")}</span>\n <span className=\"text-gray-300\">/</span>\n <span className=\"rounded bg-amber-50 px-2 py-0.5 text-amber-700\">{chip(\"Sales Invoice\")}</span>\n <span className=\"text-gray-400\">→</span>\n <span className=\"rounded bg-purple-50 px-2 py-0.5 text-purple-700\">{chip(\"Payment Entry\")}</span>\n </div>\n <div className=\"mt-1 text-xs text-gray-400 italic\">\n {t(\"tutorial.flowShortcut\")}\n </div>\n </div>\n <div>\n <div className=\"font-medium text-gray-800 mb-1\">{t(\"tutorial.purchaseCycle\")}</div>\n <div className=\"flex flex-wrap items-center gap-1 font-mono text-xs\">\n <span className=\"rounded bg-blue-50 px-2 py-0.5 text-blue-700\">{chip(\"Purchase Order\")}</span>\n <span className=\"text-gray-400\">→</span>\n <span className=\"rounded bg-green-50 px-2 py-0.5 text-green-700\">{chip(\"Purchase Receipt\")}</span>\n <span className=\"text-gray-300\">/</span>\n <span className=\"rounded bg-amber-50 px-2 py-0.5 text-amber-700\">{chip(\"Purchase Invoice\")}</span>\n <span className=\"text-gray-400\">→</span>\n <span className=\"rounded bg-purple-50 px-2 py-0.5 text-purple-700\">{chip(\"Payment Entry\")}</span>\n </div>\n </div>\n <div>\n <div className=\"font-medium text-gray-800 mb-1\">{t(\"tutorial.returns\")}</div>\n <div className=\"flex flex-wrap items-center gap-1 font-mono text-xs\">\n <span className=\"rounded bg-amber-50 px-2 py-0.5 text-amber-700\">{chip(\"Sales Invoice\")}</span>\n <span className=\"text-gray-400\">→</span>\n <span className=\"rounded bg-red-50 px-2 py-0.5 text-red-700\">{chip(\"Credit Note\")}</span>\n <span className=\"mx-2 text-gray-300\">|</span>\n <span className=\"rounded bg-green-50 px-2 py-0.5 text-green-700\">{chip(\"Delivery Note\")}</span>\n <span className=\"text-gray-400\">→</span>\n <span className=\"rounded bg-red-50 px-2 py-0.5 text-red-700\">{chip(\"DN Return\")}</span>\n <span className=\"mx-2 text-gray-300\">|</span>\n <span className=\"rounded bg-amber-50 px-2 py-0.5 text-amber-700\">{chip(\"Purchase Invoice\")}</span>\n <span className=\"text-gray-400\">→</span>\n <span className=\"rounded bg-red-50 px-2 py-0.5 text-red-700\">{chip(\"Debit Note\")}</span>\n </div>\n </div>\n <div className=\"border-t pt-3 text-xs text-gray-500\">\n <span className=\"rounded bg-green-50 px-1.5 py-0.5 text-green-700\">Green</span> = {t(\"tutorial.legendStock\")},{\" \"}\n <span className=\"rounded bg-amber-50 px-1.5 py-0.5 text-amber-700\">Amber</span> = {t(\"tutorial.legendGl\")},{\" \"}\n <span className=\"rounded bg-purple-50 px-1.5 py-0.5 text-purple-700\">Purple</span> = {t(\"tutorial.legendCash\")},{\" \"}\n <span className=\"rounded bg-red-50 px-1.5 py-0.5 text-red-700\">Red</span> = {t(\"tutorial.legendReversal\")}\n </div>\n </div>\n </Card>\n );\n}\n\nfunction LifecycleCard() {\n const { t } = useTranslation();\n const chip = (k: string) => t(`tutorial.chips.${k}`, { defaultValue: k });\n return (\n <Card>\n <h3 className=\"text-base font-semibold text-gray-900 mb-3\">\n {t(\"tutorial.lifecycleTitle\")}\n </h3>\n <div className=\"space-y-2 text-sm text-gray-600\">\n <div className=\"flex flex-wrap items-center gap-2 font-mono text-xs\">\n <span className=\"rounded bg-gray-100 px-2 py-0.5 text-gray-600\">{chip(\"Draft\")}</span>\n <span className=\"text-gray-400\">→ save()</span>\n <span className=\"rounded bg-gray-100 px-2 py-0.5 text-gray-600\">{chip(\"Draft\")}</span>\n <span className=\"text-gray-400\">→ submit()</span>\n <span className=\"rounded bg-blue-100 px-2 py-0.5 text-blue-700\">{chip(\"Submitted\")}</span>\n <span className=\"text-gray-400\">→ cancel()</span>\n <span className=\"rounded bg-red-100 px-2 py-0.5 text-red-700\">{chip(\"Cancelled\")}</span>\n </div>\n <ul className=\"list-disc pl-5 space-y-1 text-xs text-gray-500\">\n <li><strong>{t(\"tutorial.lcDraftLabel\")}</strong> {t(\"tutorial.lcDraftDesc\")}</li>\n <li><strong>{t(\"tutorial.lcSubmittedLabel\")}</strong> {t(\"tutorial.lcSubmittedDesc\")}</li>\n <li><strong>{t(\"tutorial.lcCancelledLabel\")}</strong> {t(\"tutorial.lcCancelledDesc\")}</li>\n <li>{t(\"tutorial.lcNoDelete\")}</li>\n <li>{t(\"tutorial.lcCorrect\")}</li>\n </ul>\n </div>\n </Card>\n );\n}\n\nexport default function TutorialPage() {\n const { t } = useTranslation();\n return (\n <div className=\"mx-auto max-w-3xl space-y-6\">\n <div>\n <h2 className=\"text-xl font-semibold text-gray-900\">\n {t(\"tutorial.pageTitle\")}\n </h2>\n <p className=\"mt-1 text-sm text-gray-500\">\n {t(\"tutorial.intro\")}\n </p>\n <Link\n to=\"/chat\"\n className=\"mt-3 inline-flex items-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-700\"\n >\n {t(\"tutorial.openChat\")} →\n </Link>\n <p className=\"mt-4 rounded-lg border border-blue-200 bg-blue-50 px-4 py-3 text-sm text-blue-800\">\n <strong>{t(\"tutorial.tipLabel\")}</strong> {t(\"tutorial.topTip\")}\n </p>\n <p className=\"mt-4 text-sm text-gray-500\">\n {t(\"tutorial.manualIntro\")}\n </p>\n </div>\n\n <CompanySetupHighlight />\n <CustomAnalyticsHighlight />\n <FlowDiagram />\n <LifecycleCard />\n\n {STEPS.map((step) => (\n <Card key={step.number}>\n <div className=\"flex gap-4\">\n <div className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-blue-100 text-sm font-bold text-blue-700\">\n {step.number}\n </div>\n <div className=\"space-y-2\">\n <h3 className=\"text-base font-semibold text-gray-900\">\n {t(`tutorial.steps.${step.number}.title`, { defaultValue: step.title })}\n </h3>\n <p className=\"text-sm leading-relaxed text-gray-600\">\n {t(`tutorial.steps.${step.number}.description`, { defaultValue: step.description })}\n </p>\n {step.tip && (\n <p className=\"text-xs leading-relaxed text-amber-700 bg-amber-50 rounded px-3 py-2\">\n <strong>{t(\"tutorial.tipLabel\")}</strong> {t(`tutorial.steps.${step.number}.tip`, { defaultValue: step.tip })}\n </p>\n )}\n <div className=\"flex flex-wrap gap-3 pt-1\">\n {step.link && step.linkLabel && (\n <Link\n to={step.link}\n className=\"text-sm font-medium text-blue-600 hover:text-blue-800\"\n >\n {t(`tutorial.links.${step.linkLabel}`, { defaultValue: step.linkLabel })} →\n </Link>\n )}\n {step.links?.map((l) => (\n <Link\n key={l.to}\n to={l.to}\n className=\"text-sm font-medium text-blue-600 hover:text-blue-800\"\n >\n {t(`tutorial.links.${l.label}`, { defaultValue: l.label })} →\n </Link>\n ))}\n </div>\n </div>\n </div>\n </Card>\n ))}\n\n <Card>\n <div className=\"flex gap-4\">\n <div className=\"flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-green-100 text-sm font-bold text-green-700\">\n ✓\n </div>\n <div className=\"space-y-2\">\n <h3 className=\"text-base font-semibold text-gray-900\">\n {t(\"tutorial.readyTitle\")}\n </h3>\n <p className=\"text-sm leading-relaxed text-gray-600\">\n {t(\"tutorial.readyBody1\")}\n </p>\n <p className=\"text-sm leading-relaxed text-gray-600\">\n {t(\"tutorial.readyBody2\")}\n </p>\n <Link\n to=\"/chat\"\n className=\"inline-block text-sm font-medium text-blue-600 hover:text-blue-800\"\n >\n {t(\"tutorial.openChat\")} →\n </Link>\n </div>\n </div>\n </Card>\n </div>\n );\n}\n","import { useState, useEffect, useLayoutEffect, useRef, useCallback } from \"react\";\nimport { Link, useParams, useNavigate, useSearchParams, useLocation } from \"react-router-dom\";\nimport { type ChatMessage, type ChatAttachment, useChat, rememberSessionId } from \"@/components/chat/chat-provider\";\nimport { api } from \"@/api/client\";\nimport { useTranslation } from \"react-i18next\";\n\nconst MAX_ATTACHMENTS = 5;\nconst MAX_ATTACHMENT_SIZE = 10 * 1024 * 1024;\nconst ALLOWED_MIMES = new Set([\n \"image/png\", \"image/jpeg\", \"image/gif\", \"image/webp\", \"application/pdf\",\n // Spreadsheets\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\", // xlsx\n \"application/vnd.ms-excel\", // xls\n \"application/vnd.oasis.opendocument.spreadsheet\", // ods\n // Documents\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\", // docx\n \"application/msword\", // doc\n \"application/vnd.oasis.opendocument.text\", // odt\n // Presentations\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\", // pptx\n \"application/vnd.ms-powerpoint\", // ppt\n \"application/vnd.oasis.opendocument.presentation\", // odp\n // Delimited / text\n \"text/csv\", \"text/plain\",\n]);\n\n// Some browsers/OSes hand us an empty or octet-stream type for Office files, so\n// the picker also accepts by extension (mirrors the server's extension fallback).\nconst ALLOWED_EXTS = new Set([\n \"png\", \"jpg\", \"jpeg\", \"gif\", \"webp\", \"pdf\",\n \"xlsx\", \"xls\", \"ods\", \"docx\", \"doc\", \"odt\", \"pptx\", \"ppt\", \"odp\", \"csv\", \"txt\",\n]);\n\ninterface PendingAttachment {\n localId: string;\n file: File;\n previewUrl?: string;\n uploadedId?: string;\n uploading: boolean;\n error?: string;\n}\n\nfunction wait(ms: number): Promise<void> {\n return new Promise((resolve) => window.setTimeout(resolve, ms));\n}\n\n// Strip the `data:<mime>;base64,` prefix a FileReader data URL carries so we\n// send the server the bare base64 payload.\nfunction blobToBase64(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => {\n const result = typeof reader.result === \"string\" ? reader.result : \"\";\n resolve(result.includes(\",\") ? result.slice(result.indexOf(\",\") + 1) : result);\n };\n reader.onerror = () => reject(reader.error ?? new Error(\"Could not read audio.\"));\n reader.readAsDataURL(blob);\n });\n}\n\nfunction formatTime(ts?: string): string {\n if (!ts) return \"\";\n const d = new Date(ts);\n if (isNaN(d.getTime())) return \"\";\n\n const now = new Date();\n const sameDay =\n d.getFullYear() === now.getFullYear() &&\n d.getMonth() === now.getMonth() &&\n d.getDate() === now.getDate();\n\n if (sameDay) {\n return d.toLocaleTimeString([], { hour: \"2-digit\", minute: \"2-digit\" });\n }\n\n const sameYear = d.getFullYear() === now.getFullYear();\n if (sameYear) {\n return d.toLocaleDateString([], { day: \"numeric\", month: \"short\" });\n }\n\n return d.toLocaleDateString([], { day: \"numeric\", month: \"short\", year: \"numeric\" });\n}\n\nfunction formatFullTimestamp(ts?: string): string {\n if (!ts) return \"\";\n const d = new Date(ts);\n if (isNaN(d.getTime())) return \"\";\n return d.toLocaleString([], {\n year: \"numeric\", month: \"short\", day: \"numeric\",\n hour: \"2-digit\", minute: \"2-digit\", second: \"2-digit\",\n timeZoneName: \"short\",\n });\n}\n\nexport default function ChatPage() {\n const { t } = useTranslation();\n const { sessionId } = useParams<{ sessionId: string }>();\n const navigate = useNavigate();\n const location = useLocation();\n const [searchParams] = useSearchParams();\n const demoRequested = searchParams.get(\"demo\") === \"1\";\n const [input, setInput] = useState(\"\");\n const [demoError, setDemoError] = useState(\"\");\n const [attachments, setAttachments] = useState<PendingAttachment[]>([]);\n const [attachmentError, setAttachmentError] = useState(\"\");\n const [isDragOver, setIsDragOver] = useState(false);\n // Voice → text: \"idle\" (mic ready), \"recording\" (capturing), \"transcribing\"\n // (waiting on the server). Click toggles record on/off.\n const [voiceState, setVoiceState] = useState<\"idle\" | \"recording\" | \"transcribing\">(\"idle\");\n const fileInputRef = useRef<HTMLInputElement>(null);\n const mediaRecorderRef = useRef<MediaRecorder | null>(null);\n const audioChunksRef = useRef<Blob[]>([]);\n const {\n connectionStatus,\n connectionVersion,\n createSession,\n startDemo,\n completeDemoTyping,\n loadHistory,\n loadMoreHistory,\n sendMessage,\n transcribeAudio,\n getMessages,\n hasMoreHistory,\n isLoadingOlder,\n isThinking: getIsThinking,\n getDemoStatus,\n getDemoTypingCue,\n } = useChat();\n const scrollContainerRef = useRef<HTMLDivElement>(null);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLTextAreaElement>(null);\n const inputAreaRef = useRef<HTMLDivElement>(null);\n const [inputAreaHeight, setInputAreaHeight] = useState(0);\n const previousThinkingRef = useRef(false);\n const demoRunStartedRef = useRef<string | null>(null);\n const demoTypingRunIdRef = useRef(0);\n const shouldAutoScrollRef = useRef(true);\n const pendingPrependHeightRef = useRef<number | null>(null);\n // True while we're driving the scroll ourselves (smooth-scroll animation\n // or ResizeObserver-driven pin-to-bottom). Scroll events fired by those\n // animations must NOT be interpreted as the user scrolling up, or else\n // shouldAutoScrollRef flips to false mid-animation and every subsequent\n // rescroll gets gated out.\n const programmaticScrollRef = useRef(false);\n const programmaticScrollTimerRef = useRef<number | null>(null);\n const messages = getMessages(sessionId);\n const isConnected = connectionStatus === \"connected\";\n const isThinking = getIsThinking(sessionId);\n const demoStatus = getDemoStatus(sessionId);\n const demoTypingCue = getDemoTypingCue(sessionId);\n const isDemoReplaying = demoRequested || demoStatus === \"running\";\n const canLoadOlder = hasMoreHistory(sessionId);\n const loadingOlder = isLoadingOlder(sessionId);\n\n const lastMessage = messages[messages.length - 1];\n const lastMessageKey = lastMessage\n ? `${lastMessage.type}:${lastMessage.timestamp || \"\"}:${lastMessage.content}`\n : \"empty\";\n\n // Flag programmatic scrolls so the onScroll handler doesn't interpret\n // the browser's mid-animation scroll events as \"user scrolled up\".\n // Refreshes the reset timer each call — a rescroll inside 600ms\n // keeps the flag on for the full animation + reflow window.\n const markProgrammaticScroll = useCallback(() => {\n programmaticScrollRef.current = true;\n if (programmaticScrollTimerRef.current !== null) {\n window.clearTimeout(programmaticScrollTimerRef.current);\n }\n programmaticScrollTimerRef.current = window.setTimeout(() => {\n programmaticScrollRef.current = false;\n programmaticScrollTimerRef.current = null;\n }, 600);\n }, []);\n\n const scrollToBottom = useCallback((behavior: ScrollBehavior = \"smooth\") => {\n const el = scrollContainerRef.current;\n if (!el) return;\n // Drive the container directly instead of relying on\n // scrollIntoView — it's more predictable for tall messages and\n // avoids quirks around the zero-height end-of-list marker.\n markProgrammaticScroll();\n el.scrollTo({ top: el.scrollHeight, behavior });\n // A tall, freshly-mounted assistant bubble (markdown tables, long\n // lists) can still reflow after the effect commits — re-check once\n // a frame later, and once more after ~100ms for stragglers like\n // late-rendered images or resize-observed blocks. If the user has\n // already scrolled up manually, leave them alone.\n const rescroll = () => {\n const current = scrollContainerRef.current;\n if (!current) return;\n if (!shouldAutoScrollRef.current && !isDemoReplaying && !isThinking) return;\n if (current.scrollTop + current.clientHeight >= current.scrollHeight - 2) return;\n markProgrammaticScroll();\n current.scrollTo({ top: current.scrollHeight, behavior: \"auto\" });\n };\n requestAnimationFrame(rescroll);\n window.setTimeout(rescroll, 120);\n }, [isDemoReplaying, isThinking, markProgrammaticScroll]);\n\n useLayoutEffect(() => {\n const el = scrollContainerRef.current;\n const prevHeight = pendingPrependHeightRef.current;\n if (!el || prevHeight === null) return;\n const delta = el.scrollHeight - prevHeight;\n if (delta > 0) {\n el.scrollTop = el.scrollTop + delta;\n }\n pendingPrependHeightRef.current = null;\n }, [messages.length]);\n\n useEffect(() => {\n if (pendingPrependHeightRef.current !== null) return;\n if (!shouldAutoScrollRef.current && !isDemoReplaying && !isThinking) return;\n scrollToBottom(isDemoReplaying ? \"auto\" : \"smooth\");\n }, [lastMessageKey, isDemoReplaying, isThinking, scrollToBottom]);\n\n // Chase any post-commit layout growth (markdown tables, late-rendered\n // links, web-font reflows, images finalising their box). ResizeObserver\n // fires whenever the scroll container's content box changes size; if the\n // user hasn't manually scrolled up, keep pinning the view to the bottom.\n useEffect(() => {\n const el = scrollContainerRef.current;\n if (!el || typeof ResizeObserver === \"undefined\") return;\n let raf = 0;\n const observer = new ResizeObserver(() => {\n if (pendingPrependHeightRef.current !== null) return;\n if (!shouldAutoScrollRef.current && !isDemoReplaying && !isThinking) return;\n cancelAnimationFrame(raf);\n raf = requestAnimationFrame(() => {\n const current = scrollContainerRef.current;\n if (!current) return;\n const distanceFromBottom =\n current.scrollHeight - current.scrollTop - current.clientHeight;\n // Only chase when we're already near the bottom — avoids yanking the\n // view when the user is scrolled up reading history.\n if (distanceFromBottom <= 120) {\n markProgrammaticScroll();\n current.scrollTo({ top: current.scrollHeight, behavior: \"auto\" });\n }\n });\n });\n // Observe the content wrapper so tall new bubbles trigger the callback.\n const content = el.firstElementChild;\n if (content) observer.observe(content);\n observer.observe(el);\n return () => {\n observer.disconnect();\n cancelAnimationFrame(raf);\n };\n }, [isDemoReplaying, isThinking, markProgrammaticScroll]);\n\n // Reserve bottom space in the scroll content equal to the floating input's\n // actual height so the tail of a long message never hides behind it. The\n // input height is variable (textarea auto-grows, attachment strip appears),\n // so measure it live instead of hardcoding the padding.\n useLayoutEffect(() => {\n const el = inputAreaRef.current;\n if (!el) return;\n setInputAreaHeight(el.offsetHeight);\n if (typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(() => setInputAreaHeight(el.offsetHeight));\n observer.observe(el);\n return () => observer.disconnect();\n }, []);\n\n const handleLoadOlder = useCallback(() => {\n if (!sessionId) return;\n if (loadingOlder || !canLoadOlder) return;\n const el = scrollContainerRef.current;\n pendingPrependHeightRef.current = el ? el.scrollHeight : null;\n shouldAutoScrollRef.current = false;\n void loadMoreHistory(sessionId).catch(() => {\n pendingPrependHeightRef.current = null;\n });\n }, [sessionId, loadingOlder, canLoadOlder, loadMoreHistory]);\n\n // Tracks the location.state object we've already consumed so the\n // StrictMode synthetic remount (and any later re-render with the same\n // state) doesn't double-apply or clobber the prefill.\n const consumedNavStateRef = useRef<unknown>(null);\n\n useEffect(() => {\n setDemoError(\"\");\n demoRunStartedRef.current = null;\n demoTypingRunIdRef.current += 1;\n // Remember that this browser participated in this chat, so the sidebar\n // keeps showing it even when the server-side filter hides demo-only\n // sessions for the shared public_manager account.\n if (sessionId) rememberSessionId(sessionId);\n\n const navState = location.state as { prefillMessage?: string } | null;\n if (navState?.prefillMessage && consumedNavStateRef.current !== navState) {\n consumedNavStateRef.current = navState;\n setInput(navState.prefillMessage);\n window.setTimeout(() => inputRef.current?.focus(), 50);\n } else if (!navState?.prefillMessage) {\n consumedNavStateRef.current = null;\n setInput(\"\");\n }\n }, [sessionId, demoRequested, location.state]);\n\n // If no sessionId, create one and redirect\n useEffect(() => {\n if (sessionId || !isConnected) return;\n\n let cancelled = false;\n createSession()\n .then((session) => {\n if (!cancelled) {\n navigate(`/chat/${session.id}`, { replace: true });\n }\n })\n .catch(() => {\n // ignore\n });\n\n return () => {\n cancelled = true;\n };\n }, [sessionId, isConnected, navigate]);\n\n const loadHistoryRef = useRef(loadHistory);\n useEffect(() => {\n loadHistoryRef.current = loadHistory;\n }, [loadHistory]);\n\n useEffect(() => {\n if (!sessionId || !isConnected) return;\n if (demoRequested || demoStatus === \"running\") return;\n void loadHistoryRef.current(sessionId).catch(() => {\n // ignore\n });\n }, [sessionId, isConnected, connectionVersion, demoRequested, demoStatus]);\n\n useEffect(() => {\n if (previousThinkingRef.current && !isThinking && isConnected) {\n setTimeout(() => inputRef.current?.focus(), 50);\n }\n previousThinkingRef.current = isThinking;\n }, [isThinking, isConnected]);\n\n function handleMessagesScroll(e: React.UIEvent<HTMLDivElement>) {\n // Ignore scroll events fired by our own programmatic scrolls —\n // mid-animation positions are meaningless for \"is the user reading\n // history?\" and flipping shouldAutoScrollRef mid-animation defeats\n // the whole auto-scroll chain.\n if (programmaticScrollRef.current) return;\n const el = e.currentTarget;\n const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight;\n shouldAutoScrollRef.current = distanceFromBottom < 80;\n }\n\n useEffect(() => {\n if (!sessionId || !isConnected || !demoRequested) return;\n if (demoRunStartedRef.current === sessionId) return;\n\n demoRunStartedRef.current = sessionId;\n setDemoError(\"\");\n void startDemo(sessionId).catch((err) => {\n demoRunStartedRef.current = null;\n setDemoError(err instanceof Error ? err.message : t(\"chat.demoError\"));\n });\n }, [sessionId, isConnected, demoRequested, startDemo]);\n\n useEffect(() => {\n if (!sessionId || !demoRequested || demoStatus !== \"complete\") return;\n setInput(\"\");\n navigate(`/chat/${sessionId}`, { replace: true });\n }, [sessionId, demoRequested, demoStatus, navigate]);\n\n const completeDemoTypingRef = useRef(completeDemoTyping);\n useEffect(() => {\n completeDemoTypingRef.current = completeDemoTyping;\n }, [completeDemoTyping]);\n\n const typedCueSeqRef = useRef<number | null>(null);\n useEffect(() => {\n if (!demoTypingCue || !sessionId) return;\n // Guard against re-runs for the same cue (provider re-renders recreate object refs)\n if (typedCueSeqRef.current === demoTypingCue.seq) return;\n typedCueSeqRef.current = demoTypingCue.seq;\n\n const targetSessionId = sessionId;\n const typingContent = demoTypingCue.content;\n const charDelay = typingContent.length > 0\n ? Math.max(8, demoTypingCue.typingMs / typingContent.length)\n : 0;\n const typingSeq = demoTypingCue.seq;\n\n const runId = ++demoTypingRunIdRef.current;\n\n async function animateTyping() {\n setInput(\"\");\n for (const char of typingContent) {\n if (runId !== demoTypingRunIdRef.current) return;\n setInput((prev) => prev + char);\n await wait(charDelay);\n }\n if (runId !== demoTypingRunIdRef.current) return;\n completeDemoTypingRef.current(targetSessionId, typingSeq);\n }\n\n void animateTyping();\n }, [demoTypingCue, sessionId]);\n\n useEffect(() => {\n if (demoStatus !== \"complete\") return;\n demoTypingRunIdRef.current += 1;\n setInput(\"\");\n }, [demoStatus]);\n\n const addFiles = useCallback((fileList: FileList | File[]) => {\n if (!sessionId) return;\n setAttachmentError(\"\");\n const incoming = Array.from(fileList);\n\n setAttachments((prev) => {\n const result = [...prev];\n for (const file of incoming) {\n if (result.length >= MAX_ATTACHMENTS) {\n setAttachmentError(`Maximum ${MAX_ATTACHMENTS} attachments per message.`);\n break;\n }\n const ext = file.name.includes(\".\") ? file.name.split(\".\").pop()!.toLowerCase() : \"\";\n if (!ALLOWED_MIMES.has(file.type) && !ALLOWED_EXTS.has(ext)) {\n setAttachmentError(`Unsupported file type: ${file.type || file.name}`);\n continue;\n }\n if (file.size > MAX_ATTACHMENT_SIZE) {\n setAttachmentError(`\"${file.name}\" is too large (max 10 MB).`);\n continue;\n }\n\n const localId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n const previewUrl = file.type.startsWith(\"image/\")\n ? URL.createObjectURL(file)\n : undefined;\n const pending: PendingAttachment = { localId, file, previewUrl, uploading: true };\n result.push(pending);\n\n // Fire upload\n api.uploadChatAttachment(sessionId, file)\n .then((res) => {\n setAttachments((current) =>\n current.map((a) =>\n a.localId === localId ? { ...a, uploading: false, uploadedId: res.id } : a,\n ),\n );\n // Non-blocking advisory (e.g. a spreadsheet over the model's\n // per-sheet row limit) — the attachment still uploaded fine.\n if (res.warning) setAttachmentError(`\"${file.name}\": ${res.warning}`);\n })\n .catch((err) => {\n const msg = err?.message || \"Upload failed\";\n // Surface the server's detail (e.g. demo size cap) in the banner\n // so the user actually sees *why* — the pending tile only has\n // room for \"Failed\".\n setAttachmentError(`\"${file.name}\": ${msg}`);\n setAttachments((current) =>\n current.map((a) =>\n a.localId === localId ? { ...a, uploading: false, error: msg } : a,\n ),\n );\n });\n }\n return result;\n });\n }, [sessionId]);\n\n const removeAttachment = (localId: string) => {\n setAttachments((prev) => {\n const victim = prev.find((a) => a.localId === localId);\n if (victim?.previewUrl) URL.revokeObjectURL(victim.previewUrl);\n return prev.filter((a) => a.localId !== localId);\n });\n };\n\n // Drag-and-drop support on the chat area\n const handleDragOver = (e: React.DragEvent) => {\n if (e.dataTransfer.types.includes(\"Files\")) {\n e.preventDefault();\n setIsDragOver(true);\n }\n };\n const handleDragLeave = (e: React.DragEvent) => {\n // Only clear when the drag actually leaves the outer container, not when\n // moving over children. relatedTarget is null or outside when truly leaving.\n const related = e.relatedTarget as Node | null;\n if (!related || !(e.currentTarget as Node).contains(related)) {\n setIsDragOver(false);\n }\n };\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault();\n setIsDragOver(false);\n if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n addFiles(e.dataTransfer.files);\n }\n };\n\n // Paste image / PDF from clipboard\n const handlePaste = (e: React.ClipboardEvent) => {\n const files: File[] = [];\n for (const item of e.clipboardData.items) {\n if (item.kind === \"file\") {\n const f = item.getAsFile();\n if (f) files.push(f);\n }\n }\n if (files.length > 0) {\n e.preventDefault();\n addFiles(files);\n }\n };\n\n const hasUnfinishedUploads = attachments.some((a) => a.uploading);\n const hasFailedUploads = attachments.some((a) => a.error);\n const readyAttachmentIds = attachments\n .filter((a) => a.uploadedId && !a.error)\n .map((a) => a.uploadedId as string);\n\n function sendCurrentMessage() {\n const text = input.trim();\n if (!sessionId) return;\n if (!text && readyAttachmentIds.length === 0) return;\n if (hasUnfinishedUploads) return;\n if (!sendMessage(sessionId, text, readyAttachmentIds.length > 0 ? readyAttachmentIds : undefined)) return;\n // Clean up previews\n for (const att of attachments) {\n if (att.previewUrl) URL.revokeObjectURL(att.previewUrl);\n }\n setAttachments([]);\n setAttachmentError(\"\");\n setInput(\"\");\n }\n\n function handleKeyDown(e: React.KeyboardEvent) {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n sendCurrentMessage();\n }\n }\n\n // Append the transcript to whatever is already typed so a voice note adds to\n // the draft rather than replacing it. Returns the text trimmed/spaced.\n function appendTranscript(text: string) {\n const clean = text.trim();\n if (!clean) return;\n setInput((prev) => (prev.trim() ? `${prev.trim()} ${clean}` : clean));\n // Defer focus so the textarea has the new value when we resize it.\n window.setTimeout(() => {\n const el = inputRef.current;\n if (!el) return;\n el.focus();\n el.style.height = \"auto\";\n el.style.height = Math.min(Math.max(el.scrollHeight, 48), 120) + \"px\";\n }, 0);\n }\n\n async function startRecording() {\n if (voiceState !== \"idle\") return;\n let stream: MediaStream;\n try {\n stream = await navigator.mediaDevices.getUserMedia({ audio: true });\n } catch {\n setAttachmentError(t(\"chat.micDenied\"));\n return;\n }\n\n setAttachmentError(\"\");\n const recorder = new MediaRecorder(stream);\n mediaRecorderRef.current = recorder;\n audioChunksRef.current = [];\n\n recorder.ondataavailable = (event) => {\n if (event.data.size > 0) audioChunksRef.current.push(event.data);\n };\n\n recorder.onstop = async () => {\n stream.getTracks().forEach((track) => track.stop());\n const chunks = audioChunksRef.current;\n audioChunksRef.current = [];\n mediaRecorderRef.current = null;\n if (chunks.length === 0) {\n setVoiceState(\"idle\");\n return;\n }\n const mimeType = recorder.mimeType || chunks[0]?.type || \"audio/webm\";\n const blob = new Blob(chunks, { type: mimeType });\n // \"audio/webm;codecs=opus\" → \"webm\"; the server only needs the container.\n const format = (mimeType.split(\";\")[0].split(\"/\")[1] || \"webm\").toLowerCase();\n\n setVoiceState(\"transcribing\");\n try {\n const base64 = await blobToBase64(blob);\n const text = await transcribeAudio(base64, format, sessionId);\n appendTranscript(text);\n } catch (error) {\n setAttachmentError(error instanceof Error ? error.message : t(\"chat.transcribeFailed\"));\n } finally {\n setVoiceState(\"idle\");\n }\n };\n\n recorder.start();\n setVoiceState(\"recording\");\n }\n\n function stopRecording() {\n const recorder = mediaRecorderRef.current;\n if (recorder && recorder.state !== \"inactive\") {\n recorder.stop();\n }\n }\n\n function toggleRecording() {\n if (voiceState === \"recording\") {\n stopRecording();\n } else if (voiceState === \"idle\") {\n void startRecording();\n }\n }\n\n if (!sessionId) {\n return (\n <div className=\"flex h-full items-center justify-center text-fg-muted\">\n {t(\"chat.creating\")}\n </div>\n );\n }\n\n return (\n <div\n className=\"relative -m-4 h-[calc(100%+2rem)] overflow-hidden md:-m-6 md:h-[calc(100%+3rem)]\"\n onDragOver={handleDragOver}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n >\n {isDragOver && (\n <div className=\"pointer-events-none absolute inset-3 z-50 flex items-center justify-center rounded-lg border-2 border-dashed border-brand bg-brand/5 text-sm font-medium text-brand\">\n {t(\"chat.dropToAttach\")}\n </div>\n )}\n {/* Messages — full-height scroll area so the scrollbar reaches the\n bottom edge of the viewport. Inner content reserves bottom padding\n equal to the floating input's measured height (inputAreaHeight) so\n the last message always clears it, even as the input grows. */}\n <div\n ref={scrollContainerRef}\n className=\"absolute inset-0 overflow-y-auto px-4 py-6\"\n onScroll={handleMessagesScroll}\n >\n <div\n className=\"mx-auto max-w-3xl space-y-4\"\n style={{ paddingBottom: (inputAreaHeight || 96) + 16 }}\n >\n {(canLoadOlder || loadingOlder) && messages.length > 0 && (\n <div className=\"flex justify-center\">\n <button\n onClick={handleLoadOlder}\n disabled={loadingOlder || !canLoadOlder}\n className=\"rounded-full bg-surface px-3 py-1 text-xs text-fg-muted ring-1 ring-line transition-colors hover:bg-surface-subtle hover:text-fg disabled:cursor-not-allowed disabled:opacity-60\"\n >\n {loadingOlder ? t(\"common.loading\") : t(\"chat.loadOlder\")}\n </button>\n </div>\n )}\n {demoError && (\n <div className=\"rounded-md bg-rose-50 px-4 py-3 text-sm text-rose-700 ring-1 ring-rose-200\">\n {demoError}\n </div>\n )}\n\n {messages.length === 0 && demoStatus !== \"running\" && !demoRequested && (\n <div className=\"py-20 text-center\">\n <h3 className=\"text-lg font-semibold text-fg-muted\">\n {t(\"chat.title\")}\n </h3>\n <p className=\"mt-2 text-sm text-fg-muted\">\n {t(\"chat.subtitle\")}\n </p>\n <div className=\"mt-6 flex flex-wrap justify-center gap-2\">\n {[\n t(\"chat.s1\"),\n t(\"chat.s2\"),\n t(\"chat.s3\"),\n t(\"chat.s4\"),\n ].map((suggestion) => (\n <button\n key={suggestion}\n onClick={() => {\n setInput(suggestion);\n inputRef.current?.focus();\n }}\n className=\"rounded-full bg-surface px-3 py-1.5 text-xs text-fg-muted ring-1 ring-line transition-all hover:bg-surface-subtle hover:text-fg hover:ring-brand/30\"\n >\n {suggestion}\n </button>\n ))}\n </div>\n </div>\n )}\n\n {messages.map((msg, idx) => (\n <MessageBubble key={idx} message={msg} />\n ))}\n <div ref={messagesEndRef} />\n </div>\n </div>\n\n {/* Input — absolutely positioned over the message scroll area so the\n scrollbar can reach the bottom edge. bg-surface-muted matches the\n page bg so the textarea card visually floats. The right-side gap\n (md:right-6 / md:pl-6 / md:pr-0) only applies on desktop, where\n scrollbars are always visible and ~17–18px wide. On mobile the\n overlay scrollbar auto-hides, so we extend the wrapper edge-to-\n edge (right-0, px-4) to avoid an empty gap on the right. */}\n <div\n ref={inputAreaRef}\n className=\"absolute bottom-0 left-0 right-0 bg-surface-muted px-4 pb-[max(0.75rem,env(safe-area-inset-bottom))] md:right-6 md:pl-6 md:pr-0\"\n >\n <div className=\"mx-auto max-w-3xl\">\n {/* Attachment preview strip */}\n {attachments.length > 0 && (\n <div className=\"mb-2 flex flex-wrap gap-2\">\n {attachments.map((att) => (\n <div\n key={att.localId}\n className=\"relative flex items-center gap-2 rounded-lg bg-surface px-2 py-1.5 text-xs ring-1 ring-line shadow-card\"\n >\n {att.previewUrl ? (\n <img src={att.previewUrl} alt=\"\" className=\"h-10 w-10 rounded object-cover\" />\n ) : (\n <div className=\"flex h-10 w-10 items-center justify-center rounded bg-rose-100 text-[10px] font-bold text-rose-700\">\n PDF\n </div>\n )}\n <div className=\"flex min-w-0 flex-col\">\n <span className=\"max-w-[160px] truncate text-fg\">{att.file.name}</span>\n <span className=\"text-[10px] text-fg-muted\">\n {att.uploading ? t(\"chat.uploading\") : att.error ? t(\"chat.failed\") : `${Math.round(att.file.size / 1024)} KB`}\n </span>\n </div>\n <button\n onClick={() => removeAttachment(att.localId)}\n className=\"ml-1 text-fg-muted transition-colors hover:text-red-500\"\n title={t(\"chat.remove\")}\n >\n <svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" fill=\"currentColor\">\n <path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\" />\n </svg>\n </button>\n </div>\n ))}\n </div>\n )}\n {attachmentError && (\n <div className=\"mb-2 rounded-md bg-rose-50 px-3 py-1.5 text-xs text-rose-700 ring-1 ring-rose-200 shadow-card\">{attachmentError}</div>\n )}\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/png,image/jpeg,image/gif,image/webp,application/pdf,.xlsx,.xls,.ods,.docx,.doc,.odt,.pptx,.ppt,.odp,.csv,.txt,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel,application/vnd.oasis.opendocument.spreadsheet,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/msword,application/vnd.oasis.opendocument.text,application/vnd.openxmlformats-officedocument.presentationml.presentation,application/vnd.ms-powerpoint,application/vnd.oasis.opendocument.presentation,text/csv,text/plain\"\n multiple\n className=\"hidden\"\n onChange={(e) => {\n if (e.target.files && e.target.files.length > 0) {\n addFiles(e.target.files);\n e.target.value = \"\";\n }\n }}\n />\n {/* Single \"input card\" that contains the textarea and both action\n buttons. The card carries the surface bg + ring + shadow that\n the textarea used to carry on its own; focus-within promotes\n the ring to the brand-tinted halo when the textarea is\n focused. Send button no longer has a filled bg — both action\n buttons are ghost-style with semantic colors (text-fg-muted\n for attach, text-brand for send). */}\n <div className=\"flex items-end gap-1 rounded-xl bg-surface p-1.5 ring-1 ring-line shadow-card transition-all focus-within:ring-2 focus-within:ring-brand/30\">\n <textarea\n ref={inputRef}\n value={input}\n onChange={(e) => setInput(e.target.value)}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n placeholder={\n isDemoReplaying\n ? t(\"chat.placeholderDemo\")\n : isConnected\n ? t(\"chat.placeholderType\")\n : t(\"chat.placeholderConnecting\")\n }\n disabled={!isConnected || !sessionId || isThinking || isDemoReplaying}\n rows={2}\n className=\"block flex-1 resize-none bg-transparent px-2.5 py-1.5 text-sm text-fg outline-none placeholder:text-fg-muted/70 disabled:text-fg-muted\"\n style={{ minHeight: \"3rem\", maxHeight: \"120px\" }}\n onInput={(e) => {\n const target = e.target as HTMLTextAreaElement;\n target.style.height = \"auto\";\n target.style.height = Math.min(Math.max(target.scrollHeight, 48), 120) + \"px\";\n }}\n />\n <button\n onClick={() => fileInputRef.current?.click()}\n disabled={!isConnected || !sessionId || isThinking || isDemoReplaying || attachments.length >= MAX_ATTACHMENTS}\n className=\"flex h-11 w-11 shrink-0 items-center justify-center rounded-lg text-fg-muted transition-all hover:bg-surface-subtle hover:text-fg disabled:cursor-not-allowed disabled:opacity-40 md:h-10 md:w-10\"\n title={t(\"chat.attachTitle\")}\n >\n <svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M21.44 11.05l-9.19 9.19a6 6 0 01-8.49-8.49l9.19-9.19a4 4 0 015.66 5.66l-9.2 9.19a2 2 0 01-2.83-2.83l8.49-8.48\" />\n </svg>\n </button>\n <button\n onClick={toggleRecording}\n disabled={!isConnected || !sessionId || isThinking || isDemoReplaying || voiceState === \"transcribing\"}\n className={`flex h-11 w-11 shrink-0 items-center justify-center rounded-lg transition-all disabled:cursor-not-allowed disabled:opacity-40 md:h-10 md:w-10 ${\n voiceState === \"recording\"\n ? \"bg-rose-500/10 text-rose-600 hover:bg-rose-500/20\"\n : \"text-fg-muted hover:bg-surface-subtle hover:text-fg\"\n }`}\n title={\n voiceState === \"recording\"\n ? t(\"chat.voiceStop\")\n : voiceState === \"transcribing\"\n ? t(\"chat.voiceTranscribing\")\n : t(\"chat.voiceStart\")\n }\n >\n {voiceState === \"transcribing\" ? (\n <svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" className=\"animate-spin\">\n <path d=\"M21 12a9 9 0 11-6.219-8.56\" strokeLinecap=\"round\" />\n </svg>\n ) : voiceState === \"recording\" ? (\n <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"currentColor\" className=\"animate-pulse\">\n <rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"2\" />\n </svg>\n ) : (\n <svg viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 1a3 3 0 00-3 3v8a3 3 0 006 0V4a3 3 0 00-3-3z\" />\n <path d=\"M19 10v2a7 7 0 01-14 0v-2\" />\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\" />\n <line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\" />\n </svg>\n )}\n </button>\n <button\n onClick={sendCurrentMessage}\n disabled={(!input.trim() && readyAttachmentIds.length === 0) || !isConnected || !sessionId || isThinking || isDemoReplaying || hasUnfinishedUploads || hasFailedUploads}\n className=\"flex h-11 w-11 shrink-0 items-center justify-center rounded-lg text-brand transition-all hover:bg-brand/10 active:translate-y-px disabled:cursor-not-allowed disabled:text-fg-muted disabled:active:translate-y-0 md:h-10 md:w-10\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n width=\"18\"\n height=\"18\"\n fill=\"currentColor\"\n >\n <path d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\" />\n </svg>\n </button>\n </div>\n <div className=\"mt-1.5 flex items-center gap-1.5\">\n <span\n className={`inline-block h-1.5 w-1.5 rounded-full ${isConnected ? \"bg-emerald-500\" : \"bg-rose-500\"} ${isConnected ? \"\" : \"animate-pulse\"}`}\n />\n <span className=\"text-[11px] text-fg-muted\">\n {isConnected ? \"Connected\" : connectionStatus === \"connecting\" ? \"Connecting...\" : \"Disconnected\"}\n </span>\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nfunction AttachmentThumbs({ attachments }: { attachments?: ChatAttachment[] }) {\n if (!attachments || attachments.length === 0) return null;\n return (\n <div className=\"mt-1 flex flex-wrap gap-1.5\">\n {attachments.map((att) => {\n const url = api.getChatAttachmentUrl(att.id);\n const isImage = att.mime_type.startsWith(\"image/\");\n return (\n <a\n key={att.id}\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-1.5 rounded bg-black/10 px-1.5 py-1 text-[11px] hover:bg-black/20\"\n title={att.filename}\n >\n {isImage ? (\n <img src={url} alt={att.filename} className=\"h-8 w-8 rounded object-cover\" />\n ) : (\n <span className=\"flex h-8 w-8 items-center justify-center rounded bg-red-200 text-[9px] font-bold text-red-800\">PDF</span>\n )}\n <span className=\"max-w-[120px] truncate\">{att.filename}</span>\n </a>\n );\n })}\n </div>\n );\n}\n\nfunction MessageBubble({ message }: { message: ChatMessage }) {\n if (message.type === \"user\") {\n return (\n <div className=\"flex justify-end\">\n <div className=\"max-w-[80%] break-words rounded-2xl rounded-br-md bg-gradient-to-b from-brand to-brand/90 px-4 py-2.5 text-sm text-brand-fg ring-1 ring-black/10 shadow-bubble-user\">\n <div className=\"whitespace-pre-wrap\">{message.content}</div>\n <AttachmentThumbs attachments={message.attachments} />\n {message.timestamp && (\n <div className=\"mt-1 text-right text-[10px] text-brand-fg/70\" title={formatFullTimestamp(message.timestamp)}>{formatTime(message.timestamp)}</div>\n )}\n </div>\n </div>\n );\n }\n\n if (message.type === \"assistant\") {\n return (\n <div className=\"flex justify-start\">\n <div className=\"max-w-[80%] break-words rounded-2xl rounded-bl-md bg-surface px-4 py-2.5 text-sm text-fg ring-1 ring-line shadow-card\">\n <MarkdownContent content={message.content} />\n {message.timestamp && (\n <div className=\"mt-1 text-right text-[10px] text-fg-muted\" title={formatFullTimestamp(message.timestamp)}>{formatTime(message.timestamp)}</div>\n )}\n </div>\n </div>\n );\n }\n\n if (message.type === \"thinking\") {\n return (\n <div className=\"flex justify-start\">\n <div className=\"flex items-center gap-2 rounded-full bg-surface px-3 py-1.5 text-xs text-fg-muted ring-1 ring-line shadow-card\">\n <span className=\"inline-block h-1.5 w-1.5 animate-pulse rounded-full bg-brand\" />\n {message.content}\n {message.provider && (\n <span className=\"rounded bg-surface-subtle px-1.5 py-0.5 text-[10px] font-medium text-fg-muted ring-1 ring-line\">\n {message.provider}\n {message.model ? ` · ${message.model}` : \"\"}\n </span>\n )}\n </div>\n </div>\n );\n }\n\n if (message.type === \"tool_call\") {\n return (\n <div className=\"flex justify-start\">\n <div className=\"rounded-lg bg-surface px-3 py-2 text-xs ring-1 ring-line shadow-card\">\n <div className=\"flex items-center gap-1.5 font-medium text-fg-muted\">\n <svg\n viewBox=\"0 0 24 24\"\n width=\"12\"\n height=\"12\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z\" />\n </svg>\n <span className=\"font-mono\">{message.tool}</span>\n </div>\n {message.args && (\n <pre className=\"mt-1 max-h-20 overflow-auto whitespace-pre-wrap font-mono text-[11px] text-fg-muted/80\">\n {JSON.stringify(message.args, null, 2)}\n </pre>\n )}\n </div>\n </div>\n );\n }\n\n if (message.type === \"tool_result\") {\n return (\n <div className=\"flex justify-start\">\n <div\n className={`rounded-lg px-3 py-2 text-xs shadow-card ring-1 ring-inset ${message.success ? \"bg-emerald-50 ring-emerald-200\" : \"bg-rose-50 ring-rose-200\"}`}\n >\n <div className=\"flex items-center gap-1.5\">\n <span className={message.success ? \"text-emerald-600\" : \"text-rose-600\"}>\n {message.success ? \"\\u2713\" : \"\\u2717\"}\n </span>\n <span className=\"font-mono font-medium text-fg\">{message.tool}</span>\n </div>\n <pre className=\"mt-1 max-h-32 overflow-auto whitespace-pre-wrap font-mono text-[11px] text-fg-muted\">\n {message.content}\n </pre>\n </div>\n </div>\n );\n }\n\n if (message.type === \"error\") {\n return (\n <div className=\"flex justify-start\">\n <div className=\"max-w-[80%] rounded-2xl rounded-bl-md bg-rose-50 px-4 py-2.5 text-sm text-rose-700 ring-1 ring-rose-200 shadow-card\">\n {message.content}\n </div>\n </div>\n );\n }\n\n return null;\n}\n\nfunction MarkdownContent({ content }: { content: string }) {\n const lines = content.split(\"\\n\");\n const elements: React.ReactNode[] = [];\n let inCodeBlock = false;\n let codeLines: string[] = [];\n\n lines.forEach((line, i) => {\n if (line.startsWith(\"```\")) {\n if (inCodeBlock) {\n elements.push(\n <pre\n key={`code-${i}`}\n className=\"my-2 overflow-auto rounded bg-gray-800 p-3 text-xs text-green-300\"\n >\n {codeLines.join(\"\\n\")}\n </pre>,\n );\n codeLines = [];\n inCodeBlock = false;\n } else {\n inCodeBlock = true;\n }\n return;\n }\n if (inCodeBlock) {\n codeLines.push(line);\n return;\n }\n\n if (line.startsWith(\"### \")) {\n elements.push(\n <h4 key={i} className=\"mt-3 mb-1 font-semibold\">\n {line.slice(4)}\n </h4>,\n );\n } else if (line.startsWith(\"## \")) {\n elements.push(\n <h3 key={i} className=\"mt-3 mb-1 text-base font-semibold\">\n {line.slice(3)}\n </h3>,\n );\n } else if (/^\\s*[-*•]\\s+/.test(line)) {\n // Require whitespace after the marker so a bold line like `**Heading**`\n // isn't mistaken for a `*` bullet (which stripped one star and mangled\n // the bold). Real list items always have a space: `- item`, `* item`.\n const content = line.replace(/^\\s*[-*•]\\s+/, \"\");\n elements.push(\n <div key={i} className=\"ml-3 flex gap-1\">\n <span className=\"text-fg-muted\">•</span>\n <span>{formatInline(content)}</span>\n </div>,\n );\n } else if (line.trim() === \"\") {\n elements.push(<div key={i} className=\"h-2\" />);\n } else {\n elements.push(\n <p key={i} className=\"leading-relaxed\">\n {formatInline(line)}\n </p>,\n );\n }\n });\n\n return <div>{elements}</div>;\n}\n\nfunction renderLink(href: string, label: React.ReactNode, key: number | string): React.ReactNode {\n // `/api/*` is a backend endpoint (PDFs, file downloads, attachments) —\n // not a React Router route. Route client-side only for real SPA paths.\n const isSpaRoute = href.startsWith(\"/\") && !href.startsWith(\"/api/\");\n const baseClass = \"font-medium text-brand underline decoration-brand/40 underline-offset-2 transition-colors hover:decoration-brand\";\n if (isSpaRoute) {\n return (\n <Link key={key} to={href} className={baseClass}>\n {label}\n </Link>\n );\n }\n return (\n <a\n key={key}\n href={href}\n className={baseClass}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {label}\n </a>\n );\n}\n\n// Bare URLs: http(s)://... or /internal?query paths. We stop at whitespace,\n// closing punctuation like ), ], }, \", ', and end-of-string. Trailing\n// sentence punctuation (. , ; : ! ?) is stripped below so it doesn't get\n// swallowed into the href.\nconst BARE_URL_RE = /(https?:\\/\\/[^\\s)\\]}\"'<>]+|\\/(?:reports|app|masters|admin|chat|setup|tutorial)[^\\s)\\]}\"'<>]*)/g;\n\nfunction formatInline(text: string): React.ReactNode {\n // Split on (in priority order) markdown links, bold, inline code, bare URLs.\n const parts = text.split(/(\\[[^\\]]+\\]\\([^)]+\\)|\\*\\*[^*]+?\\*\\*|`[^`]+`)/g);\n return parts.flatMap((part, i) => {\n const linkMatch = part.match(/^\\[([^\\]]+)\\]\\(([^)]+)\\)$/);\n if (linkMatch) {\n const [, label, href] = linkMatch;\n return renderLink(href, formatInline(label), i);\n }\n if (part.startsWith(\"**\") && part.endsWith(\"**\") && part.length > 4) {\n return (\n <strong key={i} className=\"font-semibold\">\n {formatInline(part.slice(2, -2))}\n </strong>\n );\n }\n if (part.startsWith(\"`\") && part.endsWith(\"`\")) {\n return (\n <code\n key={i}\n className=\"rounded bg-gray-200 px-1 py-0.5 text-xs font-mono\"\n >\n {part.slice(1, -1)}\n </code>\n );\n }\n // Plain text segment: scan for bare URLs and linkify them.\n return linkifyBare(part, `${i}`);\n });\n}\n\nfunction linkifyBare(text: string, keyPrefix: string): React.ReactNode[] {\n const nodes: React.ReactNode[] = [];\n let lastIndex = 0;\n let match: RegExpExecArray | null;\n const re = new RegExp(BARE_URL_RE.source, \"g\");\n let idx = 0;\n while ((match = re.exec(text)) !== null) {\n const start = match.index;\n let matched = match[0];\n // Strip trailing sentence punctuation that shouldn't belong to the URL.\n let trailing = \"\";\n while (matched.length > 0 && /[.,;:!?]$/.test(matched)) {\n trailing = matched.slice(-1) + trailing;\n matched = matched.slice(0, -1);\n }\n if (start > lastIndex) {\n nodes.push(text.slice(lastIndex, start));\n }\n nodes.push(renderLink(matched, matched, `${keyPrefix}-u${idx}`));\n if (trailing) nodes.push(trailing);\n lastIndex = start + match[0].length;\n idx += 1;\n }\n if (lastIndex < text.length) {\n nodes.push(text.slice(lastIndex));\n }\n return nodes.length > 0 ? nodes : [text];\n}\n","import { useState, useEffect } from \"react\";\nimport { useNavigate, useSearchParams } from \"react-router-dom\";\nimport { useTranslation } from \"react-i18next\";\nimport { useAuth } from \"@/contexts/auth-context\";\nimport { api, ApiError } from \"@/api/client\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\n\nexport default function LoginPage() {\n const navigate = useNavigate();\n const [searchParams] = useSearchParams();\n const { user, login, register } = useAuth();\n const { t } = useTranslation();\n const inviteToken = searchParams.get(\"invite\") || \"\";\n\n const [mode, setMode] = useState<\"login\" | \"register\">(inviteToken ? \"register\" : \"login\");\n const [registrationOpen, setRegistrationOpen] = useState(false);\n // first run = no users yet (next registrant becomes admin); distinct from\n // public signup (admin enabled open self-registration as viewer).\n const [firstRun, setFirstRun] = useState(false);\n const [oauthProviders, setOauthProviders] = useState<string[]>([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState(\"\");\n\n const [email, setEmail] = useState(\"\");\n const [fullName, setFullName] = useState(\"\");\n const [password, setPassword] = useState(\"\");\n const [confirmPassword, setConfirmPassword] = useState(\"\");\n // Keep the login page accessible during demo mode so admins can still sign in.\n useEffect(() => {\n if (user && user.role !== \"public_manager\") {\n navigate(\"/\", { replace: true });\n }\n }, [user, navigate]);\n\n // Check if registration is open (first-run)\n useEffect(() => {\n api.authSetupStatus()\n .then((s) => {\n setRegistrationOpen(s.registration_open);\n setFirstRun(s.first_run);\n setOauthProviders(s.oauth_providers ?? []);\n // Force register only on first run; under public signup keep login the\n // default (existing users sign in) while still allowing registration.\n if (s.first_run) setMode(\"register\");\n })\n .catch(() => {})\n .finally(() => setLoading(false));\n }, []);\n\n // Surface an OAuth failure the backend redirected back with (?oauth_error=…).\n useEffect(() => {\n const code = searchParams.get(\"oauth_error\");\n if (code) setError(t(`login.oauthError.${code}`, { defaultValue: t(\"login.oauthError.generic\") }));\n }, [searchParams, t]);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(\"\");\n\n if (mode === \"register\") {\n if (password !== confirmPassword) {\n setError(t(\"login.passwordsNoMatch\"));\n return;\n }\n if (password.length < 6) {\n setError(t(\"login.passwordTooShort\"));\n return;\n }\n try {\n await register(email, fullName, password, inviteToken || undefined);\n navigate(\"/\", { replace: true });\n } catch (err) {\n setError(err instanceof ApiError ? err.message : t(\"login.registrationFailed\"));\n }\n } else {\n try {\n await login(email, password);\n navigate(\"/\", { replace: true });\n } catch (err) {\n setError(err instanceof ApiError ? err.message : t(\"login.loginFailed\"));\n }\n }\n };\n\n if (loading) {\n return (\n <div className=\"flex h-dvh items-center justify-center bg-surface-muted\">\n <div className=\"text-fg-muted\">{t(\"common.loading\")}</div>\n </div>\n );\n }\n\n return (\n <div className=\"flex min-h-dvh items-center justify-center bg-surface-muted px-4\">\n <div className=\"w-full max-w-sm space-y-6\">\n <div className=\"text-center\">\n <h1 className=\"text-2xl font-bold text-brand\">Lambda ERP</h1>\n <p className=\"mt-1 text-sm text-fg-muted\">\n {firstRun\n ? t(\"login.taglineFirstRun\")\n : mode === \"register\"\n ? t(\"login.taglineRegister\")\n : t(\"login.taglineSignIn\")}\n </p>\n {user?.role === \"public_manager\" && (\n <p className=\"mt-2 text-xs text-amber-700\">\n {t(\"login.demoBanner\")}\n </p>\n )}\n </div>\n\n {error && (\n <div className=\"rounded-lg bg-rose-50 px-4 py-3 text-sm text-rose-700 ring-1 ring-rose-200\">\n {error}\n </div>\n )}\n\n <Card>\n <form onSubmit={handleSubmit} className=\"space-y-4\">\n {mode === \"register\" && (\n <Input\n label={t(\"login.fullName\")}\n value={fullName}\n onChange={(e) => setFullName(e.target.value)}\n required\n />\n )}\n <Input\n label={t(\"login.email\")}\n type=\"email\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n required\n />\n <Input\n label={t(\"login.password\")}\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n required\n />\n {mode === \"register\" && (\n <Input\n label={t(\"login.confirmPassword\")}\n type=\"password\"\n value={confirmPassword}\n onChange={(e) => setConfirmPassword(e.target.value)}\n required\n />\n )}\n <Button type=\"submit\" className=\"w-full\">\n {mode === \"register\" ? (firstRun ? t(\"login.createAdmin\") : t(\"login.register\")) : t(\"login.signIn\")}\n </Button>\n </form>\n\n {oauthProviders.length > 0 && (\n <div className=\"mt-4 space-y-3\">\n <div className=\"flex items-center gap-3\">\n <div className=\"h-px flex-1 bg-border\" />\n <span className=\"text-xs uppercase tracking-wide text-fg-muted\">{t(\"login.orContinueWith\")}</span>\n <div className=\"h-px flex-1 bg-border\" />\n </div>\n <div className=\"space-y-2\">\n {oauthProviders.map((p) => (\n <button\n key={p}\n type=\"button\"\n onClick={() => { window.location.href = api.oauthLoginUrl(p, { invite: inviteToken || undefined }); }}\n className=\"flex w-full items-center justify-center gap-2 rounded-lg border border-border bg-surface px-4 py-2 text-sm font-medium text-fg transition-colors hover:bg-surface-muted\"\n >\n <ProviderIcon provider={p} />\n {t(\"login.continueWithProvider\", { provider: providerLabel(p) })}\n </button>\n ))}\n </div>\n </div>\n )}\n </Card>\n\n {user?.role === \"public_manager\" && (\n <Card>\n <div className=\"space-y-3\">\n <div>\n <h2 className=\"text-sm font-semibold text-fg\">{t(\"login.browsingTitle\")}</h2>\n <p className=\"mt-1 text-sm text-fg-muted\">\n {t(\"login.browsingBody\")}\n </p>\n </div>\n <Button\n type=\"button\"\n className=\"w-full\"\n onClick={() => navigate(\"/demo\", { replace: true })}\n >\n {t(\"login.enterDemo\")}\n </Button>\n </div>\n </Card>\n )}\n\n {/* Only offer registration when it's actually open (first-run or public\n signup). When the instance is invite-only, there is no signup screen:\n invited users arrive via the invite link (which forces register mode)\n and can then set a password or continue with Google. */}\n {!firstRun && !inviteToken && registrationOpen && (\n <p className=\"text-center text-sm text-fg-muted\">\n {mode === \"login\" ? (\n <>\n {t(\"login.noAccountPrompt\")}{\" \"}\n <button onClick={() => setMode(\"register\")} className=\"font-medium text-brand transition-colors hover:text-brand/80\">\n {t(\"login.registerLink\")}\n </button>\n </>\n ) : (\n <>\n {t(\"login.alreadyHaveAccount\")}{\" \"}\n <button onClick={() => setMode(\"login\")} className=\"font-medium text-brand transition-colors hover:text-brand/80\">\n {t(\"login.signInLink\")}\n </button>\n </>\n )}\n </p>\n )}\n </div>\n </div>\n );\n}\n\nfunction providerLabel(provider: string): string {\n return provider.charAt(0).toUpperCase() + provider.slice(1);\n}\n\nfunction ProviderIcon({ provider }: { provider: string }) {\n if (provider === \"google\") {\n return (\n <svg className=\"h-4 w-4\" viewBox=\"0 0 48 48\" aria-hidden=\"true\">\n <path fill=\"#EA4335\" d=\"M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z\" />\n <path fill=\"#4285F4\" d=\"M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z\" />\n <path fill=\"#FBBC05\" d=\"M10.53 28.59c-.48-1.45-.76-2.99-.76-4.59s.27-3.14.76-4.59l-7.98-6.19C.92 16.46 0 20.12 0 24c0 3.88.92 7.54 2.56 10.78l7.97-6.19z\" />\n <path fill=\"#34A853\" d=\"M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z\" />\n </svg>\n );\n }\n if (provider === \"apple\") {\n return (\n <svg className=\"h-4 w-4\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M16.365 1.43c0 1.14-.42 2.22-1.14 3.03-.78.9-2.06 1.6-3.12 1.5-.13-1.1.42-2.28 1.08-3.03.78-.9 2.13-1.56 3.18-1.5zM20.7 17.1c-.56 1.3-.83 1.88-1.55 3.03-1 1.6-2.42 3.6-4.18 3.62-1.56.02-1.96-1.02-4.07-1-2.12.01-2.56 1.02-4.12 1.01-1.76-.02-3.1-1.82-4.1-3.42C-.3 16.9-.6 11.16 1.7 8.1c1.16-1.54 3-2.51 4.85-2.51 1.87 0 3.05 1.02 4.6 1.02 1.5 0 2.42-1.02 4.6-1.02 1.62 0 3.34.88 4.56 2.4-4.01 2.2-3.36 7.92 0 9.11z\" />\n </svg>\n );\n }\n return null;\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { useNavigate } from \"react-router-dom\";\nimport { api, ApiError } from \"@/api/client\";\n\n/**\n * Shareable entry point that mirrors the \"Enter Live Demo\" button on /login.\n * Creates a fresh chat session (as the public_manager fallback user if the\n * visitor has no cookie) and redirects to /chat/{id}?demo=1 for replay.\n */\nexport default function DemoPage() {\n const navigate = useNavigate();\n const startedRef = useRef(false);\n const [error, setError] = useState<string>(\"\");\n\n useEffect(() => {\n // StrictMode double-mounts the effect. A `let cancelled` flag flipped in\n // cleanup would still be `true` when the (single) fetch resolves on the\n // second mount — the promise closure captures the first mount's variable.\n // Guard duplicate kickoffs with a ref and drop the cancelled flag entirely.\n if (startedRef.current) return;\n startedRef.current = true;\n\n api.createChatSession()\n .then((session) => {\n navigate(`/chat/${session.id}?demo=1`, { replace: true });\n })\n .catch((err) => {\n setError(err instanceof ApiError ? err.message : \"Could not start demo\");\n });\n }, [navigate]);\n\n return (\n <div className=\"flex min-h-dvh items-center justify-center bg-surface-muted px-4\">\n <div className=\"text-center\">\n {error ? (\n <>\n <p className=\"text-sm text-rose-600\">{error}</p>\n <button\n onClick={() => navigate(\"/login\", { replace: true })}\n className=\"mt-4 text-sm text-brand transition-colors hover:text-brand/80\"\n >\n Back to login\n </button>\n </>\n ) : (\n <div className=\"space-y-3\">\n <div className=\"mx-auto h-2 w-2 animate-pulse rounded-full bg-brand\" />\n <p className=\"text-sm text-fg-muted\">Starting live demo...</p>\n </div>\n )}\n </div>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { useNavigate } from \"react-router-dom\";\nimport { api } from \"@/api/client\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Select } from \"@/components/ui/select\";\nimport { Button } from \"@/components/ui/button\";\nimport { LinkField } from \"@/components/document/link-field\";\n\ninterface AccountRow { account: string; debit: string; credit: string; party_type: string; party: string }\ninterface StockRow { item_code: string; qty: string; rate: string }\ninterface InvoiceRow { type: string; party: string; amount: string; due_date: string; remarks: string }\n\nfunction emptyAccountRow(): AccountRow { return { account: \"\", debit: \"\", credit: \"\", party_type: \"\", party: \"\" }; }\nfunction emptyStockRow(): StockRow { return { item_code: \"\", qty: \"\", rate: \"\" }; }\nfunction emptyInvoiceRow(): InvoiceRow { return { type: \"sales\", party: \"\", amount: \"\", due_date: \"\", remarks: \"\" }; }\n\nexport default function OpeningBalancesPage() {\n const navigate = useNavigate();\n const queryClient = useQueryClient();\n const [company, setCompany] = useState(\"\");\n const [postingDate, setPostingDate] = useState(new Date().toISOString().split(\"T\")[0]);\n const [warehouse, setWarehouse] = useState(\"\");\n\n const [accountRows, setAccountRows] = useState<AccountRow[]>([emptyAccountRow()]);\n const [stockRows, setStockRows] = useState<StockRow[]>([emptyStockRow()]);\n const [invoiceRows, setInvoiceRows] = useState<InvoiceRow[]>([emptyInvoiceRow()]);\n\n const [results, setResults] = useState<Record<string, any>>({});\n\n const accountMut = useMutation({\n mutationFn: () => api.importAccountBalances({\n company,\n posting_date: postingDate,\n entries: accountRows.filter(r => r.account && (r.debit || r.credit)).map(r => ({\n account: r.account, debit: parseFloat(r.debit) || 0, credit: parseFloat(r.credit) || 0,\n party_type: r.party_type || undefined, party: r.party || undefined,\n })),\n }),\n onSuccess: (d) => setResults(prev => ({ ...prev, accounts: d })),\n });\n\n const stockMut = useMutation({\n mutationFn: () => api.importStockBalances({\n company,\n posting_date: postingDate,\n warehouse,\n items: stockRows.filter(r => r.item_code && r.qty).map(r => ({\n item_code: r.item_code, qty: parseFloat(r.qty) || 0, rate: parseFloat(r.rate) || 0,\n })),\n }),\n onSuccess: (d) => setResults(prev => ({ ...prev, stock: d })),\n });\n\n const invoiceMut = useMutation({\n mutationFn: () => api.importOutstandingInvoices({\n company,\n invoices: invoiceRows.filter(r => r.party && r.amount).map(r => ({\n type: r.type, party: r.party, amount: parseFloat(r.amount) || 0,\n due_date: r.due_date || undefined, remarks: r.remarks || undefined, posting_date: postingDate,\n })),\n }),\n onSuccess: (d) => setResults(prev => ({ ...prev, invoices: d })),\n });\n\n function updateRow<T>(rows: T[], setRows: (r: T[]) => void, idx: number, field: string, value: string) {\n const updated = [...rows];\n (updated[idx] as any)[field] = value;\n setRows(updated);\n }\n\n return (\n <div className=\"space-y-6\">\n <p className=\"text-sm text-gray-500\">\n Import balances from your previous system. Each section creates the appropriate documents\n (Journal Entry, Stock Entry, or Invoices) and submits them automatically.\n </p>\n\n <Card title=\"Common Settings\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <LinkField label=\"Company\" value={company} onChange={setCompany} linkDoctype=\"company\" readOnly={false} />\n <Input label=\"As-of Date\" type=\"date\" value={postingDate} onChange={e => setPostingDate(e.target.value)} />\n </div>\n </Card>\n\n {/* Account Balances */}\n <Card title=\"1. Account Balances\">\n <p className=\"mb-3 text-xs text-gray-500\">\n Enter your trial balance from the old system. The difference will be automatically balanced against Opening Balance Equity.\n For receivable/payable accounts, also set the party type and party.\n </p>\n <div>\n <table className=\"min-w-full text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-2 py-2 text-left font-medium text-gray-500\">Account</th>\n <th className=\"px-2 py-2 text-left font-medium text-gray-500\">Party Type</th>\n <th className=\"px-2 py-2 text-left font-medium text-gray-500\">Party</th>\n <th className=\"px-2 py-2 text-right font-medium text-gray-500\">Debit</th>\n <th className=\"px-2 py-2 text-right font-medium text-gray-500\">Credit</th>\n </tr>\n </thead>\n <tbody>\n {accountRows.map((row, i) => (\n <tr key={i}>\n <td className=\"px-2 py-1\">\n <LinkField value={row.account} onChange={v => updateRow(accountRows, setAccountRows, i, \"account\", v)} linkDoctype=\"account\" readOnly={false} label=\"\" />\n </td>\n <td className=\"px-2 py-1\">\n <select value={row.party_type} onChange={e => updateRow(accountRows, setAccountRows, i, \"party_type\", e.target.value)} className=\"w-full rounded border border-gray-300 px-2 py-1.5 text-sm\">\n <option value=\"\">—</option>\n <option value=\"Customer\">Customer</option>\n <option value=\"Supplier\">Supplier</option>\n </select>\n </td>\n <td className=\"px-2 py-1\">\n {row.party_type ? (\n <LinkField label=\"\" value={row.party} onChange={v => updateRow(accountRows, setAccountRows, i, \"party\", v)} linkDoctype={row.party_type.toLowerCase()} readOnly={false} />\n ) : <span className=\"text-gray-300 text-xs\">set party type first</span>}\n </td>\n <td className=\"px-2 py-1\"><input type=\"number\" value={row.debit} onChange={e => updateRow(accountRows, setAccountRows, i, \"debit\", e.target.value)} className=\"w-24 rounded border border-gray-300 px-2 py-1.5 text-right text-sm\" placeholder=\"0.00\" /></td>\n <td className=\"px-2 py-1\"><input type=\"number\" value={row.credit} onChange={e => updateRow(accountRows, setAccountRows, i, \"credit\", e.target.value)} className=\"w-24 rounded border border-gray-300 px-2 py-1.5 text-right text-sm\" placeholder=\"0.00\" /></td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <div className=\"mt-2 flex gap-2\">\n <button onClick={() => setAccountRows([...accountRows, emptyAccountRow()])} className=\"text-xs text-blue-600 hover:text-blue-800\">+ Add Row</button>\n </div>\n <div className=\"mt-3 flex items-center gap-3\">\n <Button onClick={() => accountMut.mutate()} disabled={!company || accountMut.isPending}>\n {accountMut.isPending ? \"Importing...\" : \"Import Account Balances\"}\n </Button>\n {accountMut.error && <span className=\"text-xs text-red-600\">{(accountMut.error as Error).message}</span>}\n {results.accounts && <span className=\"text-xs text-green-600\">Created {results.accounts.journal_entry}</span>}\n </div>\n </Card>\n\n {/* Stock Balances */}\n <Card title=\"2. Stock Balances\">\n <p className=\"mb-3 text-xs text-gray-500\">\n Enter your current inventory. Creates a Stock Entry (Opening Stock) — posts Dr Stock In Hand / Cr Opening Balance Equity so the P&L isn't distorted by day-one inventory.\n </p>\n <div className=\"mb-3\">\n <LinkField label=\"Warehouse\" value={warehouse} onChange={setWarehouse} linkDoctype=\"warehouse\" readOnly={false} />\n </div>\n <div>\n <table className=\"min-w-full text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-2 py-2 text-left font-medium text-gray-500\">Item</th>\n <th className=\"px-2 py-2 text-right font-medium text-gray-500\">Qty</th>\n <th className=\"px-2 py-2 text-right font-medium text-gray-500\">Rate</th>\n </tr>\n </thead>\n <tbody>\n {stockRows.map((row, i) => (\n <tr key={i}>\n <td className=\"px-2 py-1\"><LinkField label=\"\" value={row.item_code} onChange={v => updateRow(stockRows, setStockRows, i, \"item_code\", v)} linkDoctype=\"item\" readOnly={false} /></td>\n <td className=\"px-2 py-1\"><input type=\"number\" value={row.qty} onChange={e => updateRow(stockRows, setStockRows, i, \"qty\", e.target.value)} className=\"w-24 rounded border border-gray-300 px-2 py-1.5 text-right text-sm\" placeholder=\"0\" /></td>\n <td className=\"px-2 py-1\"><input type=\"number\" value={row.rate} onChange={e => updateRow(stockRows, setStockRows, i, \"rate\", e.target.value)} className=\"w-24 rounded border border-gray-300 px-2 py-1.5 text-right text-sm\" placeholder=\"0.00\" /></td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <div className=\"mt-2\">\n <button onClick={() => setStockRows([...stockRows, emptyStockRow()])} className=\"text-xs text-blue-600 hover:text-blue-800\">+ Add Row</button>\n </div>\n <div className=\"mt-3 flex items-center gap-3\">\n <Button onClick={() => stockMut.mutate()} disabled={!company || !warehouse || stockMut.isPending}>\n {stockMut.isPending ? \"Importing...\" : \"Import Stock Balances\"}\n </Button>\n {stockMut.error && <span className=\"text-xs text-red-600\">{(stockMut.error as Error).message}</span>}\n {results.stock && <span className=\"text-xs text-green-600\">Created {results.stock.stock_entry} ({results.stock.items_count} items)</span>}\n </div>\n </Card>\n\n {/* Outstanding Invoices */}\n <Card title=\"3. Outstanding Invoices\">\n <p className=\"mb-3 text-xs text-gray-500\">\n Enter unpaid invoices from your old system. Creates submitted Sales or Purchase Invoices with the correct outstanding amounts for AR/AP aging.\n </p>\n <div>\n <table className=\"min-w-full text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-2 py-2 text-left font-medium text-gray-500\">Type</th>\n <th className=\"px-2 py-2 text-left font-medium text-gray-500\">Customer / Supplier</th>\n <th className=\"px-2 py-2 text-right font-medium text-gray-500\">Amount</th>\n <th className=\"px-2 py-2 text-left font-medium text-gray-500\">Due Date</th>\n <th className=\"px-2 py-2 text-left font-medium text-gray-500\">Ref / Remarks</th>\n </tr>\n </thead>\n <tbody>\n {invoiceRows.map((row, i) => (\n <tr key={i}>\n <td className=\"px-2 py-1\">\n <select value={row.type} onChange={e => updateRow(invoiceRows, setInvoiceRows, i, \"type\", e.target.value)} className=\"rounded border border-gray-300 px-2 py-1.5 text-sm\">\n <option value=\"sales\">Sales (AR)</option>\n <option value=\"purchase\">Purchase (AP)</option>\n </select>\n </td>\n <td className=\"px-2 py-1\">\n <LinkField\n label=\"\"\n value={row.party}\n onChange={v => updateRow(invoiceRows, setInvoiceRows, i, \"party\", v)}\n linkDoctype={row.type === \"sales\" ? \"customer\" : \"supplier\"}\n readOnly={false}\n />\n </td>\n <td className=\"px-2 py-1\"><input type=\"number\" value={row.amount} onChange={e => updateRow(invoiceRows, setInvoiceRows, i, \"amount\", e.target.value)} className=\"w-28 rounded border border-gray-300 px-2 py-1.5 text-right text-sm\" placeholder=\"0.00\" /></td>\n <td className=\"px-2 py-1\"><input type=\"date\" value={row.due_date} onChange={e => updateRow(invoiceRows, setInvoiceRows, i, \"due_date\", e.target.value)} className=\"rounded border border-gray-300 px-2 py-1.5 text-sm\" /></td>\n <td className=\"px-2 py-1\"><input type=\"text\" value={row.remarks} onChange={e => updateRow(invoiceRows, setInvoiceRows, i, \"remarks\", e.target.value)} className=\"w-full rounded border border-gray-300 px-2 py-1.5 text-sm\" placeholder=\"Old invoice ref\" /></td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n <div className=\"mt-2\">\n <button onClick={() => setInvoiceRows([...invoiceRows, emptyInvoiceRow()])} className=\"text-xs text-blue-600 hover:text-blue-800\">+ Add Row</button>\n </div>\n <div className=\"mt-3 flex items-center gap-3\">\n <Button onClick={() => invoiceMut.mutate()} disabled={!company || invoiceMut.isPending}>\n {invoiceMut.isPending ? \"Importing...\" : \"Import Outstanding Invoices\"}\n </Button>\n {invoiceMut.error && <span className=\"text-xs text-red-600\">{(invoiceMut.error as Error).message}</span>}\n {results.invoices && <span className=\"text-xs text-green-600\">Created {results.invoices.invoices_created} invoices</span>}\n </div>\n </Card>\n\n {/* Finish */}\n <div className=\"rounded-lg border border-gray-200 bg-gray-50 p-6 text-center\">\n <p className=\"text-sm text-gray-600\">\n Done importing? You can disable this page and re-enable it later under Settings > General.\n </p>\n <button\n onClick={async () => {\n await api.updateSettings({ opening_balances_enabled: \"0\" });\n queryClient.invalidateQueries({ queryKey: [\"settings\"] });\n navigate(\"/\");\n }}\n className=\"mt-3 rounded-lg bg-gray-900 px-5 py-2 text-sm font-medium text-white hover:bg-gray-800\"\n >\n Finish and Disable Opening Balances\n </button>\n </div>\n </div>\n );\n}\n","import { useState } from \"react\";\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { api } from \"@/api/client\";\nimport { useAuth } from \"@/contexts/auth-context\";\nimport { Card } from \"@/components/ui/card\";\nimport { Input } from \"@/components/ui/input\";\nimport { Select } from \"@/components/ui/select\";\nimport { Button } from \"@/components/ui/button\";\nimport { usePrompt } from \"@/components/ui/dialog\";\n\nexport default function UsersPage() {\n const { user: currentUser } = useAuth();\n const queryClient = useQueryClient();\n\n const { data: users, isLoading } = useQuery({\n queryKey: [\"auth-users\"],\n queryFn: () => api.authListUsers(),\n });\n\n const { data: invites } = useQuery({\n queryKey: [\"auth-invites\"],\n queryFn: () => api.authListInvites(),\n });\n\n const [inviteEmail, setInviteEmail] = useState(\"\");\n const [inviteRole, setInviteRole] = useState(\"viewer\");\n const [inviteResult, setInviteResult] = useState<{ link: string } | null>(null);\n\n const inviteMut = useMutation({\n mutationFn: () => api.authInvite(inviteEmail, inviteRole),\n onSuccess: (result) => {\n setInviteResult(result);\n setInviteEmail(\"\");\n queryClient.invalidateQueries({ queryKey: [\"auth-invites\"] });\n },\n });\n\n const changeRoleMut = useMutation({\n mutationFn: ({ name, role }: { name: string; role: string }) => api.authChangeRole(name, role),\n onSuccess: () => queryClient.invalidateQueries({ queryKey: [\"auth-users\"] }),\n });\n\n const disableMut = useMutation({\n mutationFn: (name: string) => api.authDisableUser(name),\n onSuccess: () => queryClient.invalidateQueries({ queryKey: [\"auth-users\"] }),\n });\n\n const revokeMut = useMutation({\n mutationFn: (token: string) => api.authRevokeInvite(token),\n onSuccess: () => queryClient.invalidateQueries({ queryKey: [\"auth-invites\"] }),\n });\n\n const [copiedToken, setCopiedToken] = useState<string | null>(null);\n const prompt = usePrompt();\n const inviteLink = (token: string) => `${window.location.origin}/login?invite=${token}`;\n const copyInviteLink = async (token: string) => {\n try {\n await navigator.clipboard.writeText(inviteLink(token));\n setCopiedToken(token);\n setTimeout(() => setCopiedToken((t) => (t === token ? null : t)), 2000);\n } catch {\n // Clipboard API unavailable (e.g. non-HTTPS): show the link in a dialog\n // (a selectable field) so the admin can still copy it manually.\n void prompt({ title: \"Invite link\", body: \"Copy this link:\", defaultValue: inviteLink(token) });\n }\n };\n\n if (currentUser?.role !== \"admin\") {\n return <p className=\"py-8 text-center text-gray-400\">Admin access required</p>;\n }\n\n return (\n <div className=\"space-y-6\">\n {/* Role explanation */}\n <Card title=\"Roles\">\n <div className=\"grid gap-3 text-sm sm:grid-cols-3\">\n <div className=\"rounded-lg border border-blue-200 bg-blue-50 p-3\">\n <div className=\"font-semibold text-blue-900\">Admin</div>\n <p className=\"mt-1 text-blue-700\">\n Full access. Can create and manage documents, masters, company setup, and users. Can invite team members and change roles.\n </p>\n </div>\n <div className=\"rounded-lg border border-amber-200 bg-amber-50 p-3\">\n <div className=\"font-semibold text-amber-900\">Manager</div>\n <p className=\"mt-1 text-amber-700\">\n Can create, edit, submit, and cancel documents. Can create and edit master data. Can run reports and use the AI chat. Cannot manage users or company setup.\n </p>\n </div>\n <div className=\"rounded-lg border border-gray-200 bg-gray-50 p-3\">\n <div className=\"font-semibold text-gray-900\">Viewer</div>\n <p className=\"mt-1 text-gray-600\">\n Read-only access to all documents, masters, and reports. Can use the AI chat. Cannot create or modify any data.\n </p>\n </div>\n </div>\n </Card>\n\n {/* Invite form */}\n <Card title=\"Invite User\">\n <div className=\"flex flex-wrap items-end gap-4\">\n <Input\n label=\"Email\"\n type=\"email\"\n value={inviteEmail}\n onChange={(e) => setInviteEmail(e.target.value)}\n placeholder=\"colleague@company.com\"\n />\n <Select\n label=\"Role\"\n options={[\"viewer\", \"manager\", \"admin\"]}\n value={inviteRole}\n onChange={(e) => setInviteRole(e.target.value)}\n />\n <Button\n onClick={() => inviteMut.mutate()}\n disabled={!inviteEmail.trim() || inviteMut.isPending}\n >\n {inviteMut.isPending ? \"Sending...\" : \"Create Invite\"}\n </Button>\n </div>\n {inviteMut.error && (\n <p className=\"mt-2 text-sm text-red-600\">{(inviteMut.error as Error).message}</p>\n )}\n {inviteResult && (\n <div className=\"mt-3 rounded-md bg-green-50 px-4 py-3 text-sm\">\n <p className=\"font-medium text-green-800\">Invite created!</p>\n <p className=\"mt-1 text-green-700\">\n Share this link:{\" \"}\n <code className=\"rounded bg-green-100 px-2 py-0.5 text-xs font-mono\">\n {window.location.origin}{inviteResult.link}\n </code>\n </p>\n </div>\n )}\n </Card>\n\n {/* Pending invites */}\n {invites && invites.filter((i: any) => !i.used).length > 0 && (\n <Card title=\"Pending Invites\">\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-4 py-2 text-left font-medium text-gray-500\">Email</th>\n <th className=\"px-4 py-2 text-left font-medium text-gray-500\">Role</th>\n <th className=\"px-4 py-2 text-left font-medium text-gray-500\">Created</th>\n <th className=\"px-4 py-2 text-right font-medium text-gray-500\">Actions</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {invites.filter((i: any) => !i.used).map((invite: any) => (\n <tr key={invite.token}>\n <td className=\"px-4 py-2\">{invite.email}</td>\n <td className=\"px-4 py-2\">\n <span className=\"rounded bg-gray-100 px-2 py-0.5 text-xs font-medium\">{invite.role}</span>\n </td>\n <td className=\"px-4 py-2 text-gray-500\">{invite.creation?.split(\"T\")[0]}</td>\n <td className=\"px-4 py-2 text-right\">\n <div className=\"flex items-center justify-end gap-2\">\n <Button\n variant=\"secondary\"\n size=\"sm\"\n onClick={() => copyInviteLink(invite.token)}\n >\n {copiedToken === invite.token ? \"Copied!\" : \"Copy link\"}\n </Button>\n <Button\n variant=\"danger\"\n size=\"sm\"\n onClick={() => revokeMut.mutate(invite.token)}\n disabled={revokeMut.isPending}\n >\n Revoke\n </Button>\n </div>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </Card>\n )}\n\n {/* User list */}\n <Card title=\"Team Members\">\n {isLoading ? (\n <p className=\"text-gray-500\">Loading...</p>\n ) : (\n <table className=\"min-w-full divide-y divide-gray-200 text-sm\">\n <thead className=\"bg-gray-50\">\n <tr>\n <th className=\"px-4 py-2 text-left font-medium text-gray-500\">Name</th>\n <th className=\"px-4 py-2 text-left font-medium text-gray-500\">Email</th>\n <th className=\"px-4 py-2 text-left font-medium text-gray-500\">Role</th>\n <th className=\"px-4 py-2 text-left font-medium text-gray-500\">Status</th>\n <th className=\"px-4 py-2 text-right font-medium text-gray-500\">Actions</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {(users || []).map((u: any) => (\n <tr key={u.name} className=\"hover:bg-gray-50\">\n <td className=\"px-4 py-2 font-medium text-gray-900\">{u.full_name}</td>\n <td className=\"px-4 py-2 text-gray-600\">{u.email}</td>\n <td className=\"px-4 py-2\">\n {u.role === \"public_manager\" ? (\n <span className=\"rounded bg-amber-100 px-2 py-0.5 text-xs font-medium text-amber-800\">\n public_manager (system)\n </span>\n ) : (\n <select\n value={u.role}\n onChange={(e) => changeRoleMut.mutate({ name: u.name, role: e.target.value })}\n disabled={u.name === currentUser?.name}\n className={`rounded border px-2 py-1 text-xs ${u.name === currentUser?.name ? \"border-gray-200 bg-gray-50 text-gray-400\" : \"border-gray-300 bg-white text-gray-900\"}`}\n >\n <option value=\"viewer\">viewer</option>\n <option value=\"manager\">manager</option>\n <option value=\"admin\">admin</option>\n </select>\n )}\n </td>\n <td className=\"px-4 py-2\">\n <span className={`rounded px-2 py-0.5 text-xs font-medium ${u.enabled ? \"bg-green-100 text-green-800\" : \"bg-red-100 text-red-800\"}`}>\n {u.enabled ? \"Active\" : \"Disabled\"}\n </span>\n </td>\n <td className=\"px-4 py-2 text-right\">\n {u.name !== currentUser?.name && u.enabled ? (\n <button\n onClick={() => disableMut.mutate(u.name)}\n className=\"text-xs text-red-500 hover:text-red-700\"\n >\n Disable\n </button>\n ) : null}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n )}\n </Card>\n\n </div>\n );\n}\n","import i18n from \"i18next\";\nimport { initReactI18next } from \"react-i18next\";\n\nimport en from \"./locales/en.json\";\nimport de from \"./locales/de.json\";\nimport fr from \"./locales/fr.json\";\n\n/** The languages the UI offers. `code` is what we persist + pass to i18next. */\nexport const SUPPORTED_LANGUAGES = [\n { code: \"en\", label: \"English\" },\n { code: \"de\", label: \"Deutsch\" },\n { code: \"fr\", label: \"Français\" },\n] as const;\n\nexport type LanguageCode = (typeof SUPPORTED_LANGUAGES)[number][\"code\"];\n\n// Namespaced like the app's other localStorage prefs (sidebar-collapsed,\n// lambda-erp:known-chat-sessions). Read/written with try/catch so quota or\n// private-mode errors never break rendering.\nconst STORAGE_KEY = \"lambda-erp:language\";\n\nfunction isSupported(code: string | null): code is LanguageCode {\n return !!code && SUPPORTED_LANGUAGES.some((l) => l.code === code);\n}\n\nexport function getStoredLanguage(): LanguageCode {\n try {\n const v = localStorage.getItem(STORAGE_KEY);\n if (isSupported(v)) return v;\n } catch {\n // ignore (private mode / unavailable storage)\n }\n return \"en\";\n}\n\nfunction storeLanguage(code: string) {\n try {\n localStorage.setItem(STORAGE_KEY, code);\n } catch {\n // ignore storage errors (quota / private mode)\n }\n}\n\ni18n.use(initReactI18next).init({\n resources: {\n en: { translation: en },\n de: { translation: de },\n fr: { translation: fr },\n },\n lng: getStoredLanguage(),\n fallbackLng: \"en\", // any key missing in de/fr falls back to the English value\n interpolation: { escapeValue: false }, // React already escapes\n react: { useSuspense: false }, // resources are bundled synchronously — no Suspense needed\n});\n\n// Persist on every change, including programmatic changeLanguage() calls.\ni18n.on(\"languageChanged\", storeLanguage);\n\nexport default i18n;\n","import { useTranslation } from \"react-i18next\";\nimport { Select } from \"@/components/ui/select\";\nimport { SUPPORTED_LANGUAGES } from \"@/i18n\";\n\n/**\n * Language dropdown. Reads the active language from i18next and switches it on\n * change; the i18n layer persists the choice to localStorage. `label` defaults\n * to the translated \"Language\" string but can be suppressed (e.g. in a header).\n */\nexport function LanguageSelect({ label }: { label?: string | null }) {\n const { t, i18n } = useTranslation();\n // i18n.language can carry a region suffix (e.g. \"en-US\"); match on the base.\n const current = i18n.language?.split(\"-\")[0] ?? \"en\";\n\n return (\n <Select\n label={label === null ? undefined : label ?? t(\"language.label\")}\n options={SUPPORTED_LANGUAGES.map((l) => ({ value: l.code, label: l.label }))}\n value={current}\n onChange={(e) => i18n.changeLanguage(e.target.value)}\n />\n );\n}\n","import { useState, useMemo } from \"react\";\nimport { useQuery, useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { useTranslation } from \"react-i18next\";\nimport { api, ApiError } from \"@/api/client\";\nimport { useAuth } from \"@/contexts/auth-context\";\nimport { Card } from \"@/components/ui/card\";\nimport { Select } from \"@/components/ui/select\";\nimport { Input } from \"@/components/ui/input\";\nimport { Button } from \"@/components/ui/button\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { LanguageSelect } from \"@/components/ui/language-select\";\n\n// Map window keys (as returned by /admin/demo-spend) to seconds so we can\n// normalize spend to $/hour for cross-window comparison.\nconst DEMO_SPEND_WINDOWS: Array<{ value: string; label: string; hours: number }> = [\n { value: \"1h\", label: \"Last 1 hour\", hours: 1 },\n { value: \"2h\", label: \"Last 2 hours\", hours: 2 },\n { value: \"4h\", label: \"Last 4 hours\", hours: 4 },\n { value: \"12h\", label: \"Last 12 hours\", hours: 12 },\n { value: \"24h\", label: \"Last 24 hours\", hours: 24 },\n { value: \"7d\", label: \"Last 7 days\", hours: 24 * 7 },\n];\n\nfunction fmtUsd(v: number): string {\n if (v === 0) return \"$0.00\";\n if (v < 0.01) return `$${v.toFixed(4)}`;\n return `$${v.toFixed(2)}`;\n}\n\nfunction TokenSpendCard({ demoActive }: { demoActive: boolean }) {\n const { t } = useTranslation();\n const [windowKey, setWindowKey] = useState<string>(\"1h\");\n const { data, isLoading, isFetching, error, refetch, dataUpdatedAt } = useQuery({\n queryKey: [\"demo-spend\"],\n queryFn: () => api.getDemoSpend(),\n // Refresh once a minute — demo spend changes slowly; no need to poll harder.\n refetchInterval: 60_000,\n });\n\n const windowSpec = DEMO_SPEND_WINDOWS.find((w) => w.value === windowKey)!;\n const window = data?.windows?.[windowKey];\n const demoCap = data?.caps?.global_hourly_usd ?? 0;\n // Average hourly demo spend over the selected range. This is the number that\n // matters for the cap (which is defined as $/hr), so normalizing by window\n // length lets the admin compare any range against the same threshold.\n const demoUsdPerHour = window ? window.demo_usd / windowSpec.hours : 0;\n const totalUsdPerHour = window ? window.total_usd / windowSpec.hours : 0;\n const capPct = demoCap > 0 ? Math.min(100, (demoUsdPerHour / demoCap) * 100) : 0;\n const capColor =\n capPct >= 90 ? \"bg-red-500\" : capPct >= 60 ? \"bg-amber-500\" : \"bg-emerald-500\";\n\n return (\n <Card title={t(\"settings.tokenSpendTitle\")}>\n <div className=\"flex flex-wrap items-end justify-between gap-4\">\n <div className=\"max-w-lg text-sm text-gray-600\">\n Cost and token usage from AI / LLM calls in this deployment, across\n all providers.\n {demoActive && (\n <>\n {\" \"}Only{\" \"}\n <span className=\"font-medium text-gray-900\">public_manager</span>{\" \"}\n (demo) traffic counts against the demo cap; admin/manager sessions\n are included in the total.\n </>\n )}\n </div>\n <div className=\"flex items-end gap-2\">\n <div className=\"w-48\">\n <Select\n label=\"Time range\"\n options={DEMO_SPEND_WINDOWS.map((w) => ({ value: w.value, label: w.label }))}\n value={windowKey}\n onChange={(e) => setWindowKey(e.target.value)}\n />\n </div>\n <button\n type=\"button\"\n onClick={() => refetch()}\n disabled={isFetching}\n title={\n dataUpdatedAt\n ? `Last updated ${new Date(dataUpdatedAt).toLocaleTimeString()}`\n : \"Refresh now\"\n }\n className=\"inline-flex h-[38px] items-center gap-1.5 rounded-md border border-gray-300 bg-white px-3 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-60\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 20 20\"\n fill=\"currentColor\"\n className={`h-4 w-4 ${isFetching ? \"animate-spin\" : \"\"}`}\n >\n <path\n fillRule=\"evenodd\"\n d=\"M15.312 11.424a5.5 5.5 0 01-9.201 2.466l-.312-.311h2.433a.75.75 0 000-1.5H3.989a.75.75 0 00-.75.75v4.242a.75.75 0 001.5 0v-2.43l.31.31a7 7 0 0011.712-3.138.75.75 0 00-1.449-.39zm1.23-3.723a.75.75 0 00.219-.53V2.929a.75.75 0 00-1.5 0V5.36l-.31-.31A7 7 0 003.239 8.188a.75.75 0 101.448.389A5.5 5.5 0 0113.89 6.11l.311.31h-2.432a.75.75 0 000 1.5h4.243a.75.75 0 00.53-.219z\"\n clipRule=\"evenodd\"\n />\n </svg>\n {isFetching ? t(\"common.refreshing\") : t(\"common.refresh\")}\n </button>\n </div>\n </div>\n\n {isLoading && <p className=\"mt-4 text-sm text-gray-500\">Loading spend data...</p>}\n {error && (\n <p className=\"mt-4 text-sm text-red-600\">\n Failed to load spend data: {(error as Error).message}\n </p>\n )}\n\n {window && (\n <div className=\"mt-5 space-y-5\">\n {demoActive ? (\n /* Demo deployments: spend-against-cap is the number that matters. */\n <div>\n <div className=\"flex items-baseline justify-between\">\n <div>\n <div className=\"text-xs font-medium uppercase tracking-wide text-gray-500\">\n Demo spend (avg/hr over {windowSpec.label.toLowerCase()})\n </div>\n <div className=\"mt-1 text-2xl font-semibold text-gray-900\">\n {fmtUsd(demoUsdPerHour)}\n <span className=\"ml-2 text-sm font-normal text-gray-500\">\n / {fmtUsd(demoCap)} hourly cap\n </span>\n </div>\n </div>\n <div className=\"text-right\">\n <div className=\"text-xs font-medium uppercase tracking-wide text-gray-500\">\n Total (all roles)\n </div>\n <div className=\"mt-1 text-lg font-semibold text-gray-700\">\n {fmtUsd(window.total_usd)}\n <span className=\"ml-1 text-xs font-normal text-gray-500\">\n ({fmtUsd(totalUsdPerHour)}/hr)\n </span>\n </div>\n </div>\n </div>\n <div className=\"mt-2 h-2 w-full overflow-hidden rounded-full bg-gray-100\">\n <div className={`h-full ${capColor} transition-all`} style={{ width: `${capPct}%` }} />\n </div>\n <div className=\"mt-1 text-xs text-gray-400\">\n {capPct.toFixed(0)}% of the hourly cap\n {capPct >= 100 && \" — demo visitors are currently blocked\"}\n </div>\n </div>\n ) : (\n /* Normal deployments: total LLM spend is the useful headline. */\n <div>\n <div className=\"text-xs font-medium uppercase tracking-wide text-gray-500\">\n Total spend (avg/hr over {windowSpec.label.toLowerCase()})\n </div>\n <div className=\"mt-1 text-2xl font-semibold text-gray-900\">\n {fmtUsd(totalUsdPerHour)}\n <span className=\"ml-2 text-sm font-normal text-gray-500\">\n ({fmtUsd(window.total_usd)} over {windowSpec.label.toLowerCase()})\n </span>\n </div>\n </div>\n )}\n\n {/* Stats grid */}\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-4\">\n {demoActive ? (\n <Stat label=\"Demo spend\" value={fmtUsd(window.demo_usd)} />\n ) : (\n <Stat label=\"Cost\" value={fmtUsd(window.total_usd)} />\n )}\n <Stat label=\"Calls\" value={window.call_count.toLocaleString()} />\n <Stat label=\"Unique IPs\" value={window.unique_ips.toLocaleString()} />\n <Stat\n label=\"Tokens (in/out)\"\n value={`${window.prompt_tokens.toLocaleString()} / ${window.completion_tokens.toLocaleString()}`}\n />\n </div>\n\n {/* Provider breakdown */}\n {Object.keys(window.by_provider).length > 0 && (\n <div>\n <div className=\"mb-2 text-xs font-medium uppercase tracking-wide text-gray-500\">\n By provider\n </div>\n <div className=\"overflow-hidden rounded-md border border-gray-200\">\n <table className=\"w-full text-sm\">\n <thead className=\"bg-gray-50 text-xs uppercase tracking-wide text-gray-500\">\n <tr>\n <th className=\"px-3 py-2 text-left font-medium\">Provider</th>\n <th className=\"px-3 py-2 text-right font-medium\">Cost</th>\n <th className=\"px-3 py-2 text-right font-medium\">Calls</th>\n <th className=\"px-3 py-2 text-right font-medium\">Prompt tok</th>\n <th className=\"px-3 py-2 text-right font-medium\">Completion tok</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {Object.entries(window.by_provider).map(([provider, row]) => (\n <tr key={provider}>\n <td className=\"px-3 py-2 font-medium text-gray-900\">{provider}</td>\n <td className=\"px-3 py-2 text-right tabular-nums\">{fmtUsd(row.cost_usd)}</td>\n <td className=\"px-3 py-2 text-right tabular-nums\">{row.call_count.toLocaleString()}</td>\n <td className=\"px-3 py-2 text-right tabular-nums\">{row.prompt_tokens.toLocaleString()}</td>\n <td className=\"px-3 py-2 text-right tabular-nums\">{row.completion_tokens.toLocaleString()}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n )}\n\n {/* Top IPs — fixed at 24h window regardless of selector, since that's\n what the backend returns and it's the most useful abuse-detection lens */}\n {data && data.top_ips_24h.length > 0 && (\n <div>\n <div className=\"mb-2 text-xs font-medium uppercase tracking-wide text-gray-500\">\n Top 10 IPs (last 24 hours)\n </div>\n <div className=\"overflow-hidden rounded-md border border-gray-200\">\n <table className=\"w-full text-sm\">\n <thead className=\"bg-gray-50 text-xs uppercase tracking-wide text-gray-500\">\n <tr>\n <th className=\"px-3 py-2 text-left font-medium\">IP</th>\n <th className=\"px-3 py-2 text-left font-medium\">Role</th>\n <th className=\"px-3 py-2 text-right font-medium\">Cost</th>\n <th className=\"px-3 py-2 text-right font-medium\">Calls</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-gray-100\">\n {data.top_ips_24h.map((row, i) => (\n <tr key={`${row.ip}-${row.role ?? \"\"}-${i}`}>\n <td className=\"px-3 py-2 font-mono text-xs text-gray-900\">{row.ip}</td>\n <td className=\"px-3 py-2 text-gray-600\">{row.role ?? \"—\"}</td>\n <td className=\"px-3 py-2 text-right tabular-nums\">{fmtUsd(row.cost_usd)}</td>\n <td className=\"px-3 py-2 text-right tabular-nums\">{row.call_count.toLocaleString()}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </div>\n )}\n </div>\n )}\n </Card>\n );\n}\n\nfunction Stat({ label, value }: { label: string; value: string }) {\n return (\n <div className=\"rounded-md bg-gray-50 px-3 py-2\">\n <div className=\"text-xs font-medium uppercase tracking-wide text-gray-500\">{label}</div>\n <div className=\"mt-0.5 text-sm font-semibold tabular-nums text-gray-900\">{value}</div>\n </div>\n );\n}\n\nfunction ChangePasswordCard() {\n const { t } = useTranslation();\n const { user } = useAuth();\n const [current, setCurrent] = useState(\"\");\n const [next, setNext] = useState(\"\");\n const [confirm, setConfirm] = useState(\"\");\n const [error, setError] = useState(\"\");\n const [done, setDone] = useState(false);\n\n const mut = useMutation({\n mutationFn: () => api.authChangePassword(current, next),\n onSuccess: () => {\n setDone(true);\n setError(\"\");\n setCurrent(\"\");\n setNext(\"\");\n setConfirm(\"\");\n setTimeout(() => setDone(false), 4000);\n },\n onError: (e) => setError(e instanceof ApiError ? e.message : t(\"login.registrationFailed\")),\n });\n\n const submit = (e: React.FormEvent) => {\n e.preventDefault();\n setError(\"\");\n setDone(false);\n if (next !== confirm) {\n setError(t(\"login.passwordsNoMatch\"));\n return;\n }\n if (next.length < 6) {\n setError(t(\"login.passwordTooShort\"));\n return;\n }\n mut.mutate();\n };\n\n return (\n <Card title={t(\"settings.passwordTitle\")}>\n <form onSubmit={submit} className=\"max-w-sm space-y-3\">\n {/* Hidden username anchor: lets password managers (1Password, etc.)\n associate the saved login so they fill/save against the right\n account. 1Password recommends a real text input hidden with\n display:none rather than the `hidden` attribute. */}\n <input\n type=\"text\"\n name=\"username\"\n id=\"username\"\n autoComplete=\"username\"\n value={user?.email || \"\"}\n readOnly\n tabIndex={-1}\n aria-hidden=\"true\"\n style={{ display: \"none\" }}\n />\n <Input\n label={t(\"settings.currentPassword\")}\n id=\"current-password\"\n name=\"current-password\"\n type=\"password\"\n autoComplete=\"current-password\"\n value={current}\n onChange={(e) => setCurrent(e.target.value)}\n required\n />\n <Input\n label={t(\"settings.newPassword\")}\n id=\"new-password\"\n name=\"new-password\"\n type=\"password\"\n autoComplete=\"new-password\"\n value={next}\n onChange={(e) => setNext(e.target.value)}\n required\n />\n <Input\n label={t(\"settings.confirmNewPassword\")}\n id=\"confirm-password\"\n name=\"confirm-password\"\n type=\"password\"\n autoComplete=\"new-password\"\n value={confirm}\n onChange={(e) => setConfirm(e.target.value)}\n required\n />\n {error && <p className=\"text-sm text-red-600\">{error}</p>}\n {done && <p className=\"text-sm text-green-700\">{t(\"settings.passwordChanged\")}</p>}\n <Button type=\"submit\" disabled={mut.isPending || !current || !next || !confirm}>\n {mut.isPending ? t(\"settings.changingPassword\") : t(\"settings.changePassword\")}\n </Button>\n </form>\n </Card>\n );\n}\n\nfunction SetPasswordCard() {\n const { t } = useTranslation();\n const { user, refreshUser } = useAuth();\n const [next, setNext] = useState(\"\");\n const [confirm, setConfirm] = useState(\"\");\n const [error, setError] = useState(\"\");\n const [done, setDone] = useState(false);\n\n const mut = useMutation({\n mutationFn: () => api.authSetPassword(next),\n onSuccess: async () => {\n setDone(true);\n setError(\"\");\n setNext(\"\");\n setConfirm(\"\");\n // Flip the card to \"Change Password\" now that a password exists.\n await refreshUser();\n },\n onError: (e) => setError(e instanceof ApiError ? e.message : t(\"login.registrationFailed\")),\n });\n\n const submit = (e: React.FormEvent) => {\n e.preventDefault();\n setError(\"\");\n setDone(false);\n if (next !== confirm) {\n setError(t(\"login.passwordsNoMatch\"));\n return;\n }\n if (next.length < 6) {\n setError(t(\"login.passwordTooShort\"));\n return;\n }\n mut.mutate();\n };\n\n return (\n <Card title={t(\"settings.setPasswordTitle\")}>\n <p className=\"mb-3 max-w-lg text-sm text-gray-600\">{t(\"settings.setPasswordBody\")}</p>\n <form onSubmit={submit} className=\"max-w-sm space-y-3\">\n {/* Hidden username anchor so password managers save against the account. */}\n <input\n type=\"text\"\n name=\"username\"\n autoComplete=\"username\"\n value={user?.email || \"\"}\n readOnly\n tabIndex={-1}\n aria-hidden=\"true\"\n style={{ display: \"none\" }}\n />\n <Input\n label={t(\"settings.newPassword\")}\n id=\"new-password\"\n name=\"new-password\"\n type=\"password\"\n autoComplete=\"new-password\"\n value={next}\n onChange={(e) => setNext(e.target.value)}\n required\n />\n <Input\n label={t(\"settings.confirmNewPassword\")}\n id=\"confirm-password\"\n name=\"confirm-password\"\n type=\"password\"\n autoComplete=\"new-password\"\n value={confirm}\n onChange={(e) => setConfirm(e.target.value)}\n required\n />\n {error && <p className=\"text-sm text-red-600\">{error}</p>}\n {done && <p className=\"text-sm text-green-700\">{t(\"settings.passwordSet\")}</p>}\n <Button type=\"submit\" disabled={mut.isPending || !next || !confirm}>\n {mut.isPending ? t(\"settings.changingPassword\") : t(\"settings.setPassword\")}\n </Button>\n </form>\n </Card>\n );\n}\n\nfunction LinkedAccountsCard() {\n const { t } = useTranslation();\n\n const { data: setup } = useQuery({\n queryKey: [\"auth-setup-status\"],\n queryFn: () => api.authSetupStatus(),\n });\n const { data: identities } = useQuery({\n queryKey: [\"oauth-identities\"],\n queryFn: () => api.oauthListIdentities(),\n });\n\n const providers = setup?.oauth_providers ?? [];\n if (providers.length === 0) return null; // no social login configured on this deployment\n\n const linked = new Set((identities ?? []).map((i) => i.provider));\n\n return (\n <Card title={t(\"settings.linkedAccountsTitle\")}>\n <p className=\"text-sm text-gray-600\">{t(\"settings.linkedAccountsBody\")}</p>\n <div className=\"mt-3 space-y-2\">\n {providers.map((p) => {\n const label = p.charAt(0).toUpperCase() + p.slice(1);\n const isLinked = linked.has(p);\n return (\n <div key={p} className=\"flex items-center justify-between rounded-md border border-gray-200 px-3 py-2\">\n <span className=\"text-sm font-medium text-gray-900\">{label}</span>\n {isLinked ? (\n <span className=\"inline-flex items-center gap-1.5 text-sm text-green-700\">\n <span className=\"inline-block h-2 w-2 rounded-full bg-green-500\" />\n {t(\"settings.linked\")}\n </span>\n ) : (\n <button\n type=\"button\"\n onClick={() => { window.location.href = api.oauthLoginUrl(p, { link: true }); }}\n className=\"rounded-md border border-gray-300 bg-white px-3 py-1 text-sm font-medium text-gray-700 hover:bg-gray-50\"\n >\n {t(\"settings.linkProvider\", { provider: label })}\n </button>\n )}\n </div>\n );\n })}\n </div>\n </Card>\n );\n}\n\nconst ROLE_RANK: Record<string, number> = { viewer: 1, manager: 2, admin: 3 };\n\n// Self-service API keys: every key belongs to its creator and can never act\n// above the owner's live role (the picked role is only a CAP). Non-admins see\n// and manage their own keys; admins see everyone's.\nfunction ApiKeysSection({ ownRole }: { ownRole: string }) {\n const { t } = useTranslation();\n const { user: me } = useAuth();\n const queryClient = useQueryClient();\n const [name, setName] = useState(\"\");\n const [role, setRole] = useState(ownRole in ROLE_RANK ? ownRole : \"viewer\");\n const [newToken, setNewToken] = useState<string | null>(null);\n const [confirm, setConfirm] = useState<\n null | { id: string; action: \"revoke\" | \"delete\"; owner: string; keyName: string }\n >(null);\n\n const roleOptions = [\"viewer\", \"manager\", \"admin\"].filter(\n (r) => ROLE_RANK[r] <= (ROLE_RANK[ownRole] ?? 1),\n );\n\n // The same key doubles as MCP auth (POST <origin>/api/mcp). Show ready-to-paste\n // config for the common agents right after the token, while it's still visible.\n const mcpUrl = `${window.location.origin}/api/mcp`;\n const claudeSnippet = newToken\n ? `claude mcp add --transport http --scope user lambda-erp ${mcpUrl} \\\\\\n --header \"Authorization: Bearer ${newToken}\"`\n : \"\";\n const codexSnippet = newToken\n ? `# ~/.codex/config.toml\\n[mcp_servers.lambda-erp]\\nurl = \"${mcpUrl}\"\\nhttp_headers = { Authorization = \"Bearer ${newToken}\" }`\n : \"\";\n\n const { data: keys } = useQuery({\n queryKey: [\"api-keys\"],\n queryFn: () => api.getApiKeys(),\n });\n\n const createMut = useMutation({\n mutationFn: () => api.createApiKey(name.trim(), role),\n onSuccess: (res) => {\n setNewToken(res.token);\n setName(\"\");\n queryClient.invalidateQueries({ queryKey: [\"api-keys\"] });\n },\n });\n\n const revokeMut = useMutation({\n mutationFn: (id: string) => api.revokeApiKey(id),\n onSuccess: () => queryClient.invalidateQueries({ queryKey: [\"api-keys\"] }),\n });\n\n const deleteMut = useMutation({\n mutationFn: (id: string) => api.deleteApiKey(id),\n onSuccess: () => queryClient.invalidateQueries({ queryKey: [\"api-keys\"] }),\n });\n\n type Key = NonNullable<typeof keys>[number];\n const isMine = (k: Key) => k.is_mine ?? (k.user === me?.name);\n const ownerLabel = (k: Key) =>\n k.owner_full_name || k.owner_email || k.user || t(\"settings.chatApiUnknownUser\");\n\n // Group keys by owner: your own first, then each other user alphabetically.\n const groups = useMemo(() => {\n const byOwner = new Map<\n string,\n { label: string; sublabel?: string; isMine: boolean; keys: Key[] }\n >();\n for (const k of keys ?? []) {\n const mine = k.is_mine ?? (k.user === me?.name);\n const gid = mine ? \"__me__\" : k.user ?? \"__unknown__\";\n if (!byOwner.has(gid)) {\n byOwner.set(gid, {\n label: mine\n ? t(\"settings.chatApiYourKeys\")\n : k.owner_full_name || k.owner_email || k.user || t(\"settings.chatApiUnknownUser\"),\n sublabel: mine ? undefined : k.owner_email ?? undefined,\n isMine: mine,\n keys: [],\n });\n }\n byOwner.get(gid)!.keys.push(k);\n }\n return Array.from(byOwner.values()).sort((a, b) =>\n a.isMine ? -1 : b.isMine ? 1 : a.label.localeCompare(b.label),\n );\n }, [keys, me, t]);\n\n const runAction = (id: string, action: \"revoke\" | \"delete\") => {\n if (action === \"revoke\") revokeMut.mutate(id);\n else deleteMut.mutate(id);\n };\n\n // A destructive action on someone else's key must be confirmed first.\n const act = (k: Key, action: \"revoke\" | \"delete\") => {\n if (isMine(k)) {\n runAction(k.id, action);\n } else {\n setConfirm({ id: k.id, action, owner: ownerLabel(k), keyName: k.name });\n }\n };\n\n return (\n <div>\n {newToken && (\n <div className=\"mb-3 rounded-lg bg-amber-50 p-3 ring-1 ring-inset ring-amber-200\">\n <p className=\"text-xs text-amber-800\">{t(\"settings.chatApiTokenOnce\")}</p>\n <code className=\"mt-1 block break-all rounded bg-surface px-2 py-1 font-mono text-xs text-fg\">\n {newToken}\n </code>\n <button\n className=\"mt-2 text-xs font-medium text-brand hover:underline\"\n onClick={() => navigator.clipboard?.writeText(newToken)}\n >\n {t(\"settings.chatApiCopy\")}\n </button>\n <button\n className=\"ml-3 mt-2 text-xs text-fg-muted hover:underline\"\n onClick={() => setNewToken(null)}\n >\n {t(\"settings.chatApiDismiss\")}\n </button>\n\n {/* The same key is also an MCP endpoint — reuses this key's role. */}\n <div className=\"mt-3 border-t border-amber-200 pt-3\">\n <p className=\"text-xs text-amber-800\">\n {t(\"settings.mcpNote\", {\n defaultValue:\n \"This key is also an MCP endpoint — connect an AI agent (Claude, Codex) to it. It reuses this key's role (a viewer key = read-only).\",\n })}\n </p>\n <code className=\"mt-1 block break-all rounded bg-surface px-2 py-1 font-mono text-xs text-fg\">\n {mcpUrl}\n </code>\n <details className=\"mt-2 text-xs text-amber-900\">\n <summary className=\"cursor-pointer font-medium\">Claude</summary>\n <pre className=\"mt-1 overflow-x-auto rounded bg-surface p-2 font-mono text-[11px] leading-relaxed text-fg\">{claudeSnippet}</pre>\n </details>\n <details className=\"mt-1 text-xs text-amber-900\">\n <summary className=\"cursor-pointer font-medium\">Codex</summary>\n <pre className=\"mt-1 overflow-x-auto rounded bg-surface p-2 font-mono text-[11px] leading-relaxed text-fg\">{codexSnippet}</pre>\n </details>\n </div>\n </div>\n )}\n\n {ownRole === \"admin\" && (\n <p className=\"mb-3 text-xs text-fg-muted\">{t(\"settings.chatApiAdminAllNote\")}</p>\n )}\n\n {groups.length > 0 ? (\n <div className=\"mb-4 space-y-4\">\n {groups.map((g) => (\n <div key={g.label}>\n <div className=\"mb-1.5 flex items-baseline gap-2\">\n <span className=\"text-xs font-semibold text-fg\">{g.label}</span>\n {g.isMine ? (\n <Badge variant=\"default\">{t(\"settings.chatApiYouBadge\")}</Badge>\n ) : (\n g.sublabel && <span className=\"text-xs text-fg-muted\">{g.sublabel}</span>\n )}\n </div>\n <ul className=\"divide-y divide-line rounded-lg ring-1 ring-line\">\n {g.keys.map((k) => (\n <li\n key={k.id}\n className=\"flex items-center justify-between gap-3 px-3 py-2 text-sm\"\n >\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span className=\"truncate font-medium text-fg\">{k.name}</span>\n <Badge variant=\"secondary\">{k.role}</Badge>\n {k.revoked && (\n <Badge variant=\"danger\">{t(\"settings.chatApiRevoked\")}</Badge>\n )}\n </div>\n <span className=\"font-mono text-xs text-fg-muted\">{k.key_prefix}…</span>\n </div>\n <button\n className=\"shrink-0 text-xs font-medium text-red-600 hover:underline disabled:opacity-50\"\n onClick={() => act(k, k.revoked ? \"delete\" : \"revoke\")}\n disabled={revokeMut.isPending || deleteMut.isPending}\n >\n {k.revoked ? t(\"settings.chatApiDelete\") : t(\"settings.chatApiRevoke\")}\n </button>\n </li>\n ))}\n </ul>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"mb-4 text-xs text-fg-muted\">{t(\"settings.chatApiNoKeys\")}</p>\n )}\n\n <div className=\"flex flex-wrap items-end gap-3\">\n <div className=\"w-48\">\n <Input\n label={t(\"settings.chatApiName\")}\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"lambda-web\"\n />\n </div>\n <Select\n label={t(\"settings.chatApiRole\")}\n options={roleOptions}\n value={role}\n onChange={(e) => setRole(e.target.value)}\n />\n <Button onClick={() => createMut.mutate()} disabled={!name.trim() || createMut.isPending}>\n {t(\"settings.chatApiCreate\")}\n </Button>\n </div>\n <p className=\"mt-2 text-xs text-fg-muted\">{t(\"settings.chatApiWarn\")}</p>\n\n {confirm && (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4\"\n onClick={() => setConfirm(null)}\n >\n <div\n className=\"w-full max-w-sm rounded-xl border border-line bg-surface p-5 shadow-xl\"\n role=\"dialog\"\n aria-modal=\"true\"\n onClick={(e) => e.stopPropagation()}\n >\n <h3 className=\"text-sm font-semibold text-fg\">{t(\"settings.chatApiConfirmTitle\")}</h3>\n <p className=\"mt-2 text-xs text-fg-muted\">\n {t(\n confirm.action === \"revoke\"\n ? \"settings.chatApiConfirmRevokeBody\"\n : \"settings.chatApiConfirmDeleteBody\",\n { name: confirm.owner, key: confirm.keyName },\n )}\n </p>\n <div className=\"mt-4 flex justify-end gap-2\">\n <Button variant=\"secondary\" size=\"sm\" onClick={() => setConfirm(null)}>\n {t(\"common.cancel\")}\n </Button>\n <Button\n variant=\"danger\"\n size=\"sm\"\n onClick={() => {\n runAction(confirm.id, confirm.action);\n setConfirm(null);\n }}\n >\n {confirm.action === \"revoke\"\n ? t(\"settings.chatApiRevoke\")\n : t(\"settings.chatApiDelete\")}\n </Button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n}\n\nfunction ApiToggleRow({\n enabled,\n onToggle,\n body,\n statusOn,\n statusOff,\n}: {\n enabled: boolean;\n onToggle: () => void;\n body: string;\n statusOn: string;\n statusOff: string;\n}) {\n const { t } = useTranslation();\n return (\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"text-sm text-gray-700\">{body}</p>\n <p className=\"mt-1 text-xs text-gray-400\">{enabled ? statusOn : statusOff}</p>\n </div>\n <button\n onClick={onToggle}\n className={`ml-4 shrink-0 rounded-full px-4 py-1.5 text-sm font-medium ${\n enabled\n ? \"bg-red-50 text-red-700 hover:bg-red-100\"\n : \"bg-green-50 text-green-700 hover:bg-green-100\"\n }`}\n >\n {enabled ? t(\"common.disable\") : t(\"common.enable\")}\n </button>\n </div>\n );\n}\n\n// The Chat API (POST /api/v1/chat) and the REST API (/api/documents, /api/masters, …)\n// are two surfaces authenticated by the SAME per-user Bearer keys, toggled\n// independently. The shared keys section shows once EITHER surface is enabled.\nfunction ApiAccessCard({\n chatEnabled,\n restEnabled,\n onToggleChat,\n onToggleRest,\n ownRole,\n}: {\n chatEnabled: boolean;\n restEnabled: boolean;\n onToggleChat: () => void;\n onToggleRest: () => void;\n ownRole: string;\n}) {\n const { t } = useTranslation();\n // Which surface a pending \"turn off\" confirm applies to. Enabling is harmless\n // (go straight through); disabling cuts off live callers, so confirm first —\n // keys are preserved either way, requests just start failing.\n const [confirmOff, setConfirmOff] = useState<null | \"chat\" | \"rest\">(null);\n\n return (\n <Card title={t(\"settings.apiTitle\")}>\n <div className=\"space-y-4\">\n <ApiToggleRow\n enabled={chatEnabled}\n onToggle={() => (chatEnabled ? setConfirmOff(\"chat\") : onToggleChat())}\n body={t(\"settings.chatApiBody\")}\n statusOn={t(\"settings.chatApiEnabled\")}\n statusOff={t(\"settings.chatApiDisabled\")}\n />\n <div className=\"border-t border-gray-100\" />\n <ApiToggleRow\n enabled={restEnabled}\n onToggle={() => (restEnabled ? setConfirmOff(\"rest\") : onToggleRest())}\n body={t(\"settings.restApiBody\")}\n statusOn={t(\"settings.restApiEnabled\")}\n statusOff={t(\"settings.restApiDisabled\")}\n />\n </div>\n\n {(chatEnabled || restEnabled) && (\n <div className=\"mt-4 border-t border-gray-100 pt-4\">\n <div className=\"mb-2 text-xs font-medium text-gray-500\">{t(\"settings.chatApiKeysTitle\")}</div>\n <ApiKeysSection ownRole={ownRole} />\n </div>\n )}\n\n {confirmOff && (\n <div\n className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4\"\n onClick={() => setConfirmOff(null)}\n >\n <div\n className=\"w-full max-w-md rounded-xl border border-line bg-surface p-6 shadow-xl\"\n role=\"dialog\"\n aria-modal=\"true\"\n onClick={(e) => e.stopPropagation()}\n >\n <h3 className=\"text-base font-semibold text-fg\">\n {confirmOff === \"chat\"\n ? t(\"settings.chatApiDeactivateTitle\")\n : t(\"settings.restApiDeactivateTitle\")}\n </h3>\n <p className=\"mt-3 text-sm text-fg-muted\">\n {confirmOff === \"chat\"\n ? t(\"settings.chatApiDeactivateBody\")\n : t(\"settings.restApiDeactivateBody\")}\n </p>\n <div className=\"mt-6 flex justify-end gap-2\">\n <Button variant=\"secondary\" size=\"sm\" onClick={() => setConfirmOff(null)}>\n {t(\"common.cancel\")}\n </Button>\n <Button\n variant=\"danger\"\n size=\"sm\"\n onClick={() => {\n if (confirmOff === \"chat\") onToggleChat();\n else onToggleRest();\n setConfirmOff(null);\n }}\n >\n {t(\"settings.chatApiDeactivateConfirm\")}\n </Button>\n </div>\n </div>\n </div>\n )}\n </Card>\n );\n}\n\nexport default function SettingsPage() {\n const { user } = useAuth();\n const { t } = useTranslation();\n const queryClient = useQueryClient();\n const isAdmin = user?.role === \"admin\";\n\n const { data: settings, isLoading } = useQuery({\n queryKey: [\"settings\"],\n queryFn: () => api.getSettings(),\n });\n\n const settingsMut = useMutation({\n mutationFn: (data: Record<string, string>) => api.updateSettings(data),\n onSuccess: () => queryClient.invalidateQueries({ queryKey: [\"settings\"] }),\n });\n\n const { data: pubStatus } = useQuery({\n queryKey: [\"public-manager\"],\n queryFn: () => api.getPublicManagerStatus(),\n });\n\n const { data: health } = useQuery({\n queryKey: [\"health\"],\n queryFn: () => api.getHealth(),\n staleTime: Infinity, // version only changes on deploy\n });\n\n const [showConfirm, setShowConfirm] = useState(false);\n\n const createPubMut = useMutation({\n mutationFn: () => api.createPublicManager(),\n onSuccess: () => {\n queryClient.invalidateQueries({ queryKey: [\"public-manager\"] });\n setShowConfirm(false);\n },\n });\n\n const removePubMut = useMutation({\n mutationFn: () => api.removePublicManager(),\n onSuccess: () => queryClient.invalidateQueries({ queryKey: [\"public-manager\"] }),\n });\n\n if (isLoading) return <p className=\"text-gray-500\">{t(\"common.loading\")}</p>;\n\n return (\n <div className=\"space-y-6\">\n <Card title={t(\"language.title\")}>\n <div className=\"flex flex-wrap items-end gap-4\">\n <div className=\"w-64\">\n <LanguageSelect />\n </div>\n </div>\n <p className=\"mt-2 text-xs text-gray-400\">{t(\"language.help\")}</p>\n </Card>\n\n {/* Personal account — every signed-in user can change their own password\n (the shared public_manager demo account has none). */}\n {/* Password-less (social-login-only) users get \"Set a password\"; everyone\n else keeps \"Change Password\". has_password === false is the only case\n that hides Change Password, so an unknown value stays safe. */}\n {user?.role !== \"public_manager\" &&\n (user?.has_password === false ? <SetPasswordCard /> : <ChangePasswordCard />)}\n {user?.role !== \"public_manager\" && <LinkedAccountsCard />}\n\n <Card title={t(\"settings.pdfTitle\")}>\n <div className=\"flex flex-wrap items-end gap-4\">\n {isAdmin ? (\n <Select\n label={t(\"settings.pageSize\")}\n options={[\"A4\", \"letter\"]}\n value={settings?.pdf_page_size || \"A4\"}\n onChange={(e) => settingsMut.mutate({ pdf_page_size: e.target.value })}\n />\n ) : (\n <div>\n <div className=\"text-xs font-medium text-gray-500 mb-1\">{t(\"settings.pageSize\")}</div>\n <div className=\"text-sm text-gray-900\">{settings?.pdf_page_size || \"A4\"}</div>\n </div>\n )}\n </div>\n <p className=\"mt-2 text-xs text-gray-400\">\n {t(\"settings.pdfHelp\")}\n </p>\n </Card>\n\n <Card title={t(\"settings.openingTitle\")}>\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"text-sm text-gray-700\">\n {t(\"settings.openingBody\")}\n </p>\n <p className=\"mt-1 text-xs text-gray-400\">\n {settings?.opening_balances_enabled === \"1\"\n ? t(\"settings.openingEnabled\")\n : t(\"settings.openingDisabled\")}\n </p>\n </div>\n {isAdmin && (\n <button\n onClick={() => settingsMut.mutate({\n opening_balances_enabled: settings?.opening_balances_enabled === \"1\" ? \"0\" : \"1\",\n })}\n className={`ml-4 shrink-0 rounded-full px-4 py-1.5 text-sm font-medium ${\n settings?.opening_balances_enabled === \"1\"\n ? \"bg-red-50 text-red-700 hover:bg-red-100\"\n : \"bg-green-50 text-green-700 hover:bg-green-100\"\n }`}\n >\n {settings?.opening_balances_enabled === \"1\" ? t(\"common.disable\") : t(\"common.enable\")}\n </button>\n )}\n </div>\n </Card>\n\n <Card title={t(\"settings.signupTitle\")}>\n <div className=\"flex items-center justify-between\">\n <div>\n <p className=\"text-sm text-gray-700\">\n {t(\"settings.signupBody\")}\n </p>\n <p className=\"mt-1 text-xs text-gray-400\">\n {settings?.allow_public_signup === \"1\"\n ? t(\"settings.signupEnabled\")\n : t(\"settings.signupDisabled\")}\n </p>\n </div>\n {isAdmin && (\n <button\n onClick={() => settingsMut.mutate({\n allow_public_signup: settings?.allow_public_signup === \"1\" ? \"0\" : \"1\",\n })}\n className={`ml-4 shrink-0 rounded-full px-4 py-1.5 text-sm font-medium ${\n settings?.allow_public_signup === \"1\"\n ? \"bg-red-50 text-red-700 hover:bg-red-100\"\n : \"bg-green-50 text-green-700 hover:bg-green-100\"\n }`}\n >\n {settings?.allow_public_signup === \"1\" ? t(\"common.disable\") : t(\"common.enable\")}\n </button>\n )}\n </div>\n </Card>\n\n {isAdmin && (\n <ApiAccessCard\n chatEnabled={settings?.chat_api_enabled === \"1\"}\n restEnabled={settings?.rest_api_enabled === \"1\"}\n ownRole={user?.role ?? \"viewer\"}\n onToggleChat={() =>\n settingsMut.mutate({\n chat_api_enabled: settings?.chat_api_enabled === \"1\" ? \"0\" : \"1\",\n })\n }\n onToggleRest={() =>\n settingsMut.mutate({\n rest_api_enabled: settings?.rest_api_enabled === \"1\" ? \"0\" : \"1\",\n })\n }\n />\n )}\n\n {/* Self-service API keys for non-admins: keys are personal (bound to the\n creator, capped at their role), so every real user manages their own\n here. Admins get the same section inside the Chat API card above. */}\n {!isAdmin && user?.role !== \"public_manager\" && (\n <Card title={t(\"settings.chatApiKeysTitle\")}>\n <p className=\"mb-3 text-sm text-gray-700\">{t(\"settings.chatApiPersonal\")}</p>\n <ApiKeysSection ownRole={user?.role ?? \"viewer\"} />\n </Card>\n )}\n\n {isAdmin && <TokenSpendCard demoActive={!!pubStatus?.active} />}\n\n {/* Public Manager / Demo Mode — kept last: it's the most consequential\n toggle (opens the whole app to anonymous demo access). */}\n {isAdmin && (\n <Card title={t(\"settings.publicTitle\")}>\n {pubStatus?.active ? (\n <div>\n <div className=\"flex items-center gap-2\">\n <span className=\"inline-block h-2 w-2 rounded-full bg-green-500\" />\n <span className=\"text-sm font-medium text-green-800\">{t(\"settings.publicActive\")}</span>\n </div>\n <p className=\"mt-2 text-sm text-gray-600\">\n {t(\"settings.publicActiveBody\")}\n </p>\n <button\n onClick={() => removePubMut.mutate()}\n disabled={removePubMut.isPending}\n className=\"mt-3 rounded-lg bg-gray-100 px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-200\"\n >\n {removePubMut.isPending ? t(\"settings.disabling\") : t(\"settings.disablePublic\")}\n </button>\n </div>\n ) : (\n <div>\n <p className=\"text-sm text-gray-600\">\n {t(\"settings.publicInactiveBody\")}\n </p>\n {!showConfirm ? (\n <button\n onClick={() => setShowConfirm(true)}\n className=\"mt-3 rounded-lg bg-red-600 px-4 py-2 text-sm font-medium text-white hover:bg-red-700\"\n >\n {t(\"settings.enablePublic\")}\n </button>\n ) : (\n <div className=\"mt-3 rounded-lg border border-red-200 bg-red-50 p-4\">\n <p className=\"text-sm font-medium text-red-800\">{t(\"common.areYouSure\")}</p>\n <p className=\"mt-1 text-xs text-red-600\">\n {t(\"settings.enableWarning\")}\n </p>\n <div className=\"mt-3 flex gap-2\">\n <button\n onClick={() => createPubMut.mutate()}\n disabled={createPubMut.isPending}\n className=\"rounded-lg bg-red-600 px-4 py-1.5 text-sm font-medium text-white hover:bg-red-700\"\n >\n {createPubMut.isPending ? t(\"settings.enabling\") : t(\"settings.yesEnable\")}\n </button>\n <button\n onClick={() => setShowConfirm(false)}\n className=\"rounded-lg bg-white px-4 py-1.5 text-sm font-medium text-gray-700 hover:bg-gray-50 border border-gray-300\"\n >\n {t(\"common.cancel\")}\n </button>\n </div>\n </div>\n )}\n </div>\n )}\n </Card>\n )}\n\n {health?.version && (\n <p className=\"pt-2 text-center text-xs text-gray-400\">\n {t(\"settings.version\", { version: health.version })}\n </p>\n )}\n </div>\n );\n}\n","/**\n * Component override registry.\n *\n * Lets a customer deployment swap a specific UI component for its own without\n * forking the core. Core render sites that want to be overridable resolve\n * their component through `getComponent(name, CoreDefault)` instead of\n * referencing the concrete component directly; the customer calls\n * `registerComponent(name, MyComponent)` at startup.\n *\n * This is the fine-grained seam. For whole pages, prefer the route registry\n * (registerRoute) — it replaces the routed element directly.\n */\nimport type { ComponentType } from \"react\";\n\nconst COMPONENTS: Record<string, ComponentType<any>> = {};\n\nexport function registerComponent(name: string, component: ComponentType<any>) {\n COMPONENTS[name] = component;\n}\n\n/** Resolve a registered override, falling back to the core default. */\nexport function getComponent<P>(\n name: string,\n fallback: ComponentType<P>,\n): ComponentType<P> {\n return (COMPONENTS[name] as ComponentType<P>) ?? fallback;\n}\n","import { type RouteObject } from \"react-router-dom\";\nimport { AppShell } from \"@/components/layout/app-shell\";\nimport { ProtectedRoute } from \"@/components/auth/protected-route\";\nimport Dashboard from \"@/pages/dashboard\";\nimport DocumentList from \"@/pages/documents/document-list\";\nimport DocumentForm from \"@/pages/documents/document-form\";\nimport ProposalForm from \"@/pages/proposals/proposal-form\";\nimport MasterList from \"@/pages/masters/master-list\";\nimport MasterForm from \"@/pages/masters/master-form\";\nimport TrialBalance from \"@/pages/reports/trial-balance\";\nimport ChartOfAccounts from \"@/pages/reports/chart-of-accounts\";\nimport GeneralLedger from \"@/pages/reports/general-ledger\";\nimport StockBalance from \"@/pages/reports/stock-balance\";\nimport ProfitLoss from \"@/pages/reports/profit-loss\";\nimport BalanceSheet from \"@/pages/reports/balance-sheet\";\nimport ArAging from \"@/pages/reports/ar-aging\";\nimport ApAging from \"@/pages/reports/ap-aging\";\nimport Analytics from \"@/pages/reports/analytics\";\nimport Setup from \"@/pages/setup\";\nimport Tutorial from \"@/pages/tutorial\";\nimport Chat from \"@/pages/chat\";\nimport Login from \"@/pages/login\";\nimport Demo from \"@/pages/demo\";\nimport OpeningBalances from \"@/pages/opening-balances\";\nimport Users from \"@/pages/admin/users\";\nimport GeneralSettings from \"@/pages/admin/settings\";\nimport { getComponent } from \"@/lib/component-registry\";\n\n// The dashboard (the index route) is resolved through the component registry\n// so a customer deployment can swap it via registerComponent(\"Dashboard\", …).\nfunction DashboardRoute() {\n const C = getComponent(\"Dashboard\", Dashboard);\n return <C />;\n}\n\nconst baseTopRoutes: RouteObject[] = [\n { path: \"/login\", element: <Login /> },\n { path: \"/demo\", element: <Demo /> },\n];\n\nconst baseChildRoutes: RouteObject[] = [\n { index: true, element: <DashboardRoute /> },\n { path: \"setup\", element: <Setup /> },\n { path: \"setup/opening-balances\", element: <OpeningBalances /> },\n { path: \"tutorial\", element: <Tutorial /> },\n { path: \"chat\", element: <Chat /> },\n { path: \"chat/:sessionId\", element: <Chat /> },\n\n // Proposal (Sammelofferte) — a custom builder; the list reuses the generic\n // DocumentList via the `proposal` doctype config. The static \"proposal\"\n // segment outranks the \":doctype\" wildcard below in react-router's matcher.\n { path: \"app/proposal/new\", element: <ProposalForm /> },\n { path: \"app/proposal/:name\", element: <ProposalForm /> },\n\n // Documents\n { path: \"app/:doctype\", element: <DocumentList /> },\n { path: \"app/:doctype/new\", element: <DocumentForm /> },\n { path: \"app/:doctype/:name\", element: <DocumentForm /> },\n\n // Masters (reuse same routes - the components detect whether it's a doctype or master)\n { path: \"masters/:type\", element: <MasterList /> },\n { path: \"masters/:type/new\", element: <MasterForm /> },\n { path: \"masters/:type/:name\", element: <MasterForm /> },\n\n // Reports\n { path: \"reports/chart-of-accounts\", element: <ChartOfAccounts /> },\n { path: \"reports/trial-balance\", element: <TrialBalance /> },\n { path: \"reports/general-ledger\", element: <GeneralLedger /> },\n { path: \"reports/stock-balance\", element: <StockBalance /> },\n { path: \"reports/profit-and-loss\", element: <ProfitLoss /> },\n { path: \"reports/balance-sheet\", element: <BalanceSheet /> },\n { path: \"reports/ar-aging\", element: <ArAging /> },\n { path: \"reports/ap-aging\", element: <ApAging /> },\n { path: \"reports/analytics\", element: <Analytics /> },\n\n // Admin\n { path: \"admin/users\", element: <Users /> },\n { path: \"admin/settings\", element: <GeneralSettings /> },\n];\n\nconst extraTopRoutes: RouteObject[] = [];\nconst extraChildRoutes: RouteObject[] = [];\n\n/**\n * Register a route from a customer deployment.\n * - area \"app\" (default): added under the protected app shell (sidebar +\n * header), so it's an authenticated page like the core ones.\n * - area \"top\": added at the root (e.g. a public/unauthenticated page).\n *\n * A registered route whose `path` (or index) matches a core route replaces\n * it — that's how you override a core page wholesale.\n */\nexport function registerRoute(route: RouteObject, opts?: { area?: \"app\" | \"top\" }) {\n if (opts?.area === \"top\") {\n extraTopRoutes.push(route);\n } else {\n extraChildRoutes.push(route);\n }\n}\n\nconst routeKey = (r: RouteObject) => (r.index ? \"__index__\" : r.path ?? \"\");\n\nfunction mergeRoutes(base: RouteObject[], extra: RouteObject[]): RouteObject[] {\n const out = [...base];\n for (const r of extra) {\n const k = routeKey(r);\n const i = out.findIndex((m) => routeKey(m) === k);\n if (i >= 0) out[i] = r;\n else out.push(r);\n }\n return out;\n}\n\n/**\n * Build the full route table, merging any customer-registered routes over the\n * core ones. Call this when constructing the router (the demo does so via\n * bootstrap) — after plugins have registered, so overrides take effect.\n */\nexport function buildRoutes(): RouteObject[] {\n return [\n ...mergeRoutes(baseTopRoutes, extraTopRoutes),\n {\n path: \"/\",\n element: <ProtectedRoute><AppShell /></ProtectedRoute>,\n children: mergeRoutes(baseChildRoutes, extraChildRoutes),\n },\n ];\n}\n","// Auto-registered redirects for page-less chat-doctypes.\n//\n// A doctype registered via register_chat_doctype(..., page=\"<link_field>\") has\n// no standalone page — it's shown inside a parent (e.g. a contact inside its\n// lead). The AI chat may still emit `/app/{slug}/{name}` links for it. This\n// fetches /api/chat-doctypes at bootstrap and, for each such doctype, registers\n// a route that looks up the record's parent and redirects to the parent's page,\n// so those links resolve. Best-effort: if the fetch fails the app still renders\n// (the chat's prompt page-rules already point it at the right link).\nimport { useEffect } from \"react\";\nimport { useParams, useNavigate } from \"react-router-dom\";\nimport { api, request } from \"@/api/client\";\nimport { registerRoute } from \"@/routes\";\n\ntype PageInfo =\n | { kind: \"self\"; slug: string }\n | { kind: \"via\"; link_field: string; parent_slug: string }\n | { kind: \"none\" };\n\nfunction ChatDoctypeRedirect({ slug, parentSlug, linkField }: {\n slug: string; parentSlug: string; linkField: string;\n}) {\n const { name = \"\" } = useParams();\n const navigate = useNavigate();\n useEffect(() => {\n let alive = true;\n api\n .getDocument(slug, name)\n .then((doc: any) => {\n if (!alive) return;\n const parent = doc?.[linkField];\n navigate(parent ? `/app/${parentSlug}/${parent}` : `/app/${slug}`, { replace: true });\n })\n .catch(() => { if (alive) navigate(\"/app\", { replace: true }); });\n return () => { alive = false; };\n }, [slug, name, parentSlug, linkField, navigate]);\n return <div className=\"p-6 text-sm text-fg-muted\">…</div>;\n}\n\nexport async function registerChatDoctypeRedirects(): Promise<void> {\n try {\n const res = await request<{ doctypes: { slug: string; page: PageInfo | null }[] }>(\n \"/chat-doctypes\",\n { signal: AbortSignal.timeout(1500) },\n );\n for (const d of res.doctypes || []) {\n const page = d.page;\n if (page && page.kind === \"via\") {\n registerRoute({\n path: `app/${d.slug}/:name`,\n element: (\n <ChatDoctypeRedirect slug={d.slug} parentSlug={page.parent_slug} linkField={page.link_field} />\n ),\n });\n }\n }\n } catch {\n // best-effort — the app renders fine without these fallback redirects.\n }\n}\n","import { StrictMode } from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport { QueryClient, QueryClientProvider } from \"@tanstack/react-query\";\nimport { createBrowserRouter, RouterProvider } from \"react-router-dom\";\nimport { AuthProvider } from \"./contexts/auth-context\";\nimport { buildRoutes } from \"./routes\";\nimport { registerChatDoctypeRedirects } from \"./lib/chat-doctype-redirects\";\nimport \"./i18n\"; // initialize i18next (reads saved language from localStorage)\n\nexport function createAppQueryClient() {\n return new QueryClient({\n defaultOptions: {\n queries: { retry: 1, refetchOnWindowFocus: false },\n },\n });\n}\n\nexport interface BootstrapOptions {\n /** Mount target. Defaults to the element with id \"root\". */\n rootElement?: HTMLElement;\n /** Provide a custom QueryClient (e.g. to tune caching). */\n queryClient?: QueryClient;\n}\n\n/**\n * Render the full app (providers + router) into the DOM. The demo app and a\n * customer deployment both call this from their entry module — the customer\n * imports its plugin (which registers overrides/routes/doctypes) and the\n * stylesheet first, then calls bootstrap(). Routes are built here, after\n * registration, so overrides take effect.\n */\nexport async function bootstrap(opts: BootstrapOptions = {}) {\n const root = opts.rootElement ?? document.getElementById(\"root\");\n if (!root) {\n throw new Error('bootstrap: no mount element (pass rootElement or add <div id=\"root\">)');\n }\n const queryClient = opts.queryClient ?? createAppQueryClient();\n // Auto-register redirects for page-less chat-doctypes (best-effort, bounded)\n // BEFORE routes are built, so their /app/{slug}/{name} links resolve.\n await registerChatDoctypeRedirects();\n const router = createBrowserRouter(buildRoutes());\n\n createRoot(root).render(\n <StrictMode>\n <QueryClientProvider client={queryClient}>\n <AuthProvider>\n <RouterProvider router={router} />\n </AuthProvider>\n </QueryClientProvider>\n </StrictMode>,\n );\n}\n","// Inline arm-to-confirm button for low-stakes, in-row actions (e.g. removing a\n// row from a list). On first click it splits in place into \"Cancel | Confirm\",\n// with **Cancel occupying the trigger's original position** — so an accidental\n// double-click's second click lands on Cancel and nothing happens. It\n// auto-collapses after `timeout` ms or on pointer-leave.\n//\n// For heavier or destructive actions (deleting a whole record), prefer the\n// modal useConfirm() from dialog.tsx instead — a transient inline split in a\n// busy toolbar is more clutter than a focused dialog.\nimport { useEffect, useRef, useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { cn } from \"@/lib/utils\";\n\ninterface ConfirmButtonProps {\n onConfirm: () => void;\n /** Resting trigger content (icon or text). */\n children: React.ReactNode;\n confirmLabel?: React.ReactNode;\n cancelLabel?: React.ReactNode;\n title?: string; // tooltip on the resting trigger\n danger?: boolean; // red confirm (default true)\n disabled?: boolean;\n className?: string; // applied to the resting trigger\n timeout?: number; // auto-collapse ms (default 4000)\n /** Armed-button size: \"sm\" (compact, for icon triggers — default) or \"md\"\n * (normal button height, to match a full-size labelled trigger). */\n size?: \"sm\" | \"md\";\n /** Which side the Cancel button sits on when armed. It should land where the\n * trigger was so a double-click cancels: \"left\" for a left-aligned trigger\n * (default), \"right\" for a right-aligned one (e.g. a toolbar delete button). */\n cancelSide?: \"left\" | \"right\";\n}\n\nexport function ConfirmButton({\n onConfirm,\n children,\n confirmLabel,\n cancelLabel,\n title,\n danger = true,\n disabled,\n className,\n timeout = 4000,\n size = \"sm\",\n cancelSide = \"left\",\n}: ConfirmButtonProps) {\n const { t } = useTranslation();\n const [armed, setArmed] = useState(false);\n const timer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n\n useEffect(() => {\n if (!armed) return;\n timer.current = setTimeout(() => setArmed(false), timeout);\n return () => clearTimeout(timer.current);\n }, [armed, timeout]);\n\n if (!armed) {\n return (\n <button\n type=\"button\"\n disabled={disabled}\n title={title}\n onClick={() => setArmed(true)}\n className={className}\n >\n {children}\n </button>\n );\n }\n\n const md = size === \"md\";\n const confirmBtn = (\n <button\n key=\"confirm\"\n type=\"button\"\n onClick={() => {\n setArmed(false);\n onConfirm();\n }}\n className={cn(\n \"rounded-md font-medium text-white\",\n md ? \"px-3 py-1.5 text-sm\" : \"px-2 py-1 text-xs\",\n danger ? \"bg-red-600 hover:bg-red-700\" : \"bg-brand hover:bg-brand/90\",\n )}\n >\n {confirmLabel ?? t(\"common.delete\", { defaultValue: \"Delete\" })}\n </button>\n );\n const cancelBtn = (\n <button\n key=\"cancel\"\n type=\"button\"\n onClick={() => setArmed(false)}\n className={cn(\n \"rounded-md\",\n md\n ? \"px-3 py-1.5 text-sm font-medium text-fg ring-1 ring-line hover:bg-surface-subtle\"\n : \"px-2 py-1 text-xs text-fg-muted hover:text-fg\",\n )}\n >\n {cancelLabel ?? t(\"common.cancel\", { defaultValue: \"Cancel\" })}\n </button>\n );\n\n return (\n <span\n className={cn(\"inline-flex items-center\", md ? \"gap-2\" : \"gap-1\")}\n onMouseLeave={() => setArmed(false)}\n >\n {/* Cancel sits at the trigger's original position (cancelSide), so a\n double-click lands on Cancel and nothing happens. */}\n {cancelSide === \"right\" ? [confirmBtn, cancelBtn] : [cancelBtn, confirmBtn]}\n </span>\n );\n}\n"],"names":["BASE","configureApiBase","base","apiUrl","path","ApiError","status","message","formatErrorDetail","detail","item","rec","loc","msg","request","options","res","body","qs","params","clean","v","s","api","sessionId","file","form","id","doctype","name","masterType","data","targetDoctype","company","customer","type","q","results","provider","opts","suffix","email","password","current_password","new_password","role","userName","token","AuthContext","createContext","AuthProvider","children","user","setUser","useState","loading","setLoading","useEffect","u","login","useCallback","register","fullName","inviteToken","logout","refreshUser","jsx","useAuth","ctx","useContext","ChatContext","NAV_FLASH_MAP","MASTER_FLASH_MAP","normalizeDoctype","value","getNavigationFlashFromTool","tool","args","mapPersistedMessage","KNOWN_SESSIONS_KEY","getKnownSessionIds","raw","parsed","writeKnownSessionIds","ids","rememberSessionId","forgetSessionId","makeRequestId","toSortTime","timestamp","ChatProvider","queryClient","useQueryClient","sessions","setSessions","messagesBySession","setMessagesBySession","hasMoreBySession","setHasMoreBySession","oldestIdBySession","setOldestIdBySession","loadingOlderBySession","setLoadingOlderBySession","thinkingBySession","setThinkingBySession","demoStatusBySession","setDemoStatusBySession","demoTypingCueBySession","setDemoTypingCueBySession","navigationFlash","setNavigationFlash","connectionStatus","setConnectionStatus","connectionVersion","setConnectionVersion","wsRef","useRef","reconnectTimerRef","pendingRequestsRef","pendingCreateSessionRef","lastMessageAtRef","pendingToolCallsRef","navFlashTimeoutRef","rejectPendingRequests","pending","updateSessionMessages","updater","prev","setSessionThinking","setSessionDemoStatus","setSessionDemoTypingCue","triggerNavigationFlash","group","sortSessionsByMessageActivity","sessionList","left","right","leftTime","updateSessionList","recordSessionMessage","nextTimestamp","currentTimestamp","hydrateLastMessageTimes","next","session","sendRaw","payload","ws","sendRequest","expectedType","resolve","reject","requestId","error","disposed","connect","wsUrl","event","eventType","nextSessions","serverIds","missing","row","fetched","resolved","p","entry","nextLastMessageAt","persisted","isPrepend","hasMore","oldestId","existing","existingIds","filtered","title","lastPersistedMessage","prior","m","model","content","pendingToolCall","backendReportId","argReportId","_a","flashTarget","createSession","promise","startDemo","completeDemoTyping","seq","deleteSession","loadHistory","loadMoreHistory","clearHistory","sendMessage","attachmentIds","trimmed","hasAttachments","transcribeAudio","audioBase64","audioFormat","getMessages","isThinking","hasMoreHistory","isLoadingOlder","getDemoStatus","getDemoTypingCue","useChat","context","cn","classes","formatCurrency","currency","formatNumber","decimals","dateLocale","setDateLocale","locale","formatDate","flt","precision","n","variantClasses","sizeClasses","Button","variant","size","disabled","onClick","className","Input","label","hint","props","inputId","DialogContext","DialogProvider","t","useTranslation","state","setState","setValue","confirm","prompt","useMemo","settle","result","onConfirm","onCancel","jsxs","e","useDialog","useConfirm","usePrompt","NAV_GROUPS","BookOpen","ShoppingCart","CreditCard","FileText","Package","BarChart3","Database","Settings","getNavGroups","registerNavGroup","g","registerNavItem","groupLabel","branding","configureBranding","root","key","getBranding","STORAGE_KEY","getCollapsed","setCollapsed","collapsed","useSidebarToggle","open","setOpen","toggle","expand","FLASH_STYLES","ChatGroup","location","useLocation","navigate","useNavigate","handleNewChat","handleDelete","MessageCircle","ChevronDown","ChevronRight","Plus","active","NavLink","ActiveAccent","Trash2","CustomAnalyticsGroup","isGroupFlashing","flashStyle","useQuery","drafts","deleteMutation","useMutation","_result","handleNew","prefill","targetSessionId","LineChart","draft","isItemFlashing","SidebarGroup","end","other","isActive","Fragment","HIDDEN_PATHS","Sidebar","isMobileOpen","onClose","settings","setupStatus","firstCompany","companyName","groups","settingKey","titleCase","slug","c","deriveTitle","pathname","parts","cap","one","deriveBackPath","AppShell","AppShellContent","pageTitle","backPath","handleBack","mobileOpen","setMobileOpen","ArrowLeft","Outlet","ProtectedRoute","Navigate","Card","interactive","Badge","dot","STATUS_VARIANT_MAP","StatusBadge","useBaseCurrency","companies","match","MetricCard","Icon","tone","toneClass","baseCurrency","fmtCurrency","MetricCardSkeleton","DOCTYPE_ICON","Receipt","Wallet","RecentDocumentRow","doc","date","href","Link","RecentDocumentRowSkeleton","DashboardPage","isLoading","TrendingUp","ArrowDownRight","ArrowUpRight","idx","KEY","readAll","setListContext","all","getListContext","useDocumentList","filters","refetch","useUrlPatch","setParams","useSearchParams","patch","useUrlState","defaultValue","ITEM_FIELDS","QUOTATION_ITEM_FIELDS","CURRENCY_FIELD","TAX_FIELDS","CONFIGS","getDoctypeConfig","registerDoctype","config","getAllDoctypeConfigs","DocPager","onSave","kind","isMaster","goPrev","goNext","back","onKey","el","btn","ChevronLeft","normalizeOption","opt","Select","onChange","required","selectId","l","HintTooltip","text","visible","setVisible","NotesMarkupHelp","rows","Info","syntax","desc","useCurrencies","enabled","LINKABLE_MASTERS","linkRefHref","linkDoctype","FieldLabel","extra","LinkField","field","hideLabel","query","setQuery","wrapRef","menuRect","setMenuRect","update","r","createPortal","FieldRenderer","readOnly","rowData","isDisabled","Label","needsCurrencyOptions","currencyOptions","resolvedLinkDoctype","display","pClass","resolvedField","showMarkupHelp","inputType","ChildTableEditor","tableDef","updateRow","fieldName","updated","i","addRow","blank","f","removeRow","_","DocumentActions","isNew","docstatus","discarded","saving","onSubmit","onConvert","onDiscard","confirmingCancel","setConfirmingCancel","confirmingDiscard","setConfirmingDiscard","pdfUrl","showCancel","conv","recalculate","formData","ct","sum","tax","totalTax","DocumentFormPage","useParams","setFormData","currencyTouched","setCurrencyTouched","existingDoc","hasCurrencyField","partyType","partyName","companyCurrency","partyMaster","suggested","defaults","createMut","updateMut","submitMut","cancelMut","discardMut","convertMut","targetSlug","setField","setChildTable","handleSave","handleSubmit","handleCancel","handleConvert","handleDiscard","docCurrency","docRate","editableFields","gridFields","noteFields","totalsFields","iso","d","startOfWeek","day","diff","endOfWeek","startOfMonth","endOfMonth","startOfQuarter","endOfQuarter","startOfYear","endOfYear","PRESETS","now","lastMonth","lastQuarter","lastYear","DateRangePresets","onSelect","from","to","SingleDatePresets","STATUS_OPTIONS","CURRENCY_FIELDS","DATE_FIELDS","MASTER_REF_FIELDS","partyMasterType","PAGE_SIZE_OPTIONS","ListPager","page","totalPages","pageSize","total","rangeStart","rangeEnd","setPage","setPageSize","pageInput","setPageInput","commit","DocumentListPage","configFilters","filterValues","out","fromDate","toDate","showDiscarded","searchFields","urlQ","searchInput","setSearchInput","urlPage","patchUrl","setStatus","setFromDate","setToDate","setShowDiscarded","on","limit","offset","ctxFilters","columns","helper","createColumnHelper","headerLabel","titleCased","w","col","info","table","useReactTable","getCoreRowModel","o","headerGroup","header","flexRender","cell","setResults","dropdownStyle","setDropdownStyle","debounceRef","containerRef","dropdownRef","inputRef","selectingRef","updateDropdownPosition","rect","search","handleInputChange","handleSelect","handleBlur","handler","target","_b","blankRow","LETTERS","ProposalForm","qc","tr","k","dflt","setForm","setRows","appendix","setAppendix","appendixBusy","setAppendixBusy","setError","fileRef","set","loadCoverDefault","cover_letter","saveMut","rs","j","moveRow","dir","onPickAppendix","err","removeAppendix","MasterListPage","notice","val","MASTER_FIELDS","TYPE_LABELS","AUTO_NAME_TYPES","MasterFormPage","labelTr","fields","fieldLabel","current","deleteMut","missingRequiredFields","isReadOnly","isRequired","useTrialBalance","useChartOfAccounts","useGeneralLedger","useStockBalance","useProfitAndLoss","useBalanceSheet","useArAging","useApAging","TrialBalancePage","urlCompany","urlFromDate","urlToDate","setCompany","handleApply","isBalanced","ROOT_ORDER","ChartOfAccountsPage","currentYear","year","setYear","yearOptions","fmt","accounts","childrenOf","rootsByType","byName","a","acc","list","glLink","renderRow","depth","kids","isCollapsed","dim","kid","rt","rootType","toSlug","voucherType","GeneralLedgerPage","urlAccount","urlParty","account","setAccount","party","setParty","StockBalancePage","urlItemCode","urlWarehouse","itemCode","setItemCode","warehouse","setWarehouse","ProfitLossPage","hasData","SectionTable","totalLabel","BalanceSheetPage","urlAsOfDate","asOfDate","setAsOfDate","_c","ArAgingPage","ApAgingPage","buildExampleCustomReport","today","start","EXAMPLE_CUSTOM_REPORT","AnalyticsPage","reportId","metric","groupBy","urlFrom","urlTo","customSpec","setCustomSpec","runtimeData","setRuntimeData","runtimeOutput","setRuntimeOutput","runtimeError","setRuntimeError","running","setRunning","loadingDraft","setLoadingDraft","sourceChatSessionId","setSourceChatSessionId","workerRef","loadedDraftRef","loadedSpecRef","runIdRef","legacySpecText","buildLegacyRuntimeSpec","onRunCustom","specText","runId","isCurrent","spec","dataResponse","worker","ReportRuntimeWorker","timer","cancelled","nextSpec","showLegacyBanner","renderIssues","describeRuntimeOutputIssues","onFixInChat","isDirty","reportLabel","preview","dataset","RuntimeReportRenderer","output","tables","chartTables","buildChartTableIndex","kpi","formatRuntimeValue","chart","xLabels","layout","computeAxisLayout","containerHeight","ResponsiveContainer","CartesianGrid","XAxis","YAxis","shortNum","Tooltip","inferFormat","Line","PieChart","Pie","rowIdx","Cell","PIE_COLORS","BarChart","Bar","column","labelFor","map","issues","legacyMetricLabel","timeBucket","buildGroupedAmountSpec","isReceived","isAr","partyField","amountField","bucketExpr","abs","AXIS_TICK_FONT","_measureCanvas","measureTextWidth","font","labels","widths","maxWidth","angle","radians","projected","axisHeight","CURRENCY_OPTIONS","SetupPage","setCompanyName","setCurrency","details","setDetails","setDetail","seedMode","setSeedMode","success","setSuccess","historyStats","setHistoryStats","createCompanyMut","seedDemoMut","seedHistoryMut","handleSetup","CompanyRow","b","isPending","cityCountry","STEPS","useTryInChat","CompanySetupHighlight","tryInChat","CustomAnalyticsHighlight","samplePrompts","FlowDiagram","chip","LifecycleCard","TutorialPage","step","MAX_ATTACHMENTS","MAX_ATTACHMENT_SIZE","ALLOWED_MIMES","ALLOWED_EXTS","wait","ms","blobToBase64","blob","reader","formatTime","ts","formatFullTimestamp","ChatPage","searchParams","demoRequested","input","setInput","demoError","setDemoError","attachments","setAttachments","attachmentError","setAttachmentError","isDragOver","setIsDragOver","voiceState","setVoiceState","fileInputRef","mediaRecorderRef","audioChunksRef","getIsThinking","scrollContainerRef","messagesEndRef","inputAreaRef","inputAreaHeight","setInputAreaHeight","previousThinkingRef","demoRunStartedRef","demoTypingRunIdRef","shouldAutoScrollRef","pendingPrependHeightRef","programmaticScrollRef","programmaticScrollTimerRef","messages","isConnected","demoStatus","demoTypingCue","isDemoReplaying","canLoadOlder","loadingOlder","lastMessage","lastMessageKey","markProgrammaticScroll","scrollToBottom","behavior","rescroll","useLayoutEffect","prevHeight","delta","raf","observer","handleLoadOlder","consumedNavStateRef","navState","loadHistoryRef","handleMessagesScroll","distanceFromBottom","completeDemoTypingRef","typedCueSeqRef","typingContent","charDelay","typingSeq","animateTyping","char","addFiles","fileList","incoming","ext","localId","previewUrl","removeAttachment","victim","handleDragOver","handleDragLeave","related","handleDrop","handlePaste","files","hasUnfinishedUploads","hasFailedUploads","readyAttachmentIds","sendCurrentMessage","att","handleKeyDown","appendTranscript","startRecording","stream","recorder","track","chunks","mimeType","format","base64","stopRecording","toggleRecording","suggestion","MessageBubble","AttachmentThumbs","url","isImage","MarkdownContent","lines","elements","inCodeBlock","codeLines","line","formatInline","renderLink","isSpaRoute","baseClass","BARE_URL_RE","part","linkMatch","linkifyBare","keyPrefix","nodes","lastIndex","re","matched","trailing","LoginPage","mode","setMode","registrationOpen","setRegistrationOpen","firstRun","setFirstRun","oauthProviders","setOauthProviders","setEmail","setFullName","setPassword","confirmPassword","setConfirmPassword","code","ProviderIcon","providerLabel","DemoPage","startedRef","emptyAccountRow","emptyStockRow","emptyInvoiceRow","OpeningBalancesPage","postingDate","setPostingDate","accountRows","setAccountRows","stockRows","setStockRows","invoiceRows","setInvoiceRows","accountMut","stockMut","invoiceMut","UsersPage","currentUser","users","invites","inviteEmail","setInviteEmail","inviteRole","setInviteRole","inviteResult","setInviteResult","inviteMut","changeRoleMut","disableMut","revokeMut","copiedToken","setCopiedToken","inviteLink","copyInviteLink","invite","SUPPORTED_LANGUAGES","isSupported","getStoredLanguage","storeLanguage","i18n","initReactI18next","en","de","fr","LanguageSelect","DEMO_SPEND_WINDOWS","fmtUsd","TokenSpendCard","demoActive","windowKey","setWindowKey","isFetching","dataUpdatedAt","windowSpec","window","demoCap","demoUsdPerHour","totalUsdPerHour","capPct","capColor","Stat","ChangePasswordCard","setCurrent","setNext","setConfirm","done","setDone","mut","submit","SetPasswordCard","LinkedAccountsCard","setup","identities","providers","linked","isLinked","ROLE_RANK","ApiKeysSection","ownRole","me","setName","setRole","newToken","setNewToken","roleOptions","mcpUrl","claudeSnippet","codexSnippet","keys","isMine","ownerLabel","byOwner","mine","gid","runAction","action","act","ApiToggleRow","onToggle","statusOn","statusOff","ApiAccessCard","chatEnabled","restEnabled","onToggleChat","onToggleRest","confirmOff","setConfirmOff","SettingsPage","isAdmin","settingsMut","pubStatus","health","showConfirm","setShowConfirm","createPubMut","removePubMut","COMPONENTS","registerComponent","component","getComponent","fallback","DashboardRoute","C","Dashboard","baseTopRoutes","Login","Demo","baseChildRoutes","Setup","OpeningBalances","Tutorial","Chat","DocumentList","DocumentForm","MasterList","MasterForm","ChartOfAccounts","TrialBalance","GeneralLedger","StockBalance","ProfitLoss","BalanceSheet","ArAging","ApAging","Analytics","Users","GeneralSettings","extraTopRoutes","extraChildRoutes","registerRoute","route","routeKey","mergeRoutes","buildRoutes","ChatDoctypeRedirect","parentSlug","linkField","alive","parent","registerChatDoctypeRedirects","createAppQueryClient","QueryClient","bootstrap","router","createBrowserRouter","createRoot","StrictMode","QueryClientProvider","RouterProvider","ConfirmButton","confirmLabel","cancelLabel","danger","timeout","cancelSide","armed","setArmed","md","confirmBtn","cancelBtn"],"mappings":"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"}
|