sea-dev 1.0.0
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/.claude/tasks/README.md +89 -0
- package/.cursor/rules/commits.mdc +31 -0
- package/.cursor/rules/general.mdc +84 -0
- package/.github/workflows/ci-cd.yml +141 -0
- package/CLAUDE.md +337 -0
- package/README.md +129 -0
- package/apps/api/.prettierignore +6 -0
- package/apps/api/.prettierrc.js +3 -0
- package/apps/api/dotenvx-safe.sh +11 -0
- package/apps/api/eslint.config.mjs +3 -0
- package/apps/api/package.json +58 -0
- package/apps/api/src/clients/posthog.ts +25 -0
- package/apps/api/src/dal/submission.ts +59 -0
- package/apps/api/src/errors.ts +55 -0
- package/apps/api/src/index.ts +21 -0
- package/apps/api/src/lib/channel.ts +28 -0
- package/apps/api/src/lib/config.ts +9 -0
- package/apps/api/src/lib/fmt.test.ts +9 -0
- package/apps/api/src/lib/fmt.ts +62 -0
- package/apps/api/src/lib/invariant.ts +23 -0
- package/apps/api/src/middleware/auth.ts +66 -0
- package/apps/api/src/routes/index.ts +20 -0
- package/apps/api/src/routes/v2/chat/handlers.ts +693 -0
- package/apps/api/src/routes/v2/chat/index.ts +257 -0
- package/apps/api/src/routes/v2/chat/schemas.ts +43 -0
- package/apps/api/src/routes/v2/deals/handlers.ts +64 -0
- package/apps/api/src/routes/v2/deals/index.ts +88 -0
- package/apps/api/src/routes/v2/deals/schemas.ts +38 -0
- package/apps/api/src/routes/v2/forms/handlers.ts +415 -0
- package/apps/api/src/routes/v2/forms/index.ts +382 -0
- package/apps/api/src/routes/v2/forms/schemas.ts +243 -0
- package/apps/api/src/routes/v2/index.ts +19 -0
- package/apps/api/src/routes/v2/pipelines/handlers.ts +261 -0
- package/apps/api/src/routes/v2/pipelines/index.ts +224 -0
- package/apps/api/src/routes/v2/pipelines/schemas.ts +173 -0
- package/apps/api/src/routes/v2/submissions/handlers.ts +555 -0
- package/apps/api/src/routes/v2/submissions/index.ts +366 -0
- package/apps/api/src/routes/v2/submissions/schemas.ts +233 -0
- package/apps/api/src/routes/v2/workflows/handlers.ts +81 -0
- package/apps/api/src/routes/v2/workflows/index.ts +88 -0
- package/apps/api/src/routes/v2/workflows/schemas.ts +40 -0
- package/apps/api/src/server.ts +146 -0
- package/apps/api/src/static/favicon.ico +0 -0
- package/apps/api/src/types/api.ts +14 -0
- package/apps/api/src/types/result.ts +3 -0
- package/apps/api/tsconfig.json +22 -0
- package/apps/api/vite.config.ts +28 -0
- package/apps/api/vitest.config.ts +14 -0
- package/apps/conversion-worker/Dockerfile +59 -0
- package/apps/conversion-worker/package.json +31 -0
- package/apps/conversion-worker/src/lib/config.ts +7 -0
- package/apps/conversion-worker/src/main.ts +22 -0
- package/apps/conversion-worker/src/workflows/convert-pptx.ts +116 -0
- package/apps/conversion-worker/tsconfig.json +27 -0
- package/apps/conversion-worker/vite.config.ts +33 -0
- package/apps/main/.prettierignore +6 -0
- package/apps/main/.prettierrc.js +3 -0
- package/apps/main/CLAUDE.md +245 -0
- package/apps/main/Procfile +1 -0
- package/apps/main/README.md +193 -0
- package/apps/main/db-tests.jsonl +116 -0
- package/apps/main/dotenvx-safe.sh +11 -0
- package/apps/main/drizzle/meta/_journal.json +1 -0
- package/apps/main/drizzle.config.ts +25 -0
- package/apps/main/eslint.config.mjs +3 -0
- package/apps/main/generate-routes.mjs +5 -0
- package/apps/main/package.json +131 -0
- package/apps/main/playwright.config.ts +23 -0
- package/apps/main/postcss.config.ts +5 -0
- package/apps/main/public/bg-dark.svg +10 -0
- package/apps/main/public/bg.svg +10 -0
- package/apps/main/public/favicon.ico +0 -0
- package/apps/main/run.sh +146 -0
- package/apps/main/scripts/browser.ts +14 -0
- package/apps/main/scripts/db-test-cov.ts +277 -0
- package/apps/main/scripts/login.ts +78 -0
- package/apps/main/scripts/repl.ts +61 -0
- package/apps/main/src/_foo.ts +31 -0
- package/apps/main/src/_tests/db.test.ts +19 -0
- package/apps/main/src/_tests/mock-db.ts +60 -0
- package/apps/main/src/client.tsx +13 -0
- package/apps/main/src/clients/loops.ts +13 -0
- package/apps/main/src/clients/polar.ts +12 -0
- package/apps/main/src/clients/posthog.ts +12 -0
- package/apps/main/src/components/chat/chat-context.tsx +99 -0
- package/apps/main/src/components/chat/chat-messages.tsx +184 -0
- package/apps/main/src/components/chat/chat-status.tsx +140 -0
- package/apps/main/src/components/chat/chat.tsx +458 -0
- package/apps/main/src/components/chat/citation-modal.tsx +54 -0
- package/apps/main/src/components/cta.tsx +21 -0
- package/apps/main/src/components/data-display/derived.tsx +40 -0
- package/apps/main/src/components/data-display/group-single.tsx +57 -0
- package/apps/main/src/components/data-display/group-table.tsx +165 -0
- package/apps/main/src/components/data-display/group-wrapper.tsx +54 -0
- package/apps/main/src/components/data-display/item.tsx +678 -0
- package/apps/main/src/components/error.tsx +45 -0
- package/apps/main/src/components/forms/error.tsx +22 -0
- package/apps/main/src/components/grid.tsx +7 -0
- package/apps/main/src/components/header/container.tsx +73 -0
- package/apps/main/src/components/header/header-bar.tsx +102 -0
- package/apps/main/src/components/modals/copy-display.tsx +37 -0
- package/apps/main/src/components/modals/copy-form.tsx +152 -0
- package/apps/main/src/components/modals/duplicate-workflow.tsx +89 -0
- package/apps/main/src/components/modals/field-correction.tsx +323 -0
- package/apps/main/src/components/modals/form-viewer.tsx +126 -0
- package/apps/main/src/components/modals/modals.tsx +44 -0
- package/apps/main/src/components/modals/new-deal.tsx +78 -0
- package/apps/main/src/components/modals/new-form.tsx +133 -0
- package/apps/main/src/components/modals/new-pipeline.tsx +70 -0
- package/apps/main/src/components/modals/new-submission.tsx +321 -0
- package/apps/main/src/components/modals/new-workflow.tsx +342 -0
- package/apps/main/src/components/modals/transformation-sources-modal.tsx +157 -0
- package/apps/main/src/components/modals/view-report.tsx +193 -0
- package/apps/main/src/components/not-found.tsx +14 -0
- package/apps/main/src/components/search/search-bar.tsx +178 -0
- package/apps/main/src/components/sheet-selector.tsx +135 -0
- package/apps/main/src/components/side-panel/doc-list.tsx +480 -0
- package/apps/main/src/components/sidebar/admin-sidebar.tsx +75 -0
- package/apps/main/src/components/sidebar/app-sidebar.tsx +417 -0
- package/apps/main/src/components/sidebar/model-select.tsx +134 -0
- package/apps/main/src/components/sidebar/settings-sidebar.tsx +132 -0
- package/apps/main/src/components/sidebar/sidebar-right.tsx +22 -0
- package/apps/main/src/components/sidebar/stop-impersonate.tsx +21 -0
- package/apps/main/src/components/svg/loading.tsx +33 -0
- package/apps/main/src/components/theme-selector.tsx +43 -0
- package/apps/main/src/components/unsaved-badge.tsx +19 -0
- package/apps/main/src/components/upload/file-upload.tsx +354 -0
- package/apps/main/src/fns/submission-groups.ts +28 -0
- package/apps/main/src/fns/submission-items.ts +11 -0
- package/apps/main/src/global-middleware.ts +16 -0
- package/apps/main/src/hooks/use-update-state.ts +18 -0
- package/apps/main/src/lib/auth-client.ts +16 -0
- package/apps/main/src/lib/auth.test.ts +359 -0
- package/apps/main/src/lib/auth.ts +144 -0
- package/apps/main/src/lib/billing.ts +23 -0
- package/apps/main/src/lib/config-iso.ts +76 -0
- package/apps/main/src/lib/config.ts +61 -0
- package/apps/main/src/lib/excel.ts +16 -0
- package/apps/main/src/lib/feedback-cache.ts +70 -0
- package/apps/main/src/lib/logger.ts +44 -0
- package/apps/main/src/lib/models.ts +22 -0
- package/apps/main/src/lib/not-found.ts +17 -0
- package/apps/main/src/lib/pdf.ts +16 -0
- package/apps/main/src/lib/tabularize.ts +54 -0
- package/apps/main/src/lib/utils.ts +10 -0
- package/apps/main/src/lib/zfd.ts +217 -0
- package/apps/main/src/middleware.ts +55 -0
- package/apps/main/src/routeTree.gen.ts +1255 -0
- package/apps/main/src/router.tsx +24 -0
- package/apps/main/src/routes/__root.tsx +92 -0
- package/apps/main/src/routes/_authed/_app/(dashboard)/index.tsx +227 -0
- package/apps/main/src/routes/_authed/_app/agents/$agentId/config.tsx +224 -0
- package/apps/main/src/routes/_authed/_app/agents/$agentId/index.tsx +206 -0
- package/apps/main/src/routes/_authed/_app/agents/-components/agent-actions-menu.tsx +94 -0
- package/apps/main/src/routes/_authed/_app/agents/-components/agent-artifacts.tsx +153 -0
- package/apps/main/src/routes/_authed/_app/agents/-components/agent-chat.tsx +220 -0
- package/apps/main/src/routes/_authed/_app/agents/-components/agent-history-menu.tsx +81 -0
- package/apps/main/src/routes/_authed/_app/agents/-components/agent-model-select.tsx +84 -0
- package/apps/main/src/routes/_authed/_app/agents/-components/agent-relevant-items.tsx +226 -0
- package/apps/main/src/routes/_authed/_app/agents/-components/agent-upload-button.tsx +298 -0
- package/apps/main/src/routes/_authed/_app/agents/-components/context-modal.tsx +187 -0
- package/apps/main/src/routes/_authed/_app/agents/-fns.ts +560 -0
- package/apps/main/src/routes/_authed/_app/agents/index.tsx +65 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/$subId/-components/citation-tree.tsx +268 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/$subId.tsx +655 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/doc-loading.tsx +37 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/share-link.tsx +42 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/submission-card.tsx +89 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/submission-filter.tsx +193 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/submissions.tsx +36 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/summary.tsx +82 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/upload-doc.tsx +120 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/-fns.ts +653 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/index.tsx +259 -0
- package/apps/main/src/routes/_authed/_app/deals/$dealId/route.tsx +29 -0
- package/apps/main/src/routes/_authed/_app/deals/index.tsx +104 -0
- package/apps/main/src/routes/_authed/_app/feedback/index.tsx +639 -0
- package/apps/main/src/routes/_authed/_app/feedback/insights.tsx +250 -0
- package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/$runId/-components/blockers-panel.tsx +260 -0
- package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/$runId/-components/manual-input-panel.tsx +301 -0
- package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/$runId/-components/submission-selector-modal.tsx +143 -0
- package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/$runId/-components/upload-doc.tsx +120 -0
- package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/$runId/index.tsx +1485 -0
- package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/-components/dag-view.tsx +296 -0
- package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/-components/step-config-modal.tsx +634 -0
- package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/index.tsx +911 -0
- package/apps/main/src/routes/_authed/_app/pipelines/-fns.ts +510 -0
- package/apps/main/src/routes/_authed/_app/pipelines/index.tsx +103 -0
- package/apps/main/src/routes/_authed/_app/reports/$reportId.tsx +397 -0
- package/apps/main/src/routes/_authed/_app/reports/-fns.ts +11 -0
- package/apps/main/src/routes/_authed/_app/reports/index.tsx +22 -0
- package/apps/main/src/routes/_authed/_app/route.tsx +48 -0
- package/apps/main/src/routes/_authed/_app/submissions/-columns.tsx +161 -0
- package/apps/main/src/routes/_authed/_app/submissions/-fns.ts +128 -0
- package/apps/main/src/routes/_authed/_app/submissions/index.tsx +190 -0
- package/apps/main/src/routes/_authed/_app/workflows/$wfSlug/$formId.tsx +542 -0
- package/apps/main/src/routes/_authed/_app/workflows/$wfSlug/-components/derived.tsx +154 -0
- package/apps/main/src/routes/_authed/_app/workflows/$wfSlug/-components/field.tsx +369 -0
- package/apps/main/src/routes/_authed/_app/workflows/$wfSlug/-components/group.tsx +475 -0
- package/apps/main/src/routes/_authed/_app/workflows/$wfSlug/index.tsx +263 -0
- package/apps/main/src/routes/_authed/_app/workflows/$wfSlug/route.tsx +33 -0
- package/apps/main/src/routes/_authed/_app/workflows/-components/form-card.tsx +315 -0
- package/apps/main/src/routes/_authed/_app/workflows/index.tsx +86 -0
- package/apps/main/src/routes/_authed/admin/index.tsx +12 -0
- package/apps/main/src/routes/_authed/admin/route.tsx +42 -0
- package/apps/main/src/routes/_authed/admin/users/-columns.tsx +124 -0
- package/apps/main/src/routes/_authed/admin/users/-fns.ts +30 -0
- package/apps/main/src/routes/_authed/admin/users/index.tsx +29 -0
- package/apps/main/src/routes/_authed/catchNotFound.tsx +114 -0
- package/apps/main/src/routes/_authed/redirects/forms.$id.tsx +29 -0
- package/apps/main/src/routes/_authed/redirects/submissions.$id.tsx +27 -0
- package/apps/main/src/routes/_authed/redirects/workflows.$id.tsx +27 -0
- package/apps/main/src/routes/_authed/route.tsx +51 -0
- package/apps/main/src/routes/_authed/settings/-components/new-api-key.tsx +85 -0
- package/apps/main/src/routes/_authed/settings/-components/new-invite.tsx +100 -0
- package/apps/main/src/routes/_authed/settings/analytics.tsx +1710 -0
- package/apps/main/src/routes/_authed/settings/billing/-components/price-table.tsx +129 -0
- package/apps/main/src/routes/_authed/settings/billing/-fns.ts +76 -0
- package/apps/main/src/routes/_authed/settings/billing/index.tsx +119 -0
- package/apps/main/src/routes/_authed/settings/embed.tsx +337 -0
- package/apps/main/src/routes/_authed/settings/index.tsx +12 -0
- package/apps/main/src/routes/_authed/settings/keys.tsx +157 -0
- package/apps/main/src/routes/_authed/settings/members.tsx +276 -0
- package/apps/main/src/routes/_authed/settings/route.tsx +22 -0
- package/apps/main/src/routes/_authed/settings/user.tsx +87 -0
- package/apps/main/src/routes/_authed/settings/workspace.tsx +206 -0
- package/apps/main/src/routes/_public/-components/sign-in-up.tsx +96 -0
- package/apps/main/src/routes/_public/embedded.tsx +57 -0
- package/apps/main/src/routes/_public/invite.$inviteId.tsx +143 -0
- package/apps/main/src/routes/_public/no-access.tsx +38 -0
- package/apps/main/src/routes/_public/no-invite.tsx +39 -0
- package/apps/main/src/routes/_public/otp.tsx +103 -0
- package/apps/main/src/routes/_public/route.tsx +15 -0
- package/apps/main/src/routes/_public/sign-in.tsx +111 -0
- package/apps/main/src/routes/_public/sign-up.tsx +114 -0
- package/apps/main/src/routes/api/auth/$.ts +11 -0
- package/apps/main/src/routes/api/billing/paid.ts +42 -0
- package/apps/main/src/routes/api/billing/webhooks.ts +70 -0
- package/apps/main/src/routes/api/chat/agent.ts +40 -0
- package/apps/main/src/routes/api/chat/key.ts +42 -0
- package/apps/main/src/routes/api/chat/member.ts +35 -0
- package/apps/main/src/routes/api/test/index.ts +19 -0
- package/apps/main/src/server.tsx +6 -0
- package/apps/main/src/styles/app.css +23 -0
- package/apps/main/src/vite-env.d.ts +7 -0
- package/apps/main/test.http +6 -0
- package/apps/main/tsconfig.json +17 -0
- package/apps/main/vite.config.ts +24 -0
- package/apps/main/vitest.config.js +17 -0
- package/apps/mcp/README.md +171 -0
- package/apps/mcp/eslint.config.mjs +3 -0
- package/apps/mcp/package.json +37 -0
- package/apps/mcp/src/index.ts +414 -0
- package/apps/mcp/tsconfig.json +19 -0
- package/apps/mcp/vite.config.ts +22 -0
- package/apps/posthog-proxy/index.html +9 -0
- package/apps/workers/.prettierignore +7 -0
- package/apps/workers/.prettierrc.js +3 -0
- package/apps/workers/dotenvx-safe.sh +11 -0
- package/apps/workers/eslint.config.mjs +3 -0
- package/apps/workers/package.json +65 -0
- package/apps/workers/src/lib/config.ts +7 -0
- package/apps/workers/src/lib/messages.ts +0 -0
- package/apps/workers/src/lib/posthog.ts +25 -0
- package/apps/workers/src/main.ts +58 -0
- package/apps/workers/src/workflows/extraction.ts +866 -0
- package/apps/workers/src/workflows/index.ts +3 -0
- package/apps/workers/src/workflows/pipeline-dag.ts +210 -0
- package/apps/workers/src/workflows/pipeline-steps.ts +1393 -0
- package/apps/workers/tsconfig.json +16 -0
- package/apps/workers/vite.config.ts +35 -0
- package/docs/CHANGELOG.md +84 -0
- package/docs/agent-templates-and-runs.md +859 -0
- package/docs/aws-migration-plan.md +267 -0
- package/docs/impl-p0-form-builder-improvements.md +683 -0
- package/docs/on-prem-deployment-spec.docx +0 -0
- package/docs/on-prem-deployment-spec.md +378 -0
- package/docs/prd-form-builder-strategy.md +1120 -0
- package/docs/widget-ng-apf-packaging-spec.md +43 -0
- package/infra/k8s/charts/seadotdev/Chart.yaml +6 -0
- package/infra/k8s/charts/seadotdev/templates/_helpers.tpl +27 -0
- package/infra/k8s/charts/seadotdev/templates/api-v2.yaml +105 -0
- package/infra/k8s/charts/seadotdev/templates/external-secrets.yaml +83 -0
- package/infra/k8s/charts/seadotdev/templates/ingress.yaml +54 -0
- package/infra/k8s/charts/seadotdev/templates/main-app.yaml +104 -0
- package/infra/k8s/charts/seadotdev/templates/workers.yaml +182 -0
- package/infra/k8s/charts/seadotdev/values.yaml +143 -0
- package/infra/terraform/main.tf +399 -0
- package/libs/ai/.prettierignore +2 -0
- package/libs/ai/.prettierrc.js +5 -0
- package/libs/ai/README.md +139 -0
- package/libs/ai/eslint.config.mjs +3 -0
- package/libs/ai/package.json +42 -0
- package/libs/ai/src/index.ts +5 -0
- package/libs/ai/src/models.ts +19 -0
- package/libs/ai/src/rag/index.ts +1 -0
- package/libs/ai/src/rag/rag.test.ts +99 -0
- package/libs/ai/src/rag/rag.ts +510 -0
- package/libs/ai/tsconfig.json +21 -0
- package/libs/ai/vite.config.ts +38 -0
- package/libs/cache/.prettierignore +2 -0
- package/libs/cache/eslint.config.mjs +3 -0
- package/libs/cache/package.json +35 -0
- package/libs/cache/src/feedback.ts +77 -0
- package/libs/cache/src/index.ts +2 -0
- package/libs/cache/tsconfig.json +19 -0
- package/libs/cache/vite.config.ts +36 -0
- package/libs/clients/.prettierignore +6 -0
- package/libs/clients/eslint.config.mjs +3 -0
- package/libs/clients/package.json +59 -0
- package/libs/clients/src/azure.ts +249 -0
- package/libs/clients/src/gcp.ts +220 -0
- package/libs/clients/src/hatchet.ts +86 -0
- package/libs/clients/src/index.ts +8 -0
- package/libs/clients/src/loops.ts +86 -0
- package/libs/clients/src/polar.ts +77 -0
- package/libs/clients/src/posthog.ts +55 -0
- package/libs/clients/tsconfig.json +19 -0
- package/libs/clients/vite.config.ts +35 -0
- package/libs/config/.prettierignore +6 -0
- package/libs/config/.prettierrc.js +12 -0
- package/libs/config/eslint.config.mjs +3 -0
- package/libs/config/package.json +50 -0
- package/libs/config/src/azure.ts +54 -0
- package/libs/config/src/db.ts +18 -0
- package/libs/config/src/gcp.ts +53 -0
- package/libs/config/src/google.ts +17 -0
- package/libs/config/src/hatchet.ts +20 -0
- package/libs/config/src/index.ts +108 -0
- package/libs/config/src/llm.ts +17 -0
- package/libs/config/src/polar.ts +24 -0
- package/libs/config/src/util.ts +8 -0
- package/libs/config/src/vercel.ts +26 -0
- package/libs/config/tsconfig.json +19 -0
- package/libs/config/vite.config.ts +34 -0
- package/libs/core/.prettierignore +2 -0
- package/libs/core/eslint.config.mjs +3 -0
- package/libs/core/package.json +59 -0
- package/libs/core/src/chat/derived.ts +97 -0
- package/libs/core/src/chat/feedback.ts +293 -0
- package/libs/core/src/chat/index.ts +6 -0
- package/libs/core/src/chat/model.ts +92 -0
- package/libs/core/src/chat/prepare-tools.ts +286 -0
- package/libs/core/src/chat/prompts.ts +623 -0
- package/libs/core/src/chat/stream.ts +311 -0
- package/libs/core/src/chat/summarize.ts +168 -0
- package/libs/core/src/chat/tools/agent.ts +403 -0
- package/libs/core/src/chat/tools/chart-agent.ts +526 -0
- package/libs/core/src/chat/tools/chart-helpers/sandbox.ts +47 -0
- package/libs/core/src/chat/tools/chart.ts +86 -0
- package/libs/core/src/chat/tools/credit-agent.ts +1383 -0
- package/libs/core/src/chat/tools/credit.ts +1435 -0
- package/libs/core/src/chat/tools/deep-dive-agent.ts +100 -0
- package/libs/core/src/chat/tools/deep-dive.ts +141 -0
- package/libs/core/src/chat/tools/form.ts +449 -0
- package/libs/core/src/chat/tools/helpers.ts +91 -0
- package/libs/core/src/chat/tools/index.ts +42 -0
- package/libs/core/src/chat/tools/pipeline-artifact.ts +76 -0
- package/libs/core/src/chat/tools/report.ts +40 -0
- package/libs/core/src/chat/tools/search.ts +390 -0
- package/libs/core/src/chat/tools/submission.ts +227 -0
- package/libs/core/src/chat/tools/workflow.ts +684 -0
- package/libs/core/src/chat/types.ts +3 -0
- package/libs/core/src/data-extraction/classification/azure.ts +168 -0
- package/libs/core/src/data-extraction/classification/index.ts +1 -0
- package/libs/core/src/data-extraction/dal.ts +246 -0
- package/libs/core/src/data-extraction/form-structure-extractor.ts +294 -0
- package/libs/core/src/data-extraction/index.ts +4 -0
- package/libs/core/src/data-extraction/layout/azure.ts +730 -0
- package/libs/core/src/data-extraction/layout/excel.ts +180 -0
- package/libs/core/src/data-extraction/layout/gcp.ts +1071 -0
- package/libs/core/src/data-extraction/layout/index.ts +266 -0
- package/libs/core/src/data-extraction/layout/plaintext.ts +45 -0
- package/libs/core/src/data-extraction/models.ts +38 -0
- package/libs/core/src/data-extraction/pdf-utils.ts +96 -0
- package/libs/core/src/data-extraction/structuring/bank-statement.ts +1182 -0
- package/libs/core/src/data-extraction/structuring/custom.ts +495 -0
- package/libs/core/src/data-extraction/structuring/index.ts +290 -0
- package/libs/core/src/data-extraction/structuring/prompts.ts +69 -0
- package/libs/core/src/data-extraction/type-guards.ts +110 -0
- package/libs/core/src/data-extraction/types.ts +84 -0
- package/libs/core/src/data-extraction/utils.ts +31 -0
- package/libs/core/src/data-extraction/validation/bank-statement.ts +127 -0
- package/libs/core/src/deals.ts +17 -0
- package/libs/core/src/documents.ts +152 -0
- package/libs/core/src/index.ts +5 -0
- package/libs/core/src/pipelines/display.ts +678 -0
- package/libs/core/src/pipelines/execute.ts +2342 -0
- package/libs/core/src/pipelines/index.ts +4 -0
- package/libs/core/src/pipelines/list.ts +12 -0
- package/libs/core/src/pipelines/runs.ts +53 -0
- package/libs/core/tsconfig.json +20 -0
- package/libs/core/vite.config.ts +56 -0
- package/libs/dal/.prettierignore +6 -0
- package/libs/dal/.prettierrc.js +12 -0
- package/libs/dal/eslint.config.mjs +3 -0
- package/libs/dal/package.json +57 -0
- package/libs/dal/src/_tests/db.test.ts +19 -0
- package/libs/dal/src/_tests/mock-db.ts +60 -0
- package/libs/dal/src/api-key.test.ts +397 -0
- package/libs/dal/src/api-key.ts +110 -0
- package/libs/dal/src/billing.ts +23 -0
- package/libs/dal/src/conversation.test.ts +655 -0
- package/libs/dal/src/conversation.ts +532 -0
- package/libs/dal/src/deal.test.ts +45 -0
- package/libs/dal/src/deal.ts +87 -0
- package/libs/dal/src/defaults-consumer-lending-uk.ts +33 -0
- package/libs/dal/src/defaults-consumer-lending-us.ts +33 -0
- package/libs/dal/src/defaults-private-credit.ts +57 -0
- package/libs/dal/src/defaults-private-equity.ts +51 -0
- package/libs/dal/src/defaults-smb-lending-us.ts +1569 -0
- package/libs/dal/src/defaults-sme-lending-uk-express.ts +1527 -0
- package/libs/dal/src/defaults-sme-lending-uk.ts +1669 -0
- package/libs/dal/src/defaults-types.ts +23 -0
- package/libs/dal/src/defaults.ts +550 -0
- package/libs/dal/src/document.test.ts +70 -0
- package/libs/dal/src/document.ts +192 -0
- package/libs/dal/src/feedback.ts +255 -0
- package/libs/dal/src/form.test.ts +637 -0
- package/libs/dal/src/form.ts +1165 -0
- package/libs/dal/src/index.ts +20 -0
- package/libs/dal/src/invitation.test.ts +746 -0
- package/libs/dal/src/invitation.ts +207 -0
- package/libs/dal/src/member.test.ts +185 -0
- package/libs/dal/src/member.ts +80 -0
- package/libs/dal/src/organization.ts +116 -0
- package/libs/dal/src/permission.ts +25 -0
- package/libs/dal/src/pipeline.test.ts +388 -0
- package/libs/dal/src/pipeline.ts +4222 -0
- package/libs/dal/src/report.ts +199 -0
- package/libs/dal/src/result.ts +16 -0
- package/libs/dal/src/search.ts +172 -0
- package/libs/dal/src/session.test.ts +110 -0
- package/libs/dal/src/session.ts +31 -0
- package/libs/dal/src/submission.test.ts +1304 -0
- package/libs/dal/src/submission.ts +1396 -0
- package/libs/dal/src/tool.ts +159 -0
- package/libs/dal/src/user.ts +16 -0
- package/libs/dal/src/workflow.test.ts +89 -0
- package/libs/dal/src/workflow.ts +262 -0
- package/libs/dal/tsconfig.build.json +4 -0
- package/libs/dal/tsconfig.json +22 -0
- package/libs/dal/vite.config.ts +34 -0
- package/libs/db/.prettierignore +6 -0
- package/libs/db/.prettierrc.js +12 -0
- package/libs/db/eslint.config.mjs +3 -0
- package/libs/db/package.json +52 -0
- package/libs/db/src/index.ts +24 -0
- package/libs/db/src/relations.ts +549 -0
- package/libs/db/src/schema.ts +2 -0
- package/libs/db/src/schemas/api.ts +35 -0
- package/libs/db/src/schemas/conversations.ts +175 -0
- package/libs/db/src/schemas/core.ts +359 -0
- package/libs/db/src/schemas/documents.ts +181 -0
- package/libs/db/src/schemas/feedback.ts +40 -0
- package/libs/db/src/schemas/index.ts +26 -0
- package/libs/db/src/schemas/organisations.ts +97 -0
- package/libs/db/src/schemas/pipelines.ts +440 -0
- package/libs/db/src/schemas/users.ts +95 -0
- package/libs/db/src/types.ts +190 -0
- package/libs/db/src/utils.ts +14 -0
- package/libs/db/tsconfig.json +19 -0
- package/libs/db/vite.config.ts +31 -0
- package/libs/lint/.prettierignore +6 -0
- package/libs/lint/eslint.config.mjs +61 -0
- package/libs/lint/package.json +29 -0
- package/libs/lint/prettier.config.js +12 -0
- package/libs/schemas/.prettierignore +6 -0
- package/libs/schemas/.prettierrc.js +12 -0
- package/libs/schemas/README.md +15 -0
- package/libs/schemas/eslint.config.mjs +3 -0
- package/libs/schemas/package.json +67 -0
- package/libs/schemas/src/core/chat.ts +67 -0
- package/libs/schemas/src/core/core-result.ts +15 -0
- package/libs/schemas/src/core/data-extraction.ts +184 -0
- package/libs/schemas/src/core/layout.ts +478 -0
- package/libs/schemas/src/core/pipeline.ts +128 -0
- package/libs/schemas/src/core/submission.ts +97 -0
- package/libs/schemas/src/db/account.ts +57 -0
- package/libs/schemas/src/db/apiKey.ts +57 -0
- package/libs/schemas/src/db/context.ts +33 -0
- package/libs/schemas/src/db/conversation.ts +65 -0
- package/libs/schemas/src/db/deal.ts +42 -0
- package/libs/schemas/src/db/document.ts +103 -0
- package/libs/schemas/src/db/documentCitation.ts +58 -0
- package/libs/schemas/src/db/documentExtraction.ts +69 -0
- package/libs/schemas/src/db/fieldCorrection.ts +85 -0
- package/libs/schemas/src/db/form.ts +45 -0
- package/libs/schemas/src/db/formField.ts +59 -0
- package/libs/schemas/src/db/formGroup.ts +42 -0
- package/libs/schemas/src/db/impersonation.ts +39 -0
- package/libs/schemas/src/db/index.ts +25 -0
- package/libs/schemas/src/db/invitation.ts +42 -0
- package/libs/schemas/src/db/member.ts +36 -0
- package/libs/schemas/src/db/message.ts +58 -0
- package/libs/schemas/src/db/organization.ts +62 -0
- package/libs/schemas/src/db/session.ts +48 -0
- package/libs/schemas/src/db/submission.ts +54 -0
- package/libs/schemas/src/db/submissionGroup.ts +36 -0
- package/libs/schemas/src/db/submissionItem.ts +33 -0
- package/libs/schemas/src/db/submissionItemVersion.ts +70 -0
- package/libs/schemas/src/db/user.ts +51 -0
- package/libs/schemas/src/db/utils.ts +3 -0
- package/libs/schemas/src/db/verification.ts +36 -0
- package/libs/schemas/src/db/workflow.ts +42 -0
- package/libs/schemas/src/index.ts +10 -0
- package/libs/schemas/tsconfig.json +21 -0
- package/libs/schemas/vite.config.ts +38 -0
- package/libs/ui/.prettierignore +6 -0
- package/libs/ui/.prettierrc.js +12 -0
- package/libs/ui/components.json +24 -0
- package/libs/ui/eslint.config.mjs +3 -0
- package/libs/ui/package.json +142 -0
- package/libs/ui/src/components/chart-viz/chart.tsx +255 -0
- package/libs/ui/src/components/chart-viz/converters.ts +474 -0
- package/libs/ui/src/components/chart-viz/dashboard.tsx +146 -0
- package/libs/ui/src/components/chart-viz/index.ts +37 -0
- package/libs/ui/src/components/chart-viz/markdown.tsx +344 -0
- package/libs/ui/src/components/chart-viz/table.tsx +446 -0
- package/libs/ui/src/components/chart-viz/theme-context.tsx +70 -0
- package/libs/ui/src/components/chart-viz/themes/dark.ts +98 -0
- package/libs/ui/src/components/chart-viz/themes/index.ts +69 -0
- package/libs/ui/src/components/chart-viz/themes/light.ts +98 -0
- package/libs/ui/src/components/chart-viz/themes/tailwind.ts +326 -0
- package/libs/ui/src/components/chart-viz/themes/types.ts +99 -0
- package/libs/ui/src/components/chart-viz/tool-display.tsx +150 -0
- package/libs/ui/src/components/chart-viz/types.ts +95 -0
- package/libs/ui/src/components/doc-viewers/excel/index.tsx +431 -0
- package/libs/ui/src/components/doc-viewers/excel/themes.ts +160 -0
- package/libs/ui/src/components/doc-viewers/image/index.tsx +410 -0
- package/libs/ui/src/components/doc-viewers/pdf/index.tsx +258 -0
- package/libs/ui/src/components/doc-viewers/pdf/virtualized-pdf.tsx +556 -0
- package/libs/ui/src/components/misc/rel-date.tsx +52 -0
- package/libs/ui/src/components/misc/styled-link.tsx +2 -0
- package/libs/ui/src/components/table/data-table.tsx +546 -0
- package/libs/ui/src/components/table/report-table.tsx +305 -0
- package/libs/ui/src/components/table/sortable-column.tsx +34 -0
- package/libs/ui/src/components/ui/accordion.tsx +62 -0
- package/libs/ui/src/components/ui/alert-dialog.tsx +142 -0
- package/libs/ui/src/components/ui/alert.tsx +62 -0
- package/libs/ui/src/components/ui/artifact.tsx +118 -0
- package/libs/ui/src/components/ui/attachments.tsx +388 -0
- package/libs/ui/src/components/ui/avatar.tsx +39 -0
- package/libs/ui/src/components/ui/badge.tsx +43 -0
- package/libs/ui/src/components/ui/breadcrumb.tsx +102 -0
- package/libs/ui/src/components/ui/button-group.tsx +78 -0
- package/libs/ui/src/components/ui/button.tsx +79 -0
- package/libs/ui/src/components/ui/card.tsx +32 -0
- package/libs/ui/src/components/ui/carousel.tsx +228 -0
- package/libs/ui/src/components/ui/chain-of-thought.tsx +198 -0
- package/libs/ui/src/components/ui/checkbox.tsx +27 -0
- package/libs/ui/src/components/ui/citation.tsx +34 -0
- package/libs/ui/src/components/ui/code-block.tsx +500 -0
- package/libs/ui/src/components/ui/collapsible.tsx +19 -0
- package/libs/ui/src/components/ui/command.tsx +161 -0
- package/libs/ui/src/components/ui/conversation.tsx +90 -0
- package/libs/ui/src/components/ui/dialog.tsx +142 -0
- package/libs/ui/src/components/ui/dropdown-menu.tsx +246 -0
- package/libs/ui/src/components/ui/highlight.tsx +3 -0
- package/libs/ui/src/components/ui/hover-card.tsx +36 -0
- package/libs/ui/src/components/ui/inline-citation.tsx +251 -0
- package/libs/ui/src/components/ui/input-group.tsx +156 -0
- package/libs/ui/src/components/ui/input-otp.tsx +78 -0
- package/libs/ui/src/components/ui/input.tsx +21 -0
- package/libs/ui/src/components/ui/label.tsx +19 -0
- package/libs/ui/src/components/ui/model-selector.tsx +174 -0
- package/libs/ui/src/components/ui/multisidebar.tsx +750 -0
- package/libs/ui/src/components/ui/popover.tsx +43 -0
- package/libs/ui/src/components/ui/progress.tsx +28 -0
- package/libs/ui/src/components/ui/reasoning.tsx +178 -0
- package/libs/ui/src/components/ui/resizable.tsx +49 -0
- package/libs/ui/src/components/ui/scroll-area.tsx +54 -0
- package/libs/ui/src/components/ui/select.tsx +171 -0
- package/libs/ui/src/components/ui/separator.tsx +26 -0
- package/libs/ui/src/components/ui/sheet.tsx +128 -0
- package/libs/ui/src/components/ui/shimmer.tsx +53 -0
- package/libs/ui/src/components/ui/skeleton.tsx +13 -0
- package/libs/ui/src/components/ui/sonner.tsx +23 -0
- package/libs/ui/src/components/ui/switch.tsx +26 -0
- package/libs/ui/src/components/ui/table.tsx +96 -0
- package/libs/ui/src/components/ui/tabs.tsx +52 -0
- package/libs/ui/src/components/ui/textarea.tsx +41 -0
- package/libs/ui/src/components/ui/tool.tsx +209 -0
- package/libs/ui/src/components/ui/tooltip.tsx +58 -0
- package/libs/ui/src/components/ui/typography.tsx +113 -0
- package/libs/ui/src/fonts/manrope-v15-latin-300.woff2 +0 -0
- package/libs/ui/src/fonts/manrope-v15-latin-400.woff2 +0 -0
- package/libs/ui/src/fonts/manrope-v15-latin-500.woff2 +0 -0
- package/libs/ui/src/fonts/manrope-v15-latin-600.woff2 +0 -0
- package/libs/ui/src/hooks/use-mobile.ts +19 -0
- package/libs/ui/src/lib/utils.ts +6 -0
- package/libs/ui/src/styles/fonts.css +35 -0
- package/libs/ui/src/styles/style.css +218 -0
- package/libs/ui/tsconfig.json +21 -0
- package/libs/ui/vite.config.ts +80 -0
- package/libs/ui-lit/README.md +245 -0
- package/libs/ui-lit/TESTING_GUIDE.md +296 -0
- package/libs/ui-lit/eslint.config.mjs +3 -0
- package/libs/ui-lit/package.json +41 -0
- package/libs/ui-lit/scripts/build-css.js +43 -0
- package/libs/ui-lit/src/components/sea-alert.ts +132 -0
- package/libs/ui-lit/src/components/sea-button.ts +95 -0
- package/libs/ui-lit/src/components/sea-card.ts +113 -0
- package/libs/ui-lit/src/components/sea-input.ts +184 -0
- package/libs/ui-lit/src/components/sea-spinner.ts +65 -0
- package/libs/ui-lit/src/index.ts +15 -0
- package/libs/ui-lit/src/lib/utils.ts +6 -0
- package/libs/ui-lit/src/styles/tailwind.css +76 -0
- package/libs/ui-lit/src/theme.css +66 -0
- package/libs/ui-lit/src/theme.ts +79 -0
- package/libs/ui-lit/src/vite-env.d.ts +6 -0
- package/libs/ui-lit/tailwind.config.ts +50 -0
- package/libs/ui-lit/test.html +289 -0
- package/libs/ui-lit/tsconfig.json +23 -0
- package/libs/ui-lit/vite.config.ts +31 -0
- package/libs/ui-lit/vite.css.config.ts +20 -0
- package/libs/util/.prettierignore +6 -0
- package/libs/util/.prettierrc.js +12 -0
- package/libs/util/eslint.config.mjs +3 -0
- package/libs/util/package.json +45 -0
- package/libs/util/src/billing.ts +10 -0
- package/libs/util/src/data-transform.ts +19 -0
- package/libs/util/src/encryption.ts +45 -0
- package/libs/util/src/fmt.test.ts +9 -0
- package/libs/util/src/fmt.ts +71 -0
- package/libs/util/src/fuzzy.ts +47 -0
- package/libs/util/src/id.ts +24 -0
- package/libs/util/src/invariant.ts +31 -0
- package/libs/util/src/sub-name.ts +7 -0
- package/libs/util/tsconfig.json +19 -0
- package/libs/util/vite.config.ts +34 -0
- package/package.json +28 -0
- package/packages/widget/.prettierignore +6 -0
- package/packages/widget/.prettierrc.js +12 -0
- package/packages/widget/README.md +95 -0
- package/packages/widget/eslint.config.mjs +11 -0
- package/packages/widget/openapi-ts.config.ts +8 -0
- package/packages/widget/package.json +89 -0
- package/packages/widget/postcss.config.mjs +10 -0
- package/packages/widget/src/clients/api/client/client.ts +187 -0
- package/packages/widget/src/clients/api/client/index.ts +22 -0
- package/packages/widget/src/clients/api/client/types.ts +192 -0
- package/packages/widget/src/clients/api/client/utils.ts +394 -0
- package/packages/widget/src/clients/api/client.gen.ts +18 -0
- package/packages/widget/src/clients/api/core/auth.ts +39 -0
- package/packages/widget/src/clients/api/core/bodySerializer.ts +74 -0
- package/packages/widget/src/clients/api/core/params.ts +132 -0
- package/packages/widget/src/clients/api/core/pathSerializer.ts +169 -0
- package/packages/widget/src/clients/api/core/types.ts +80 -0
- package/packages/widget/src/clients/api/index.ts +3 -0
- package/packages/widget/src/clients/api/sdk.gen.ts +805 -0
- package/packages/widget/src/clients/api/types.gen.ts +2085 -0
- package/packages/widget/src/components/container.tsx +42 -0
- package/packages/widget/src/components/data-display.tsx +384 -0
- package/packages/widget/src/components/data-viewer.tsx +311 -0
- package/packages/widget/src/components/doc-list.tsx +102 -0
- package/packages/widget/src/components/field-correction-modal.tsx +265 -0
- package/packages/widget/src/components/header.tsx +71 -0
- package/packages/widget/src/components/new-submission.tsx +290 -0
- package/packages/widget/src/components/sidebar-right.tsx +19 -0
- package/packages/widget/src/components/submission-card.tsx +66 -0
- package/packages/widget/src/components/submission-page.tsx +75 -0
- package/packages/widget/src/components/upload-doc.tsx +241 -0
- package/packages/widget/src/components/widget.tsx +101 -0
- package/packages/widget/src/index.tsx +167 -0
- package/packages/widget/src/lib/config.ts +2 -0
- package/packages/widget/src/lib/util.ts +40 -0
- package/packages/widget/src/styles/index.css +5 -0
- package/packages/widget/src/styles/tw-properties.css +337 -0
- package/packages/widget/src/vite-env.d.ts +3 -0
- package/packages/widget/tsconfig.app.json +35 -0
- package/packages/widget/tsconfig.json +4 -0
- package/packages/widget/tsconfig.node.json +24 -0
- package/packages/widget/vite.config.ts +116 -0
- package/packages/widget-lit/BOTTLENECKS.md +250 -0
- package/packages/widget-lit/IMPLEMENTATION_SUMMARY.md +295 -0
- package/packages/widget-lit/README.md +232 -0
- package/packages/widget-lit/eslint.config.mjs +3 -0
- package/packages/widget-lit/package.json +52 -0
- package/packages/widget-lit/src/api-client.ts +230 -0
- package/packages/widget-lit/src/api-client.ts.backup +218 -0
- package/packages/widget-lit/src/components/sea-chat.ts +382 -0
- package/packages/widget-lit/src/components/sea-submission-viewer.ts +267 -0
- package/packages/widget-lit/src/components/sea-widget.ts +317 -0
- package/packages/widget-lit/src/index.ts +48 -0
- package/packages/widget-lit/src/react.ts +58 -0
- package/packages/widget-lit/src/style.css +47 -0
- package/packages/widget-lit/tsconfig.json +24 -0
- package/packages/widget-lit/vite.config.ts +29 -0
- package/packages/widget-ng/DEVELOPMENT.md +74 -0
- package/packages/widget-ng/README.md +657 -0
- package/packages/widget-ng/dev.sh +14 -0
- package/packages/widget-ng/eslint.config.mjs +24 -0
- package/packages/widget-ng/ng-package.json +9 -0
- package/packages/widget-ng/package.json +85 -0
- package/packages/widget-ng/src/index.ts +45 -0
- package/packages/widget-ng/src/lib/components/sea-chat.component.ts +737 -0
- package/packages/widget-ng/src/lib/components/sea-data-viewer.component.ts +2240 -0
- package/packages/widget-ng/src/lib/components/sea-deal-form-modal.component.ts +702 -0
- package/packages/widget-ng/src/lib/components/sea-document-list.component.ts +350 -0
- package/packages/widget-ng/src/lib/components/sea-feedback-modal.component.ts +461 -0
- package/packages/widget-ng/src/lib/components/sea-file-upload.component.ts +655 -0
- package/packages/widget-ng/src/lib/components/sea-model-selection-modal.component.ts +367 -0
- package/packages/widget-ng/src/lib/components/sea-new-submission-modal.component.ts +414 -0
- package/packages/widget-ng/src/lib/components/sea-pdf-viewer.component.ts +869 -0
- package/packages/widget-ng/src/lib/components/sea-submission-card.component.ts +251 -0
- package/packages/widget-ng/src/lib/components/sea-widget.component.ts +684 -0
- package/packages/widget-ng/src/lib/models/submission.model.ts +170 -0
- package/packages/widget-ng/src/lib/pipes/markdown.pipe.ts +57 -0
- package/packages/widget-ng/src/lib/services/api-client.service.ts +715 -0
- package/packages/widget-ng/src/lib/services/chat.service.ts +330 -0
- package/packages/widget-ng/src/lib/services/config.service.ts +107 -0
- package/packages/widget-ng/src/web-component.ts +56 -0
- package/packages/widget-ng/tsconfig.json +25 -0
- package/packages/widget-ng/tsconfig.lib.json +9 -0
- package/packages/widget-ng/vite.config.elements.ts +26 -0
- package/packages/widget-ng/vitest.config.ts +19 -0
- package/packages/widget-ng/vitest.setup.ts +13 -0
- package/pnpm-workspace.yaml +18 -0
- package/render.yaml +136 -0
- package/scripts/README.md +57 -0
- package/scripts/package.json +22 -0
- package/scripts/python/.python-version +1 -0
- package/scripts/python/README.md +3 -0
- package/scripts/python/export-org-data.py +693 -0
- package/scripts/python/pyproject.toml +29 -0
- package/scripts/python/requirements-dev.lock +36 -0
- package/scripts/python/requirements.lock +36 -0
- package/scripts/python/src/gen.py +297 -0
- package/scripts/python/test.py +34 -0
- package/scripts/src/fix-storage-provider-mismatch.ts +239 -0
- package/scripts/src/sync-render-yaml.ts +290 -0
- package/scripts/src/test-chat-stream.ts +300 -0
- package/scripts/src/test-reconciliation.ts +230 -0
- package/scripts/tsconfig.json +15 -0
- package/tests/angular-test-app/.vscode/extensions.json +4 -0
- package/tests/angular-test-app/.vscode/launch.json +13 -0
- package/tests/angular-test-app/.vscode/tasks.json +24 -0
- package/tests/angular-test-app/README.md +59 -0
- package/tests/angular-test-app/angular.json +111 -0
- package/tests/angular-test-app/clean-start.sh +14 -0
- package/tests/angular-test-app/package.json +36 -0
- package/tests/angular-test-app/public/favicon.ico +0 -0
- package/tests/angular-test-app/src/app/app.component.ts +220 -0
- package/tests/angular-test-app/src/app/app.config.ts +5 -0
- package/tests/angular-test-app/src/env.d.ts +13 -0
- package/tests/angular-test-app/src/index.html +13 -0
- package/tests/angular-test-app/src/main.ts +6 -0
- package/tests/angular-test-app/src/styles.css +8 -0
- package/tests/angular-test-app/tsconfig.app.json +15 -0
- package/tests/angular-test-app/tsconfig.json +27 -0
- package/tests/crm-viewer-app/API_INTEGRATION_SUMMARY.md +295 -0
- package/tests/crm-viewer-app/CURRENT_ASSETS_FIELDS.md +148 -0
- package/tests/crm-viewer-app/FIELD_ID_MAPPING.md +206 -0
- package/tests/crm-viewer-app/INTEGRATION_GUIDE.md +309 -0
- package/tests/crm-viewer-app/README.md +174 -0
- package/tests/crm-viewer-app/REAL_API_INTEGRATION.md +240 -0
- package/tests/crm-viewer-app/UPDATED_IMPLEMENTATION.md +279 -0
- package/tests/crm-viewer-app/angular.json +114 -0
- package/tests/crm-viewer-app/package.json +35 -0
- package/tests/crm-viewer-app/src/app/app.component.ts +534 -0
- package/tests/crm-viewer-app/src/app/citation.service.ts +316 -0
- package/tests/crm-viewer-app/src/env.d.ts +16 -0
- package/tests/crm-viewer-app/src/index.html +19 -0
- package/tests/crm-viewer-app/src/main.ts +7 -0
- package/tests/crm-viewer-app/src/styles.css +409 -0
- package/tests/crm-viewer-app/src/template.html +2678 -0
- package/tests/crm-viewer-app/tsconfig.app.json +15 -0
- package/tests/crm-viewer-app/tsconfig.json +27 -0
- package/tests/e2e/package.json +17 -0
- package/tests/e2e/playwright.config.ts +75 -0
- package/tests/e2e/tests/api/health.spec.ts +10 -0
- package/tests/e2e/tests/app/example.spec.ts +10 -0
- package/tests/widget-test-app/.prettierignore +6 -0
- package/tests/widget-test-app/README.md +48 -0
- package/tests/widget-test-app/index.html +12 -0
- package/tests/widget-test-app/package.json +24 -0
- package/tests/widget-test-app/src/App.css +192 -0
- package/tests/widget-test-app/src/App.tsx +80 -0
- package/tests/widget-test-app/src/main.tsx +9 -0
- package/tests/widget-test-app/src/vite-env.d.ts +4 -0
- package/tests/widget-test-app/tsconfig.json +25 -0
- package/tests/widget-test-app/tsconfig.node.json +11 -0
- package/tests/widget-test-app/vite.config.ts +14 -0
|
@@ -0,0 +1,2678 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>LOS - Financial Services</title>
|
|
7
|
+
<style>
|
|
8
|
+
* {
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
body {
|
|
15
|
+
font-family: 'Salesforce Sans', Arial, sans-serif;
|
|
16
|
+
background-color: #f3f2f2;
|
|
17
|
+
font-size: 13px;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* Top Navigation Bar */
|
|
21
|
+
.sf-header {
|
|
22
|
+
background: linear-gradient(to bottom, #2574a9 0%, #1c5a85 100%);
|
|
23
|
+
height: 40px;
|
|
24
|
+
display: flex;
|
|
25
|
+
align-items: center;
|
|
26
|
+
padding: 0 15px;
|
|
27
|
+
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.sf-logo {
|
|
31
|
+
color: white;
|
|
32
|
+
font-weight: bold;
|
|
33
|
+
font-size: 16px;
|
|
34
|
+
margin-right: 30px;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.sf-nav {
|
|
38
|
+
display: flex;
|
|
39
|
+
gap: 5px;
|
|
40
|
+
flex: 1;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.sf-nav-item {
|
|
44
|
+
color: white;
|
|
45
|
+
padding: 8px 12px;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
border-radius: 3px;
|
|
48
|
+
transition: background 0.2s;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.sf-nav-item:hover {
|
|
52
|
+
background: rgba(255,255,255,0.1);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.sf-nav-item.active {
|
|
56
|
+
background: rgba(255,255,255,0.2);
|
|
57
|
+
font-weight: bold;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.sf-user-menu {
|
|
61
|
+
margin-left: auto;
|
|
62
|
+
color: white;
|
|
63
|
+
display: flex;
|
|
64
|
+
align-items: center;
|
|
65
|
+
gap: 10px;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* Sub Navigation */
|
|
69
|
+
.sf-sub-nav {
|
|
70
|
+
background: white;
|
|
71
|
+
border-bottom: 1px solid #d8dde6;
|
|
72
|
+
padding: 10px 15px;
|
|
73
|
+
display: flex;
|
|
74
|
+
align-items: center;
|
|
75
|
+
gap: 15px;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.sf-breadcrumb {
|
|
79
|
+
color: #0070d2;
|
|
80
|
+
font-size: 12px;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.sf-search {
|
|
84
|
+
padding: 6px 12px;
|
|
85
|
+
border: 1px solid #d8dde6;
|
|
86
|
+
border-radius: 3px;
|
|
87
|
+
width: 300px;
|
|
88
|
+
background: #fafaf9;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* Main Content */
|
|
92
|
+
.sf-container {
|
|
93
|
+
padding: 15px;
|
|
94
|
+
max-width: 1400px;
|
|
95
|
+
margin: 0 auto;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* Page Header */
|
|
99
|
+
.sf-page-header {
|
|
100
|
+
background: white;
|
|
101
|
+
border: 1px solid #d8dde6;
|
|
102
|
+
border-radius: 4px;
|
|
103
|
+
padding: 15px 20px;
|
|
104
|
+
margin-bottom: 15px;
|
|
105
|
+
display: flex;
|
|
106
|
+
align-items: center;
|
|
107
|
+
justify-content: space-between;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.sf-page-title {
|
|
111
|
+
display: flex;
|
|
112
|
+
align-items: center;
|
|
113
|
+
gap: 12px;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.sf-icon {
|
|
117
|
+
width: 32px;
|
|
118
|
+
height: 32px;
|
|
119
|
+
background: #0070d2;
|
|
120
|
+
border-radius: 4px;
|
|
121
|
+
display: flex;
|
|
122
|
+
align-items: center;
|
|
123
|
+
justify-content: center;
|
|
124
|
+
color: white;
|
|
125
|
+
font-weight: bold;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.sf-title-text h1 {
|
|
129
|
+
font-size: 18px;
|
|
130
|
+
color: #080707;
|
|
131
|
+
font-weight: 400;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.sf-title-text .subtitle {
|
|
135
|
+
font-size: 12px;
|
|
136
|
+
color: #706e6b;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.sf-actions {
|
|
140
|
+
display: flex;
|
|
141
|
+
gap: 8px;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.sf-button {
|
|
145
|
+
padding: 8px 16px;
|
|
146
|
+
border: 1px solid #d8dde6;
|
|
147
|
+
background: white;
|
|
148
|
+
border-radius: 3px;
|
|
149
|
+
cursor: pointer;
|
|
150
|
+
font-size: 13px;
|
|
151
|
+
transition: all 0.2s;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.sf-button:hover {
|
|
155
|
+
background: #f4f6f9;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.sf-button-primary {
|
|
159
|
+
background: #0070d2;
|
|
160
|
+
color: white;
|
|
161
|
+
border-color: #0070d2;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.sf-button-primary:hover {
|
|
165
|
+
background: #005fb2;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/* Content Layout */
|
|
169
|
+
.sf-content {
|
|
170
|
+
display: grid;
|
|
171
|
+
grid-template-columns: 2fr 1fr;
|
|
172
|
+
gap: 15px;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.sf-content.full-width {
|
|
176
|
+
grid-template-columns: 1fr;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.sf-sidebar {
|
|
180
|
+
transition: all 0.3s ease;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.sf-content.full-width .sf-sidebar {
|
|
184
|
+
display: none;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.sf-section {
|
|
188
|
+
background: white;
|
|
189
|
+
border: 1px solid #d8dde6;
|
|
190
|
+
border-radius: 4px;
|
|
191
|
+
overflow: hidden;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.sf-section-header {
|
|
195
|
+
background: #fafaf9;
|
|
196
|
+
border-bottom: 1px solid #d8dde6;
|
|
197
|
+
padding: 12px 15px;
|
|
198
|
+
font-weight: bold;
|
|
199
|
+
color: #080707;
|
|
200
|
+
display: flex;
|
|
201
|
+
justify-content: space-between;
|
|
202
|
+
align-items: center;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
.sf-section-body {
|
|
206
|
+
padding: 15px;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.sf-table {
|
|
210
|
+
width: 100%;
|
|
211
|
+
border-collapse: collapse;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.sf-table th {
|
|
215
|
+
background: #fafaf9;
|
|
216
|
+
padding: 10px;
|
|
217
|
+
text-align: left;
|
|
218
|
+
font-weight: 600;
|
|
219
|
+
border-bottom: 1px solid #d8dde6;
|
|
220
|
+
font-size: 12px;
|
|
221
|
+
color: #080707;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.sf-table td {
|
|
225
|
+
padding: 10px;
|
|
226
|
+
border-bottom: 1px solid #e5e5e5;
|
|
227
|
+
font-size: 13px;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.sf-table tr:hover {
|
|
231
|
+
background: #f4f6f9;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.sf-link {
|
|
235
|
+
color: #0070d2;
|
|
236
|
+
text-decoration: none;
|
|
237
|
+
cursor: pointer;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.sf-link:hover {
|
|
241
|
+
text-decoration: underline;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.sf-field-row {
|
|
245
|
+
display: grid;
|
|
246
|
+
grid-template-columns: 1fr 1fr;
|
|
247
|
+
gap: 15px;
|
|
248
|
+
margin-bottom: 15px;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.sf-field {
|
|
252
|
+
display: flex;
|
|
253
|
+
flex-direction: column;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.sf-field-label {
|
|
257
|
+
font-size: 11px;
|
|
258
|
+
color: #706e6b;
|
|
259
|
+
margin-bottom: 4px;
|
|
260
|
+
text-transform: uppercase;
|
|
261
|
+
font-weight: 600;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.sf-field-value {
|
|
265
|
+
color: #080707;
|
|
266
|
+
font-size: 13px;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.sf-status-badge {
|
|
270
|
+
display: inline-block;
|
|
271
|
+
padding: 4px 8px;
|
|
272
|
+
border-radius: 3px;
|
|
273
|
+
font-size: 11px;
|
|
274
|
+
font-weight: 600;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.status-open {
|
|
278
|
+
background: #e0f3ff;
|
|
279
|
+
color: #014486;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.status-closed {
|
|
283
|
+
background: #c9f2c7;
|
|
284
|
+
color: #2e844a;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.status-pending {
|
|
288
|
+
background: #ffd351;
|
|
289
|
+
color: #514f4d;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/* Widget Container */
|
|
293
|
+
.sf-widget-container {
|
|
294
|
+
grid-column: 1 / -1;
|
|
295
|
+
height: 600px;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
.sf-widget-container .sf-section-body {
|
|
299
|
+
padding: 0;
|
|
300
|
+
height: calc(100% - 45px);
|
|
301
|
+
overflow: hidden;
|
|
302
|
+
position: relative;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.sf-widget-container iframe {
|
|
306
|
+
width: calc(100% + 60px);
|
|
307
|
+
height: 100%;
|
|
308
|
+
border: none;
|
|
309
|
+
position: relative;
|
|
310
|
+
left: -60px;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/* Tabs */
|
|
314
|
+
.sf-tabs {
|
|
315
|
+
display: flex;
|
|
316
|
+
border-bottom: 1px solid #d8dde6;
|
|
317
|
+
background: #fafaf9;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.sf-tab {
|
|
321
|
+
padding: 12px 20px;
|
|
322
|
+
cursor: pointer;
|
|
323
|
+
border-bottom: 3px solid transparent;
|
|
324
|
+
transition: all 0.2s;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
.sf-tab:hover {
|
|
328
|
+
background: #f4f6f9;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
.sf-tab.active {
|
|
332
|
+
border-bottom-color: #0070d2;
|
|
333
|
+
background: white;
|
|
334
|
+
font-weight: 600;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/* Financial Tab Specific Styles */
|
|
338
|
+
.sf-financial-tabs {
|
|
339
|
+
display: flex;
|
|
340
|
+
border-bottom: 1px solid #d8dde6;
|
|
341
|
+
background: #fafaf9;
|
|
342
|
+
margin-top: -1px;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.sf-financial-tab {
|
|
346
|
+
padding: 10px 16px;
|
|
347
|
+
cursor: pointer;
|
|
348
|
+
border-bottom: 3px solid transparent;
|
|
349
|
+
transition: all 0.2s;
|
|
350
|
+
font-size: 11px;
|
|
351
|
+
font-weight: 600;
|
|
352
|
+
color: #706e6b;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
.sf-financial-tab:hover {
|
|
356
|
+
background: #f4f6f9;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
.sf-financial-tab.active {
|
|
360
|
+
border-bottom-color: #0070d2;
|
|
361
|
+
background: white;
|
|
362
|
+
color: #0070d2;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
.sf-upload-area {
|
|
366
|
+
padding: 40px 20px;
|
|
367
|
+
text-align: center;
|
|
368
|
+
border: 2px dashed #d8dde6;
|
|
369
|
+
border-radius: 4px;
|
|
370
|
+
margin: 20px;
|
|
371
|
+
background: #fafaf9;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.sf-upload-area h3 {
|
|
375
|
+
font-size: 16px;
|
|
376
|
+
margin-bottom: 8px;
|
|
377
|
+
color: #080707;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
.sf-upload-area p {
|
|
381
|
+
color: #706e6b;
|
|
382
|
+
font-size: 13px;
|
|
383
|
+
margin-bottom: 20px;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
.sf-upload-widget {
|
|
387
|
+
border: 1px solid #d8dde6;
|
|
388
|
+
border-radius: 4px;
|
|
389
|
+
background: white;
|
|
390
|
+
margin: 20px;
|
|
391
|
+
min-height: 500px;
|
|
392
|
+
overflow: hidden;
|
|
393
|
+
position: relative;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
.sf-upload-widget.hidden {
|
|
397
|
+
display: none;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
.sf-upload-widget iframe {
|
|
401
|
+
width: calc(100% + 60px);
|
|
402
|
+
height: 800px;
|
|
403
|
+
border: none;
|
|
404
|
+
position: relative;
|
|
405
|
+
left: -60px;
|
|
406
|
+
top: -40px;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
.sf-financial-table {
|
|
410
|
+
width: 100%;
|
|
411
|
+
border-collapse: collapse;
|
|
412
|
+
margin-top: 15px;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
.sf-financial-table th {
|
|
416
|
+
background: #f8f8f8;
|
|
417
|
+
border-bottom: 2px solid #ddd;
|
|
418
|
+
padding: 8px 12px;
|
|
419
|
+
text-align: left;
|
|
420
|
+
font-size: 11px;
|
|
421
|
+
font-weight: bold;
|
|
422
|
+
color: #333;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
.sf-financial-table td {
|
|
426
|
+
padding: 6px 12px;
|
|
427
|
+
border-bottom: 1px solid #f0f0f0;
|
|
428
|
+
font-size: 11px;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
.sf-financial-table .amount-cell {
|
|
432
|
+
text-align: right;
|
|
433
|
+
font-family: 'Courier New', monospace;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
.sf-financial-table .total-row {
|
|
437
|
+
background: #f0f8ff;
|
|
438
|
+
font-weight: bold;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
.sf-statement-header {
|
|
442
|
+
background: #f8f9fa;
|
|
443
|
+
padding: 12px;
|
|
444
|
+
border-bottom: 1px solid #ddd;
|
|
445
|
+
margin-top: 20px;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
.sf-statement-header h4 {
|
|
449
|
+
margin: 0 0 4px 0;
|
|
450
|
+
font-size: 13px;
|
|
451
|
+
color: #333;
|
|
452
|
+
font-weight: bold;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
.sf-statement-source {
|
|
456
|
+
font-size: 10px;
|
|
457
|
+
color: #666;
|
|
458
|
+
font-style: italic;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
.sf-tab-content {
|
|
462
|
+
display: none;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
.sf-tab-content.active {
|
|
466
|
+
display: block;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
.sf-spread-viewer {
|
|
470
|
+
margin: 20px;
|
|
471
|
+
border: 1px solid #d8dde6;
|
|
472
|
+
border-radius: 4px;
|
|
473
|
+
background: white;
|
|
474
|
+
min-height: 600px;
|
|
475
|
+
overflow: hidden;
|
|
476
|
+
position: relative;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
.sf-spread-viewer iframe {
|
|
480
|
+
width: calc(100% + 60px);
|
|
481
|
+
height: 800px;
|
|
482
|
+
border: none;
|
|
483
|
+
position: relative;
|
|
484
|
+
left: -60px;
|
|
485
|
+
top: -40px;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
.sf-no-data {
|
|
489
|
+
text-align: center;
|
|
490
|
+
padding: 60px 20px;
|
|
491
|
+
color: #706e6b;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
.sf-no-data h3 {
|
|
495
|
+
margin-bottom: 12px;
|
|
496
|
+
font-size: 16px;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/* Expand Button */
|
|
500
|
+
.sf-expand-iframe-btn {
|
|
501
|
+
position: absolute;
|
|
502
|
+
top: 10px;
|
|
503
|
+
right: 10px;
|
|
504
|
+
background: oklch(0.26 0.07 284.42);
|
|
505
|
+
color: white;
|
|
506
|
+
border: 1px solid transparent;
|
|
507
|
+
width: 36px;
|
|
508
|
+
height: 36px;
|
|
509
|
+
padding: 0;
|
|
510
|
+
border-radius: 8px;
|
|
511
|
+
cursor: pointer;
|
|
512
|
+
font-size: 18px;
|
|
513
|
+
font-weight: 500;
|
|
514
|
+
font-family: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
515
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
516
|
+
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
517
|
+
z-index: 10;
|
|
518
|
+
outline: none;
|
|
519
|
+
display: flex;
|
|
520
|
+
align-items: center;
|
|
521
|
+
justify-content: center;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
.sf-expand-iframe-btn:hover {
|
|
525
|
+
background: oklch(0.23 0.07 284.42);
|
|
526
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 0 0 4px oklch(0.26 0.07 284.42 / 0.3);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
.sf-expand-iframe-btn:focus-visible {
|
|
530
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 0 0 3px oklch(0.26 0.07 284.42 / 0.5);
|
|
531
|
+
border-color: oklch(0.26 0.07 284.42);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/* Modal Styles */
|
|
535
|
+
.sf-iframe-modal-overlay {
|
|
536
|
+
position: fixed;
|
|
537
|
+
top: 0;
|
|
538
|
+
left: 0;
|
|
539
|
+
right: 0;
|
|
540
|
+
bottom: 0;
|
|
541
|
+
background: rgba(0, 0, 0, 0.7);
|
|
542
|
+
display: none;
|
|
543
|
+
align-items: center;
|
|
544
|
+
justify-content: center;
|
|
545
|
+
z-index: 10000;
|
|
546
|
+
padding: 20px;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
.sf-iframe-modal-overlay.active {
|
|
550
|
+
display: flex;
|
|
551
|
+
animation: fadeIn 0.3s ease;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
@keyframes fadeIn {
|
|
555
|
+
from {
|
|
556
|
+
opacity: 0;
|
|
557
|
+
}
|
|
558
|
+
to {
|
|
559
|
+
opacity: 1;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
/* Expanded iframe state */
|
|
565
|
+
.sf-upload-widget {
|
|
566
|
+
transition: all 0.3s ease;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
.sf-upload-widget.expanded {
|
|
570
|
+
position: fixed !important;
|
|
571
|
+
top: 50% !important;
|
|
572
|
+
left: 50% !important;
|
|
573
|
+
transform: translate(-50%, -50%) !important;
|
|
574
|
+
width: 90vw !important;
|
|
575
|
+
height: 90vh !important;
|
|
576
|
+
max-width: 90vw !important;
|
|
577
|
+
max-height: 90vh !important;
|
|
578
|
+
z-index: 10001 !important;
|
|
579
|
+
margin: 0 !important;
|
|
580
|
+
border-radius: 8px !important;
|
|
581
|
+
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3) !important;
|
|
582
|
+
display: flex !important;
|
|
583
|
+
flex-direction: column !important;
|
|
584
|
+
animation: modalSlideIn 0.3s ease;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
.sf-upload-widget.expanded iframe {
|
|
588
|
+
flex: 1 !important;
|
|
589
|
+
height: 100% !important;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
.sf-spread-viewer {
|
|
593
|
+
transition: all 0.3s ease;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
.sf-spread-viewer.expanded {
|
|
597
|
+
position: fixed !important;
|
|
598
|
+
top: 50% !important;
|
|
599
|
+
left: 50% !important;
|
|
600
|
+
transform: translate(-50%, -50%) !important;
|
|
601
|
+
width: 90vw !important;
|
|
602
|
+
height: 90vh !important;
|
|
603
|
+
max-width: 90vw !important;
|
|
604
|
+
max-height: 90vh !important;
|
|
605
|
+
z-index: 10001 !important;
|
|
606
|
+
margin: 0 !important;
|
|
607
|
+
border-radius: 8px !important;
|
|
608
|
+
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3) !important;
|
|
609
|
+
display: flex !important;
|
|
610
|
+
flex-direction: column !important;
|
|
611
|
+
animation: modalSlideIn 0.3s ease;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
.sf-spread-viewer.expanded iframe {
|
|
615
|
+
flex: 1 !important;
|
|
616
|
+
height: 100% !important;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
@keyframes modalSlideIn {
|
|
620
|
+
from {
|
|
621
|
+
transform: translate(-50%, -50%) scale(0.95);
|
|
622
|
+
opacity: 0;
|
|
623
|
+
}
|
|
624
|
+
to {
|
|
625
|
+
transform: translate(-50%, -50%) scale(1);
|
|
626
|
+
opacity: 1;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/* Hide expand button when expanded */
|
|
631
|
+
.sf-upload-widget.expanded .sf-expand-iframe-btn,
|
|
632
|
+
.sf-spread-viewer.expanded .sf-expand-iframe-btn {
|
|
633
|
+
display: none;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/* Close button for expanded state - matches expand button style */
|
|
637
|
+
.sf-expand-close-btn {
|
|
638
|
+
position: absolute;
|
|
639
|
+
top: 10px;
|
|
640
|
+
right: 10px;
|
|
641
|
+
background: oklch(0.26 0.07 284.42);
|
|
642
|
+
color: white;
|
|
643
|
+
border: 1px solid transparent;
|
|
644
|
+
width: 36px;
|
|
645
|
+
height: 36px;
|
|
646
|
+
padding: 0;
|
|
647
|
+
border-radius: 8px;
|
|
648
|
+
cursor: pointer;
|
|
649
|
+
font-size: 18px;
|
|
650
|
+
font-weight: 500;
|
|
651
|
+
font-family: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
652
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
653
|
+
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
654
|
+
z-index: 11;
|
|
655
|
+
outline: none;
|
|
656
|
+
display: none;
|
|
657
|
+
align-items: center;
|
|
658
|
+
justify-content: center;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
.sf-upload-widget.expanded .sf-expand-close-btn,
|
|
662
|
+
.sf-spread-viewer.expanded .sf-expand-close-btn {
|
|
663
|
+
display: flex;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
.sf-expand-close-btn:hover {
|
|
667
|
+
background: oklch(0.23 0.07 284.42);
|
|
668
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 0 0 4px oklch(0.26 0.07 284.42 / 0.3);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
.sf-expand-close-btn:focus-visible {
|
|
672
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 0 0 3px oklch(0.26 0.07 284.42 / 0.5);
|
|
673
|
+
border-color: oklch(0.26 0.07 284.42);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/* Import Manrope font */
|
|
677
|
+
@import url('https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700&display=swap');
|
|
678
|
+
|
|
679
|
+
/* Chat Widget Styles */
|
|
680
|
+
.chat-widget-button {
|
|
681
|
+
position: fixed;
|
|
682
|
+
bottom: 20px;
|
|
683
|
+
right: 20px;
|
|
684
|
+
width: 56px;
|
|
685
|
+
height: 56px;
|
|
686
|
+
border-radius: 8px;
|
|
687
|
+
background: oklch(0.26 0.07 284.42);
|
|
688
|
+
border: 1px solid transparent;
|
|
689
|
+
cursor: pointer;
|
|
690
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
691
|
+
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
692
|
+
z-index: 10000;
|
|
693
|
+
display: flex;
|
|
694
|
+
align-items: center;
|
|
695
|
+
justify-content: center;
|
|
696
|
+
font-family: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
697
|
+
outline: none;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
.chat-widget-button:hover {
|
|
701
|
+
background: oklch(0.23 0.07 284.42);
|
|
702
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 0 0 4px oklch(0.26 0.07 284.42 / 0.3);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
.chat-widget-button:focus-visible {
|
|
706
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 0 0 3px oklch(0.26 0.07 284.42 / 0.5);
|
|
707
|
+
border-color: oklch(0.26 0.07 284.42);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
.chat-widget-button.open {
|
|
711
|
+
background: oklch(0.23 0.07 284.42);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
.chat-widget-button svg {
|
|
715
|
+
width: 28px;
|
|
716
|
+
height: 28px;
|
|
717
|
+
fill: white;
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
.chat-widget-window {
|
|
721
|
+
position: fixed;
|
|
722
|
+
bottom: 90px;
|
|
723
|
+
right: 20px;
|
|
724
|
+
width: 400px;
|
|
725
|
+
height: 600px;
|
|
726
|
+
background: white;
|
|
727
|
+
border-radius: 12px;
|
|
728
|
+
border: 1px solid #e5e7eb;
|
|
729
|
+
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
|
|
730
|
+
display: none;
|
|
731
|
+
flex-direction: column;
|
|
732
|
+
z-index: 9999;
|
|
733
|
+
overflow: hidden;
|
|
734
|
+
font-family: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
.chat-widget-window.open {
|
|
738
|
+
display: flex;
|
|
739
|
+
animation: slideUp 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
@keyframes slideUp {
|
|
743
|
+
from {
|
|
744
|
+
opacity: 0;
|
|
745
|
+
transform: translateY(10px);
|
|
746
|
+
}
|
|
747
|
+
to {
|
|
748
|
+
opacity: 1;
|
|
749
|
+
transform: translateY(0);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
.chat-widget-header {
|
|
754
|
+
background: white;
|
|
755
|
+
border-bottom: 1px solid #e5e7eb;
|
|
756
|
+
color: #111827;
|
|
757
|
+
padding: 18px 20px;
|
|
758
|
+
display: flex;
|
|
759
|
+
justify-content: space-between;
|
|
760
|
+
align-items: center;
|
|
761
|
+
min-height: 60px;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
.chat-widget-title {
|
|
765
|
+
display: flex;
|
|
766
|
+
align-items: center;
|
|
767
|
+
gap: 10px;
|
|
768
|
+
font-weight: 600;
|
|
769
|
+
font-size: 16px;
|
|
770
|
+
color: #111827;
|
|
771
|
+
flex: 1;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
.chat-widget-title svg {
|
|
775
|
+
width: 22px;
|
|
776
|
+
height: 22px;
|
|
777
|
+
fill: #4f46e5;
|
|
778
|
+
flex-shrink: 0;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
.chat-widget-header-actions {
|
|
782
|
+
display: flex;
|
|
783
|
+
gap: 12px;
|
|
784
|
+
align-items: center;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
.chat-widget-sea-link {
|
|
788
|
+
background: none;
|
|
789
|
+
border: none;
|
|
790
|
+
color: #6b7280;
|
|
791
|
+
font-size: 18px;
|
|
792
|
+
cursor: pointer;
|
|
793
|
+
padding: 6px;
|
|
794
|
+
width: 32px;
|
|
795
|
+
height: 32px;
|
|
796
|
+
display: flex;
|
|
797
|
+
align-items: center;
|
|
798
|
+
justify-content: center;
|
|
799
|
+
border-radius: 6px;
|
|
800
|
+
transition: all 0.2s;
|
|
801
|
+
text-decoration: none;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
.chat-widget-sea-link:hover {
|
|
805
|
+
background: #f3f4f6;
|
|
806
|
+
transform: scale(1.05);
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
.chat-widget-expand {
|
|
810
|
+
background: none;
|
|
811
|
+
border: none;
|
|
812
|
+
color: #6b7280;
|
|
813
|
+
font-size: 20px;
|
|
814
|
+
cursor: pointer;
|
|
815
|
+
padding: 6px;
|
|
816
|
+
width: 32px;
|
|
817
|
+
height: 32px;
|
|
818
|
+
display: flex;
|
|
819
|
+
align-items: center;
|
|
820
|
+
justify-content: center;
|
|
821
|
+
border-radius: 6px;
|
|
822
|
+
transition: all 0.2s;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
.chat-widget-expand:hover {
|
|
826
|
+
background: #f3f4f6;
|
|
827
|
+
color: #111827;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
.chat-widget-close {
|
|
831
|
+
background: none;
|
|
832
|
+
border: none;
|
|
833
|
+
color: #6b7280;
|
|
834
|
+
font-size: 22px;
|
|
835
|
+
cursor: pointer;
|
|
836
|
+
width: 32px;
|
|
837
|
+
height: 32px;
|
|
838
|
+
display: flex;
|
|
839
|
+
align-items: center;
|
|
840
|
+
justify-content: center;
|
|
841
|
+
border-radius: 6px;
|
|
842
|
+
transition: all 0.2s;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
.chat-widget-close:hover {
|
|
846
|
+
background: #f3f4f6;
|
|
847
|
+
color: #111827;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
.chat-widget-window.expanded {
|
|
851
|
+
width: 600px;
|
|
852
|
+
height: 700px;
|
|
853
|
+
max-height: 85vh;
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
.chat-messages {
|
|
857
|
+
flex: 1;
|
|
858
|
+
overflow-y: auto;
|
|
859
|
+
padding: 20px;
|
|
860
|
+
background: #fafafa;
|
|
861
|
+
display: flex;
|
|
862
|
+
flex-direction: column;
|
|
863
|
+
gap: 12px;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
.chat-messages::-webkit-scrollbar {
|
|
867
|
+
width: 6px;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
.chat-messages::-webkit-scrollbar-track {
|
|
871
|
+
background: transparent;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
.chat-messages::-webkit-scrollbar-thumb {
|
|
875
|
+
background: #d1d5db;
|
|
876
|
+
border-radius: 3px;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
.chat-messages::-webkit-scrollbar-thumb:hover {
|
|
880
|
+
background: #9ca3af;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
.chat-message {
|
|
884
|
+
display: flex;
|
|
885
|
+
margin-bottom: 4px;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
.chat-message.user {
|
|
889
|
+
justify-content: flex-end;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
.chat-message.assistant {
|
|
893
|
+
justify-content: flex-start;
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
.chat-message-content {
|
|
897
|
+
max-width: 80%;
|
|
898
|
+
padding: 10px 14px;
|
|
899
|
+
border-radius: 8px;
|
|
900
|
+
font-size: 14px;
|
|
901
|
+
line-height: 1.5;
|
|
902
|
+
word-wrap: break-word;
|
|
903
|
+
text-align: left;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
.chat-message.user .chat-message-content {
|
|
907
|
+
background: oklch(0.26 0.07 284.42);
|
|
908
|
+
color: white;
|
|
909
|
+
border-bottom-right-radius: 4px;
|
|
910
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
.chat-message.assistant .chat-message-content {
|
|
914
|
+
background: white;
|
|
915
|
+
color: #374151;
|
|
916
|
+
border: 1px solid #e5e7eb;
|
|
917
|
+
border-bottom-left-radius: 4px;
|
|
918
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
.chat-message-content ul {
|
|
922
|
+
margin: 4px 0 8px 0;
|
|
923
|
+
padding-left: 20px;
|
|
924
|
+
list-style-type: disc;
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
.chat-message-content li {
|
|
928
|
+
margin: 4px 0;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
.chat-message-content strong {
|
|
932
|
+
font-weight: 600;
|
|
933
|
+
color: inherit;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
.chat-message-content div {
|
|
937
|
+
margin: 2px 0;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
.chat-input-container {
|
|
941
|
+
display: flex;
|
|
942
|
+
align-items: flex-end;
|
|
943
|
+
gap: 8px;
|
|
944
|
+
padding: 16px;
|
|
945
|
+
background: white;
|
|
946
|
+
border-top: 1px solid #e5e7eb;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
.chat-input {
|
|
950
|
+
flex: 1;
|
|
951
|
+
border: 1px solid #d1d5db;
|
|
952
|
+
border-radius: 8px;
|
|
953
|
+
padding: 10px 12px;
|
|
954
|
+
font-size: 14px;
|
|
955
|
+
font-family: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
956
|
+
outline: none;
|
|
957
|
+
transition: all 0.2s;
|
|
958
|
+
background: transparent;
|
|
959
|
+
color: #111827;
|
|
960
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
.chat-input::placeholder {
|
|
964
|
+
color: #9ca3af;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
.chat-input:focus {
|
|
968
|
+
border-color: #6366f1;
|
|
969
|
+
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
.chat-send-button {
|
|
973
|
+
width: 36px;
|
|
974
|
+
height: 36px;
|
|
975
|
+
border-radius: 8px;
|
|
976
|
+
background: oklch(0.26 0.07 284.42);
|
|
977
|
+
border: 1px solid transparent;
|
|
978
|
+
color: white;
|
|
979
|
+
cursor: pointer;
|
|
980
|
+
display: flex;
|
|
981
|
+
align-items: center;
|
|
982
|
+
justify-content: center;
|
|
983
|
+
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
984
|
+
flex-shrink: 0;
|
|
985
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
986
|
+
outline: none;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
.chat-send-button:hover:not(:disabled) {
|
|
990
|
+
background: oklch(0.23 0.07 284.42);
|
|
991
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 0 0 4px oklch(0.26 0.07 284.42 / 0.3);
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
.chat-send-button:focus-visible {
|
|
995
|
+
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 0 0 3px oklch(0.26 0.07 284.42 / 0.5);
|
|
996
|
+
border-color: oklch(0.26 0.07 284.42);
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
.chat-send-button:disabled {
|
|
1000
|
+
opacity: 0.5;
|
|
1001
|
+
cursor: not-allowed;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
.chat-send-button svg {
|
|
1005
|
+
width: 18px;
|
|
1006
|
+
height: 18px;
|
|
1007
|
+
fill: white;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
.chat-loading {
|
|
1011
|
+
display: flex;
|
|
1012
|
+
gap: 4px;
|
|
1013
|
+
padding: 10px 14px;
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
/* User Menu Dropdown */
|
|
1017
|
+
.sf-user-menu {
|
|
1018
|
+
position: relative;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
.sf-user-dropdown {
|
|
1022
|
+
position: absolute;
|
|
1023
|
+
top: 100%;
|
|
1024
|
+
right: 0;
|
|
1025
|
+
background: white;
|
|
1026
|
+
border: 1px solid #d8dde6;
|
|
1027
|
+
border-radius: 4px;
|
|
1028
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
1029
|
+
min-width: 250px;
|
|
1030
|
+
margin-top: 5px;
|
|
1031
|
+
display: none;
|
|
1032
|
+
z-index: 1000;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
.sf-user-dropdown.active {
|
|
1036
|
+
display: block;
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
.sf-user-dropdown-header {
|
|
1040
|
+
padding: 12px 15px;
|
|
1041
|
+
border-bottom: 1px solid #d8dde6;
|
|
1042
|
+
font-weight: 600;
|
|
1043
|
+
font-size: 12px;
|
|
1044
|
+
color: #080707;
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
.sf-user-dropdown-item {
|
|
1048
|
+
padding: 10px 15px;
|
|
1049
|
+
cursor: pointer;
|
|
1050
|
+
transition: background 0.2s;
|
|
1051
|
+
display: flex;
|
|
1052
|
+
align-items: center;
|
|
1053
|
+
gap: 10px;
|
|
1054
|
+
font-size: 13px;
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
.sf-user-dropdown-item:hover {
|
|
1058
|
+
background: #f4f6f9;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
.sf-user-dropdown-item input[type="checkbox"] {
|
|
1062
|
+
cursor: pointer;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
.sf-user-dropdown-item label {
|
|
1066
|
+
cursor: pointer;
|
|
1067
|
+
flex: 1;
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1070
|
+
/* Collapsed Account Details */
|
|
1071
|
+
.sf-section.collapsed {
|
|
1072
|
+
max-height: 0;
|
|
1073
|
+
overflow: hidden;
|
|
1074
|
+
opacity: 0;
|
|
1075
|
+
margin: 0;
|
|
1076
|
+
padding: 0;
|
|
1077
|
+
border: none;
|
|
1078
|
+
transition: all 0.3s ease;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
.sf-section:not(.collapsed) {
|
|
1082
|
+
max-height: 1000px;
|
|
1083
|
+
opacity: 1;
|
|
1084
|
+
transition: all 0.3s ease;
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
.chat-loading-dot {
|
|
1088
|
+
width: 8px;
|
|
1089
|
+
height: 8px;
|
|
1090
|
+
border-radius: 50%;
|
|
1091
|
+
background: #9ca3af;
|
|
1092
|
+
animation: chatDotPulse 1.4s infinite both;
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
.chat-loading-dot:nth-child(2) {
|
|
1096
|
+
animation-delay: 0.2s;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
.chat-loading-dot:nth-child(3) {
|
|
1100
|
+
animation-delay: 0.4s;
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
@keyframes chatDotPulse {
|
|
1104
|
+
0%, 80%, 100% {
|
|
1105
|
+
opacity: 0.3;
|
|
1106
|
+
transform: scale(0.8);
|
|
1107
|
+
}
|
|
1108
|
+
40% {
|
|
1109
|
+
opacity: 1;
|
|
1110
|
+
transform: scale(1);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
</style>
|
|
1114
|
+
</head>
|
|
1115
|
+
<body>
|
|
1116
|
+
<!-- Top Navigation -->
|
|
1117
|
+
<div class="sf-header">
|
|
1118
|
+
<div class="sf-logo">LOS</div>
|
|
1119
|
+
<div class="sf-nav">
|
|
1120
|
+
<div class="sf-nav-item">Home</div>
|
|
1121
|
+
<div class="sf-nav-item active">Accounts</div>
|
|
1122
|
+
<div class="sf-nav-item">Contacts</div>
|
|
1123
|
+
<div class="sf-nav-item">Opportunities</div>
|
|
1124
|
+
<div class="sf-nav-item">Financial Accounts</div>
|
|
1125
|
+
<div class="sf-nav-item">Leads</div>
|
|
1126
|
+
<div class="sf-nav-item">Reports</div>
|
|
1127
|
+
<div class="sf-nav-item">+</div>
|
|
1128
|
+
</div>
|
|
1129
|
+
<div class="sf-user-menu">
|
|
1130
|
+
<span onclick="toggleUserMenu()" style="cursor: pointer;">John Smith</span>
|
|
1131
|
+
<span onclick="toggleUserMenu()" style="cursor: pointer;">▼</span>
|
|
1132
|
+
<div class="sf-user-dropdown" id="userDropdown">
|
|
1133
|
+
<div class="sf-user-dropdown-header">Demo Settings</div>
|
|
1134
|
+
<div class="sf-user-dropdown-item" onclick="event.stopPropagation();">
|
|
1135
|
+
<input type="checkbox" id="embeddedToggle" onchange="toggleEmbedded()" checked>
|
|
1136
|
+
<label for="embeddedToggle">Embedded Features</label>
|
|
1137
|
+
</div>
|
|
1138
|
+
<div class="sf-user-dropdown-item" onclick="event.stopPropagation();">
|
|
1139
|
+
<input type="checkbox" id="inputFinancialsToggle" onchange="toggleInputFinancials()">
|
|
1140
|
+
<label for="inputFinancialsToggle">Input Financials</label>
|
|
1141
|
+
</div>
|
|
1142
|
+
</div>
|
|
1143
|
+
</div>
|
|
1144
|
+
</div>
|
|
1145
|
+
|
|
1146
|
+
<!-- Sub Navigation -->
|
|
1147
|
+
<div class="sf-sub-nav">
|
|
1148
|
+
<div class="sf-breadcrumb">Home > Accounts > Enterprise Financial Group</div>
|
|
1149
|
+
<input type="text" class="sf-search" placeholder="Search Legacy LOS..." />
|
|
1150
|
+
</div>
|
|
1151
|
+
|
|
1152
|
+
<!-- Main Content -->
|
|
1153
|
+
<div class="sf-container">
|
|
1154
|
+
<!-- Page Header -->
|
|
1155
|
+
<div class="sf-page-header">
|
|
1156
|
+
<div class="sf-page-title">
|
|
1157
|
+
<div class="sf-icon">🏢</div>
|
|
1158
|
+
<div class="sf-title-text">
|
|
1159
|
+
<h1>Enterprise Financial Group</h1>
|
|
1160
|
+
<div class="subtitle">Account • Customer - Direct</div>
|
|
1161
|
+
</div>
|
|
1162
|
+
</div>
|
|
1163
|
+
<div class="sf-actions">
|
|
1164
|
+
<button class="sf-button">Follow</button>
|
|
1165
|
+
<button class="sf-button">Edit</button>
|
|
1166
|
+
<button class="sf-button">Delete</button>
|
|
1167
|
+
<button class="sf-button-primary">New Opportunity</button>
|
|
1168
|
+
</div>
|
|
1169
|
+
</div>
|
|
1170
|
+
|
|
1171
|
+
<!-- Content Grid -->
|
|
1172
|
+
<div class="sf-content" id="mainContent">
|
|
1173
|
+
<!-- Left Column - Main Content -->
|
|
1174
|
+
<div>
|
|
1175
|
+
<!-- Account Details -->
|
|
1176
|
+
<div class="sf-section" id="accountDetailsSection">
|
|
1177
|
+
<div class="sf-section-header">Account Details</div>
|
|
1178
|
+
<div class="sf-section-body">
|
|
1179
|
+
<div class="sf-field-row">
|
|
1180
|
+
<div class="sf-field">
|
|
1181
|
+
<div class="sf-field-label">Account Name</div>
|
|
1182
|
+
<div class="sf-field-value">Enterprise Financial Group</div>
|
|
1183
|
+
</div>
|
|
1184
|
+
<div class="sf-field">
|
|
1185
|
+
<div class="sf-field-label">Account Owner</div>
|
|
1186
|
+
<div class="sf-field-value"><a href="#" class="sf-link">John Smith</a></div>
|
|
1187
|
+
</div>
|
|
1188
|
+
</div>
|
|
1189
|
+
<div class="sf-field-row">
|
|
1190
|
+
<div class="sf-field">
|
|
1191
|
+
<div class="sf-field-label">Type</div>
|
|
1192
|
+
<div class="sf-field-value">Customer - Direct</div>
|
|
1193
|
+
</div>
|
|
1194
|
+
<div class="sf-field">
|
|
1195
|
+
<div class="sf-field-label">Industry</div>
|
|
1196
|
+
<div class="sf-field-value">Financial Services</div>
|
|
1197
|
+
</div>
|
|
1198
|
+
</div>
|
|
1199
|
+
<div class="sf-field-row">
|
|
1200
|
+
<div class="sf-field">
|
|
1201
|
+
<div class="sf-field-label">Phone</div>
|
|
1202
|
+
<div class="sf-field-value">(415) 555-0123</div>
|
|
1203
|
+
</div>
|
|
1204
|
+
<div class="sf-field">
|
|
1205
|
+
<div class="sf-field-label">Annual Revenue</div>
|
|
1206
|
+
<div class="sf-field-value">$45,000,000</div>
|
|
1207
|
+
</div>
|
|
1208
|
+
</div>
|
|
1209
|
+
<div class="sf-field-row">
|
|
1210
|
+
<div class="sf-field">
|
|
1211
|
+
<div class="sf-field-label">Billing Address</div>
|
|
1212
|
+
<div class="sf-field-value">123 Market Street<br>San Francisco, CA 94105</div>
|
|
1213
|
+
</div>
|
|
1214
|
+
<div class="sf-field">
|
|
1215
|
+
<div class="sf-field-label">Website</div>
|
|
1216
|
+
<div class="sf-field-value"><a href="#" class="sf-link">www.enterprisefinancial.com</a></div>
|
|
1217
|
+
</div>
|
|
1218
|
+
</div>
|
|
1219
|
+
</div>
|
|
1220
|
+
</div>
|
|
1221
|
+
|
|
1222
|
+
<!-- Related Lists -->
|
|
1223
|
+
<div class="sf-section" style="margin-top: 15px;">
|
|
1224
|
+
<div class="sf-tabs">
|
|
1225
|
+
<div class="sf-tab active" onclick="switchMainTab('opportunities')">Opportunities</div>
|
|
1226
|
+
<div class="sf-tab" onclick="switchMainTab('contacts')">Contacts</div>
|
|
1227
|
+
<div class="sf-tab" onclick="switchMainTab('cases')">Cases</div>
|
|
1228
|
+
<div class="sf-tab" onclick="switchMainTab('activity')">Activity</div>
|
|
1229
|
+
<div class="sf-tab" onclick="switchMainTab('notes')">Notes & Attachments</div>
|
|
1230
|
+
<div class="sf-tab" onclick="switchMainTab('financials')">Financials</div>
|
|
1231
|
+
</div>
|
|
1232
|
+
|
|
1233
|
+
<!-- Opportunities Tab Content -->
|
|
1234
|
+
<div id="opportunities-content" class="sf-tab-content active">
|
|
1235
|
+
<div class="sf-section-body">
|
|
1236
|
+
<table class="sf-table">
|
|
1237
|
+
<thead>
|
|
1238
|
+
<tr>
|
|
1239
|
+
<th>Opportunity Name</th>
|
|
1240
|
+
<th>Stage</th>
|
|
1241
|
+
<th>Amount</th>
|
|
1242
|
+
<th>Close Date</th>
|
|
1243
|
+
<th>Probability</th>
|
|
1244
|
+
</tr>
|
|
1245
|
+
</thead>
|
|
1246
|
+
<tbody>
|
|
1247
|
+
<tr>
|
|
1248
|
+
<td><a href="#" class="sf-link">Wealth Management Platform</a></td>
|
|
1249
|
+
<td><span class="sf-status-badge status-open">Negotiation/Review</span></td>
|
|
1250
|
+
<td>$250,000</td>
|
|
1251
|
+
<td>03/15/2024</td>
|
|
1252
|
+
<td>75%</td>
|
|
1253
|
+
</tr>
|
|
1254
|
+
<tr>
|
|
1255
|
+
<td><a href="#" class="sf-link">Investment Portfolio System</a></td>
|
|
1256
|
+
<td><span class="sf-status-badge status-pending">Proposal/Price Quote</span></td>
|
|
1257
|
+
<td>$180,000</td>
|
|
1258
|
+
<td>04/30/2024</td>
|
|
1259
|
+
<td>50%</td>
|
|
1260
|
+
</tr>
|
|
1261
|
+
<tr>
|
|
1262
|
+
<td><a href="#" class="sf-link">Risk Assessment Tools</a></td>
|
|
1263
|
+
<td><span class="sf-status-badge status-closed">Closed Won</span></td>
|
|
1264
|
+
<td>$320,000</td>
|
|
1265
|
+
<td>01/20/2024</td>
|
|
1266
|
+
<td>100%</td>
|
|
1267
|
+
</tr>
|
|
1268
|
+
</tbody>
|
|
1269
|
+
</table>
|
|
1270
|
+
</div>
|
|
1271
|
+
</div>
|
|
1272
|
+
|
|
1273
|
+
<!-- Contacts Tab Content -->
|
|
1274
|
+
<div id="contacts-content" class="sf-tab-content">
|
|
1275
|
+
<div class="sf-section-body">
|
|
1276
|
+
<p>Contacts content goes here...</p>
|
|
1277
|
+
</div>
|
|
1278
|
+
</div>
|
|
1279
|
+
|
|
1280
|
+
<!-- Cases Tab Content -->
|
|
1281
|
+
<div id="cases-content" class="sf-tab-content">
|
|
1282
|
+
<div class="sf-section-body">
|
|
1283
|
+
<p>Cases content goes here...</p>
|
|
1284
|
+
</div>
|
|
1285
|
+
</div>
|
|
1286
|
+
|
|
1287
|
+
<!-- Activity Tab Content -->
|
|
1288
|
+
<div id="activity-content" class="sf-tab-content">
|
|
1289
|
+
<div class="sf-section-body">
|
|
1290
|
+
<p>Activity content goes here...</p>
|
|
1291
|
+
</div>
|
|
1292
|
+
</div>
|
|
1293
|
+
|
|
1294
|
+
<!-- Notes Tab Content -->
|
|
1295
|
+
<div id="notes-content" class="sf-tab-content">
|
|
1296
|
+
<div class="sf-section-body">
|
|
1297
|
+
<p>Notes & Attachments content goes here...</p>
|
|
1298
|
+
</div>
|
|
1299
|
+
</div>
|
|
1300
|
+
|
|
1301
|
+
<!-- Financials Tab Content -->
|
|
1302
|
+
<div id="financials-content" class="sf-tab-content">
|
|
1303
|
+
<!-- Financial Sub-Tabs -->
|
|
1304
|
+
<div class="sf-financial-tabs">
|
|
1305
|
+
<div class="sf-financial-tab active" onclick="switchFinancialTab('ai')">AI Financials</div>
|
|
1306
|
+
<div class="sf-financial-tab" onclick="switchFinancialTab('input')">Input Financials</div>
|
|
1307
|
+
<div class="sf-financial-tab" onclick="switchFinancialTab('analysis')">Financial Analysis</div>
|
|
1308
|
+
</div>
|
|
1309
|
+
|
|
1310
|
+
<!-- AI Financials Tab Content -->
|
|
1311
|
+
<div id="ai-content" class="sf-tab-content active">
|
|
1312
|
+
<div id="upload-widget" class="sf-upload-widget" style="margin: 0; border: none; border-radius: 0; min-height: 700px;">
|
|
1313
|
+
<button class="sf-expand-iframe-btn" onclick="expandIframe()" title="Expand">⛶</button>
|
|
1314
|
+
<button class="sf-expand-close-btn" onclick="closeIframeModal()">×</button>
|
|
1315
|
+
<iframe
|
|
1316
|
+
src="https://app.sea.dev/deals/28eq483grdz4gbfkhsili/j62iaw4d5piudvlnjexzi"
|
|
1317
|
+
allow="clipboard-write; clipboard-read">
|
|
1318
|
+
</iframe>
|
|
1319
|
+
</div>
|
|
1320
|
+
</div>
|
|
1321
|
+
|
|
1322
|
+
<!-- Input Financials Tab Content -->
|
|
1323
|
+
<div id="input-content" class="sf-tab-content">
|
|
1324
|
+
<div style="padding: 20px;">
|
|
1325
|
+
<!-- Top Section: Requirements in Left/Right Panels -->
|
|
1326
|
+
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 20px;">
|
|
1327
|
+
<!-- Left Panel: Required Documents -->
|
|
1328
|
+
<div style="background: #fff3cd; border: 1px solid #ffc107; border-radius: 4px; padding: 15px;">
|
|
1329
|
+
<h4 style="margin: 0 0 10px 0; color: #856404; font-size: 14px; font-weight: 600;">Required Documents</h4>
|
|
1330
|
+
<ul style="margin: 0; padding-left: 20px; color: #856404; font-size: 12px; line-height: 1.8;">
|
|
1331
|
+
<li>Balance Sheet (most recent fiscal year-end)</li>
|
|
1332
|
+
<li>Income Statement / Profit & Loss (last 3 years)</li>
|
|
1333
|
+
<li>Cash Flow Statement (last 3 years)</li>
|
|
1334
|
+
<li>Tax Returns (last 2 years, all schedules)</li>
|
|
1335
|
+
<li>Accounts Receivable Aging Report</li>
|
|
1336
|
+
<li>Accounts Payable Aging Report</li>
|
|
1337
|
+
<li>Inventory Report (if applicable)</li>
|
|
1338
|
+
</ul>
|
|
1339
|
+
</div>
|
|
1340
|
+
|
|
1341
|
+
<!-- Right Panel: Data Entry Requirements -->
|
|
1342
|
+
<div style="background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 4px; padding: 15px;">
|
|
1343
|
+
<h4 style="margin: 0 0 10px 0; font-size: 14px; font-weight: 600;">Data Entry Requirements</h4>
|
|
1344
|
+
<ul style="margin: 0; padding-left: 20px; font-size: 11px; line-height: 1.8; color: #495057;">
|
|
1345
|
+
<li>All amounts must be entered in whole dollars (no cents)</li>
|
|
1346
|
+
<li>Negative values must be entered with parentheses, e.g., (5000)</li>
|
|
1347
|
+
<li>Do not include currency symbols ($, €, etc.)</li>
|
|
1348
|
+
<li>Separate thousands with commas (e.g., 1,000,000)</li>
|
|
1349
|
+
<li>Percentages must be entered as decimals (e.g., 0.15 for 15%)</li>
|
|
1350
|
+
<li>All fields marked with * are required</li>
|
|
1351
|
+
<li>Data must match supporting documentation exactly</li>
|
|
1352
|
+
<li>Contact CFO if discrepancies exceed $500</li>
|
|
1353
|
+
</ul>
|
|
1354
|
+
</div>
|
|
1355
|
+
</div>
|
|
1356
|
+
|
|
1357
|
+
<!-- Bottom Section: Data Entry Forms -->
|
|
1358
|
+
|
|
1359
|
+
<!-- Balance Sheet Section -->
|
|
1360
|
+
<div style="border: 1px solid #d8dde6; border-radius: 4px; margin-bottom: 20px; overflow: hidden;">
|
|
1361
|
+
<div style="background: #fafaf9; border-bottom: 1px solid #d8dde6; padding: 12px 15px; font-weight: 600;">
|
|
1362
|
+
Balance Sheet (Year-End)
|
|
1363
|
+
</div>
|
|
1364
|
+
<div style="padding: 15px;">
|
|
1365
|
+
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px; margin-bottom: 15px;">
|
|
1366
|
+
<div>
|
|
1367
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">FISCAL YEAR END DATE *</label>
|
|
1368
|
+
<input type="date" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
|
|
1369
|
+
</div>
|
|
1370
|
+
<div>
|
|
1371
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">REPORTING CURRENCY *</label>
|
|
1372
|
+
<select style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;">
|
|
1373
|
+
<option>USD</option>
|
|
1374
|
+
<option>EUR</option>
|
|
1375
|
+
<option>GBP</option>
|
|
1376
|
+
</select>
|
|
1377
|
+
</div>
|
|
1378
|
+
</div>
|
|
1379
|
+
|
|
1380
|
+
<h5 style="margin: 15px 0 10px 0; font-size: 12px; color: #080707; font-weight: 600;">Current Assets</h5>
|
|
1381
|
+
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px;">
|
|
1382
|
+
<div>
|
|
1383
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">Cash and Cash Equivalents *</label>
|
|
1384
|
+
<input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
|
|
1385
|
+
</div>
|
|
1386
|
+
<div>
|
|
1387
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">Accounts Receivable *</label>
|
|
1388
|
+
<input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
|
|
1389
|
+
</div>
|
|
1390
|
+
<div>
|
|
1391
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">Inventory</label>
|
|
1392
|
+
<input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
|
|
1393
|
+
</div>
|
|
1394
|
+
<div>
|
|
1395
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">Prepaid Expenses</label>
|
|
1396
|
+
<input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
|
|
1397
|
+
</div>
|
|
1398
|
+
<div>
|
|
1399
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">Other Current Assets</label>
|
|
1400
|
+
<input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
|
|
1401
|
+
</div>
|
|
1402
|
+
<div>
|
|
1403
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">TOTAL CURRENT ASSETS *</label>
|
|
1404
|
+
<input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px; background: #fafaf9; font-weight: 600;" readonly />
|
|
1405
|
+
</div>
|
|
1406
|
+
</div>
|
|
1407
|
+
|
|
1408
|
+
<h5 style="margin: 15px 0 10px 0; font-size: 12px; color: #080707; font-weight: 600;">Fixed Assets</h5>
|
|
1409
|
+
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px;">
|
|
1410
|
+
<div>
|
|
1411
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">Property, Plant & Equipment *</label>
|
|
1412
|
+
<input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
|
|
1413
|
+
</div>
|
|
1414
|
+
<div>
|
|
1415
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">Accumulated Depreciation *</label>
|
|
1416
|
+
<input type="text" placeholder="(0)" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
|
|
1417
|
+
</div>
|
|
1418
|
+
<div>
|
|
1419
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">Intangible Assets</label>
|
|
1420
|
+
<input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
|
|
1421
|
+
</div>
|
|
1422
|
+
<div>
|
|
1423
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">Goodwill</label>
|
|
1424
|
+
<input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
|
|
1425
|
+
</div>
|
|
1426
|
+
</div>
|
|
1427
|
+
</div>
|
|
1428
|
+
</div>
|
|
1429
|
+
|
|
1430
|
+
<!-- Income Statement Section -->
|
|
1431
|
+
<div style="border: 1px solid #d8dde6; border-radius: 4px; margin-bottom: 20px; overflow: hidden;">
|
|
1432
|
+
<div style="background: #fafaf9; border-bottom: 1px solid #d8dde6; padding: 12px 15px; font-weight: 600;">
|
|
1433
|
+
Income Statement (Year-End)
|
|
1434
|
+
</div>
|
|
1435
|
+
<div style="padding: 15px;">
|
|
1436
|
+
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px;">
|
|
1437
|
+
<div style="grid-column: 1 / -1;">
|
|
1438
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">FINANCIAL PERIOD *</label>
|
|
1439
|
+
<input type="text" placeholder="e.g., Q4 2023, FY 2023, Jan 2024" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
|
|
1440
|
+
<div style="font-size: 10px; color: #706e6b; margin-top: 4px;">The relevant financial period. Typically month or quarter.</div>
|
|
1441
|
+
</div>
|
|
1442
|
+
|
|
1443
|
+
<div>
|
|
1444
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">REVENUE *</label>
|
|
1445
|
+
<input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
|
|
1446
|
+
<div style="font-size: 10px; color: #706e6b; margin-top: 4px;">Total income generated from normal business operations</div>
|
|
1447
|
+
</div>
|
|
1448
|
+
<div>
|
|
1449
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">REFUNDS</label>
|
|
1450
|
+
<input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
|
|
1451
|
+
<div style="font-size: 10px; color: #706e6b; margin-top: 4px;">Any indication of refunds from the income statement</div>
|
|
1452
|
+
</div>
|
|
1453
|
+
|
|
1454
|
+
<div>
|
|
1455
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">COGS (Cost of Goods Sold) *</label>
|
|
1456
|
+
<input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
|
|
1457
|
+
<div style="font-size: 10px; color: #706e6b; margin-top: 4px;">Direct costs of producing goods sold; includes materials and labor</div>
|
|
1458
|
+
</div>
|
|
1459
|
+
<div>
|
|
1460
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">SG&A (Selling, General & Admin) *</label>
|
|
1461
|
+
<input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
|
|
1462
|
+
<div style="font-size: 10px; color: #706e6b; margin-top: 4px;">Overhead and operating expenses not tied to production</div>
|
|
1463
|
+
</div>
|
|
1464
|
+
|
|
1465
|
+
<div>
|
|
1466
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">EBIT *</label>
|
|
1467
|
+
<input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px; background: #fafaf9; font-weight: 600;" readonly />
|
|
1468
|
+
<div style="font-size: 10px; color: #706e6b; margin-top: 4px;">Calculate as gross profit minus SG&A, then subtract other expenses</div>
|
|
1469
|
+
</div>
|
|
1470
|
+
<div>
|
|
1471
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">EBITDA *</label>
|
|
1472
|
+
<input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px; background: #fafaf9; font-weight: 600;" readonly />
|
|
1473
|
+
<div style="font-size: 10px; color: #706e6b; margin-top: 4px;">Earnings before interest, taxes, depreciation, and amortization</div>
|
|
1474
|
+
</div>
|
|
1475
|
+
|
|
1476
|
+
<div>
|
|
1477
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">ADJUSTED EBITDA *</label>
|
|
1478
|
+
<input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
|
|
1479
|
+
<div style="font-size: 10px; color: #706e6b; margin-top: 4px;">Permitted add-backs to normalise for one-time expenses</div>
|
|
1480
|
+
</div>
|
|
1481
|
+
<div>
|
|
1482
|
+
<label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">NET INCOME *</label>
|
|
1483
|
+
<input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px; background: #fafaf9; font-weight: 600;" readonly />
|
|
1484
|
+
<div style="font-size: 10px; color: #706e6b; margin-top: 4px;">Total profit of the company after all expenses and taxes</div>
|
|
1485
|
+
</div>
|
|
1486
|
+
</div>
|
|
1487
|
+
</div>
|
|
1488
|
+
</div>
|
|
1489
|
+
|
|
1490
|
+
<!-- Action Buttons -->
|
|
1491
|
+
<div style="display: flex; gap: 10px; justify-content: flex-end; padding-top: 10px;">
|
|
1492
|
+
<button class="sf-button">Cancel</button>
|
|
1493
|
+
<button class="sf-button">Save Draft</button>
|
|
1494
|
+
<button class="sf-button-primary">Submit for Review</button>
|
|
1495
|
+
</div>
|
|
1496
|
+
</div>
|
|
1497
|
+
</div>
|
|
1498
|
+
|
|
1499
|
+
<!-- Financial Analysis Tab Content -->
|
|
1500
|
+
<div id="analysis-content" class="sf-tab-content">
|
|
1501
|
+
<!-- Error State when AI is turned off -->
|
|
1502
|
+
<div id="analysis-error-state" style="display: none; padding: 60px 20px; text-align: center;">
|
|
1503
|
+
<div style="max-width: 500px; margin: 0 auto;">
|
|
1504
|
+
<svg width="120" height="120" viewBox="0 0 120 120" style="margin-bottom: 24px;">
|
|
1505
|
+
<circle cx="60" cy="60" r="50" fill="none" stroke="#c23934" stroke-width="3"/>
|
|
1506
|
+
<path d="M60 35 L60 65 M60 75 L60 85" stroke="#c23934" stroke-width="6" stroke-linecap="round"/>
|
|
1507
|
+
</svg>
|
|
1508
|
+
<h3 style="font-size: 20px; font-weight: 600; color: #080707; margin-bottom: 12px;">Financial Analysis Unavailable</h3>
|
|
1509
|
+
<p style="font-size: 14px; color: #706e6b; line-height: 1.6; margin-bottom: 24px;">
|
|
1510
|
+
Please complete the financial data entry in the <strong>Input Financials</strong> tab to generate automated analysis and insights.
|
|
1511
|
+
</p>
|
|
1512
|
+
<button class="sf-button-primary" onclick="switchFinancialTab('input')" style="font-size: 13px;">
|
|
1513
|
+
Go to Input Financials
|
|
1514
|
+
</button>
|
|
1515
|
+
</div>
|
|
1516
|
+
</div>
|
|
1517
|
+
|
|
1518
|
+
<!-- Actual Analysis Content -->
|
|
1519
|
+
<div id="analysis-actual-content" style="padding: 20px;">
|
|
1520
|
+
<!-- Overall Assessment at Top -->
|
|
1521
|
+
<div style="background: #e0f3ff; border: 1px solid #b3d9f2; border-radius: 4px; padding: 15px; margin-bottom: 20px;">
|
|
1522
|
+
<h4 style="margin: 0 0 10px 0; color: #014486; font-size: 14px; font-weight: 600;">Overall Lending Assessment</h4>
|
|
1523
|
+
<div style="font-size: 12px; color: #080707; line-height: 1.8;">
|
|
1524
|
+
<strong>Credit Decision:</strong> <span style="color: #2e844a; font-weight: 600;">APPROVED - Strong Candidate</span><br>
|
|
1525
|
+
<strong>Risk Rating:</strong> Low to Moderate<br>
|
|
1526
|
+
<strong>Key Strengths:</strong> Excellent liquidity, strong debt service coverage, healthy profitability margins<br>
|
|
1527
|
+
<strong>Considerations:</strong> Debt-to-Equity ratio is at upper acceptable range; recommend monitoring leverage trends
|
|
1528
|
+
</div>
|
|
1529
|
+
</div>
|
|
1530
|
+
|
|
1531
|
+
<!-- Metrics Dashboard Grid -->
|
|
1532
|
+
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px;">
|
|
1533
|
+
<!-- Current Ratio Card -->
|
|
1534
|
+
<div style="border: 1px solid #d8dde6; border-radius: 4px; padding: 15px; background: white; display: flex; justify-content: space-between; align-items: center; gap: 15px;">
|
|
1535
|
+
<div style="flex: 0 0 50%;">
|
|
1536
|
+
<div style="font-size: 11px; color: #706e6b; margin-bottom: 4px; text-transform: uppercase; font-weight: 600;">Current Ratio</div>
|
|
1537
|
+
<div style="font-size: 24px; font-weight: 600; color: #080707; margin-bottom: 8px;">2.1</div>
|
|
1538
|
+
<div style="font-size: 10px; color: #2e844a; font-weight: 600; margin-bottom: 8px;">15% above industry standard</div>
|
|
1539
|
+
<span style="background: #c9f2c7; color: #2e844a; padding: 4px 8px; border-radius: 3px; font-size: 11px; font-weight: 600;">PASS</span>
|
|
1540
|
+
</div>
|
|
1541
|
+
<div style="flex: 0 0 50%; height: 60px;">
|
|
1542
|
+
<svg width="100%" height="100%" viewBox="0 0 135 60" style="display: block;">
|
|
1543
|
+
<polyline points="0,45 25,42 50,48 75,37 100,30" fill="none" stroke="#2e844a" stroke-width="2"/>
|
|
1544
|
+
<circle cx="0" cy="45" r="2" fill="#2e844a"/>
|
|
1545
|
+
<circle cx="25" cy="42" r="2" fill="#2e844a"/>
|
|
1546
|
+
<circle cx="50" cy="48" r="2" fill="#2e844a"/>
|
|
1547
|
+
<circle cx="75" cy="37" r="2" fill="#2e844a"/>
|
|
1548
|
+
<circle cx="100" cy="30" r="3" fill="#2e844a"/>
|
|
1549
|
+
<text x="105" y="30" font-size="10" fill="#2e844a" alignment-baseline="middle" font-weight="600">2.1</text>
|
|
1550
|
+
</svg>
|
|
1551
|
+
</div>
|
|
1552
|
+
</div>
|
|
1553
|
+
|
|
1554
|
+
<!-- Quick Ratio Card -->
|
|
1555
|
+
<div style="border: 1px solid #d8dde6; border-radius: 4px; padding: 15px; background: white; display: flex; justify-content: space-between; align-items: center; gap: 15px;">
|
|
1556
|
+
<div style="flex: 0 0 50%;">
|
|
1557
|
+
<div style="font-size: 11px; color: #706e6b; margin-bottom: 4px; text-transform: uppercase; font-weight: 600;">Quick Ratio</div>
|
|
1558
|
+
<div style="font-size: 24px; font-weight: 600; color: #080707; margin-bottom: 8px;">1.8</div>
|
|
1559
|
+
<div style="font-size: 10px; color: #2e844a; font-weight: 600; margin-bottom: 8px;">12% above industry standard</div>
|
|
1560
|
+
<span style="background: #c9f2c7; color: #2e844a; padding: 4px 8px; border-radius: 3px; font-size: 11px; font-weight: 600;">PASS</span>
|
|
1561
|
+
</div>
|
|
1562
|
+
<div style="flex: 0 0 50%; height: 60px;">
|
|
1563
|
+
<svg width="100%" height="100%" viewBox="0 0 135 60" style="display: block;">
|
|
1564
|
+
<polyline points="0,48 25,45 50,42 75,36 100,33" fill="none" stroke="#2e844a" stroke-width="2"/>
|
|
1565
|
+
<circle cx="0" cy="48" r="2" fill="#2e844a"/>
|
|
1566
|
+
<circle cx="25" cy="45" r="2" fill="#2e844a"/>
|
|
1567
|
+
<circle cx="50" cy="42" r="2" fill="#2e844a"/>
|
|
1568
|
+
<circle cx="75" cy="36" r="2" fill="#2e844a"/>
|
|
1569
|
+
<circle cx="100" cy="33" r="3" fill="#2e844a"/>
|
|
1570
|
+
<text x="105" y="33" font-size="10" fill="#2e844a" alignment-baseline="middle" font-weight="600">1.8</text>
|
|
1571
|
+
</svg>
|
|
1572
|
+
</div>
|
|
1573
|
+
</div>
|
|
1574
|
+
|
|
1575
|
+
<!-- Debt-to-Equity Card -->
|
|
1576
|
+
<div style="border: 1px solid #d8dde6; border-radius: 4px; padding: 15px; background: white; display: flex; justify-content: space-between; align-items: center; gap: 15px;">
|
|
1577
|
+
<div style="flex: 0 0 50%;">
|
|
1578
|
+
<div style="font-size: 11px; color: #706e6b; margin-bottom: 4px; text-transform: uppercase; font-weight: 600;">Debt-to-Equity</div>
|
|
1579
|
+
<div style="font-size: 24px; font-weight: 600; color: #080707; margin-bottom: 8px;">1.9</div>
|
|
1580
|
+
<div style="font-size: 10px; color: #ca8a04; font-weight: 600; margin-bottom: 8px;">10% below industry standard</div>
|
|
1581
|
+
<span style="background: #ffd351; color: #514f4d; padding: 4px 8px; border-radius: 3px; font-size: 11px; font-weight: 600;">REVIEW</span>
|
|
1582
|
+
</div>
|
|
1583
|
+
<div style="flex: 0 0 50%; height: 60px;">
|
|
1584
|
+
<svg width="100%" height="100%" viewBox="0 0 135 60" style="display: block;">
|
|
1585
|
+
<polyline points="0,52 25,45 50,42 75,39 100,33" fill="none" stroke="#ca8a04" stroke-width="2"/>
|
|
1586
|
+
<circle cx="0" cy="52" r="2" fill="#ca8a04"/>
|
|
1587
|
+
<circle cx="25" cy="45" r="2" fill="#ca8a04"/>
|
|
1588
|
+
<circle cx="50" cy="42" r="2" fill="#ca8a04"/>
|
|
1589
|
+
<circle cx="75" cy="39" r="2" fill="#ca8a04"/>
|
|
1590
|
+
<circle cx="100" cy="33" r="3" fill="#ca8a04"/>
|
|
1591
|
+
<text x="105" y="33" font-size="10" fill="#ca8a04" alignment-baseline="middle" font-weight="600">1.9</text>
|
|
1592
|
+
</svg>
|
|
1593
|
+
</div>
|
|
1594
|
+
</div>
|
|
1595
|
+
|
|
1596
|
+
<!-- Debt-to-EBITDA Card -->
|
|
1597
|
+
<div style="border: 1px solid #d8dde6; border-radius: 4px; padding: 15px; background: white; display: flex; justify-content: space-between; align-items: center; gap: 15px;">
|
|
1598
|
+
<div style="flex: 0 0 50%;">
|
|
1599
|
+
<div style="font-size: 11px; color: #706e6b; margin-bottom: 4px; text-transform: uppercase; font-weight: 600;">Debt-to-EBITDA</div>
|
|
1600
|
+
<div style="font-size: 24px; font-weight: 600; color: #080707; margin-bottom: 8px;">2.8</div>
|
|
1601
|
+
<div style="font-size: 10px; color: #706e6b; font-weight: 600; margin-bottom: 8px;">At industry standard</div>
|
|
1602
|
+
<span style="background: #c9f2c7; color: #2e844a; padding: 4px 8px; border-radius: 3px; font-size: 11px; font-weight: 600;">PASS</span>
|
|
1603
|
+
</div>
|
|
1604
|
+
<div style="flex: 0 0 50%; height: 60px;">
|
|
1605
|
+
<svg width="100%" height="100%" viewBox="0 0 135 60" style="display: block;">
|
|
1606
|
+
<polyline points="0,22 25,30 50,37 75,40 100,36" fill="none" stroke="#2e844a" stroke-width="2"/>
|
|
1607
|
+
<circle cx="0" cy="22" r="2" fill="#2e844a"/>
|
|
1608
|
+
<circle cx="25" cy="30" r="2" fill="#2e844a"/>
|
|
1609
|
+
<circle cx="50" cy="37" r="2" fill="#2e844a"/>
|
|
1610
|
+
<circle cx="75" cy="40" r="2" fill="#2e844a"/>
|
|
1611
|
+
<circle cx="100" cy="36" r="3" fill="#2e844a"/>
|
|
1612
|
+
<text x="105" y="36" font-size="10" fill="#2e844a" alignment-baseline="middle" font-weight="600">2.8</text>
|
|
1613
|
+
</svg>
|
|
1614
|
+
</div>
|
|
1615
|
+
</div>
|
|
1616
|
+
|
|
1617
|
+
<!-- DSCR Card -->
|
|
1618
|
+
<div style="border: 1px solid #d8dde6; border-radius: 4px; padding: 15px; background: white; display: flex; justify-content: space-between; align-items: center; gap: 15px;">
|
|
1619
|
+
<div style="flex: 0 0 50%;">
|
|
1620
|
+
<div style="font-size: 11px; color: #706e6b; margin-bottom: 4px; text-transform: uppercase; font-weight: 600;">DSCR</div>
|
|
1621
|
+
<div style="font-size: 24px; font-weight: 600; color: #080707; margin-bottom: 8px;">1.45</div>
|
|
1622
|
+
<div style="font-size: 10px; color: #2e844a; font-weight: 600; margin-bottom: 8px;">20% above industry standard</div>
|
|
1623
|
+
<span style="background: #c9f2c7; color: #2e844a; padding: 4px 8px; border-radius: 3px; font-size: 11px; font-weight: 600;">PASS</span>
|
|
1624
|
+
</div>
|
|
1625
|
+
<div style="flex: 0 0 50%; height: 60px;">
|
|
1626
|
+
<svg width="100%" height="100%" viewBox="0 0 135 60" style="display: block;">
|
|
1627
|
+
<polyline points="0,45 25,48 50,42 75,39 100,30" fill="none" stroke="#2e844a" stroke-width="2"/>
|
|
1628
|
+
<circle cx="0" cy="45" r="2" fill="#2e844a"/>
|
|
1629
|
+
<circle cx="25" cy="48" r="2" fill="#2e844a"/>
|
|
1630
|
+
<circle cx="50" cy="42" r="2" fill="#2e844a"/>
|
|
1631
|
+
<circle cx="75" cy="39" r="2" fill="#2e844a"/>
|
|
1632
|
+
<circle cx="100" cy="30" r="3" fill="#2e844a"/>
|
|
1633
|
+
<text x="105" y="30" font-size="10" fill="#2e844a" alignment-baseline="middle" font-weight="600">1.45</text>
|
|
1634
|
+
</svg>
|
|
1635
|
+
</div>
|
|
1636
|
+
</div>
|
|
1637
|
+
|
|
1638
|
+
<!-- Interest Coverage Card -->
|
|
1639
|
+
<div style="border: 1px solid #d8dde6; border-radius: 4px; padding: 15px; background: white; display: flex; justify-content: space-between; align-items: center; gap: 15px;">
|
|
1640
|
+
<div style="flex: 0 0 50%;">
|
|
1641
|
+
<div style="font-size: 11px; color: #706e6b; margin-bottom: 4px; text-transform: uppercase; font-weight: 600;">Interest Coverage</div>
|
|
1642
|
+
<div style="font-size: 24px; font-weight: 600; color: #080707; margin-bottom: 8px;">5.2</div>
|
|
1643
|
+
<div style="font-size: 10px; color: #2e844a; font-weight: 600; margin-bottom: 8px;">30% above industry standard</div>
|
|
1644
|
+
<span style="background: #c9f2c7; color: #2e844a; padding: 4px 8px; border-radius: 3px; font-size: 11px; font-weight: 600;">PASS</span>
|
|
1645
|
+
</div>
|
|
1646
|
+
<div style="flex: 0 0 50%; height: 60px;">
|
|
1647
|
+
<svg width="100%" height="100%" viewBox="0 0 135 60" style="display: block;">
|
|
1648
|
+
<polyline points="0,42 25,39 50,45 75,36 100,27" fill="none" stroke="#2e844a" stroke-width="2"/>
|
|
1649
|
+
<circle cx="0" cy="42" r="2" fill="#2e844a"/>
|
|
1650
|
+
<circle cx="25" cy="39" r="2" fill="#2e844a"/>
|
|
1651
|
+
<circle cx="50" cy="45" r="2" fill="#2e844a"/>
|
|
1652
|
+
<circle cx="75" cy="36" r="2" fill="#2e844a"/>
|
|
1653
|
+
<circle cx="100" cy="27" r="3" fill="#2e844a"/>
|
|
1654
|
+
<text x="105" y="27" font-size="10" fill="#2e844a" alignment-baseline="middle" font-weight="600">5.2</text>
|
|
1655
|
+
</svg>
|
|
1656
|
+
</div>
|
|
1657
|
+
</div>
|
|
1658
|
+
|
|
1659
|
+
<!-- Net Profit Margin Card -->
|
|
1660
|
+
<div style="border: 1px solid #d8dde6; border-radius: 4px; padding: 15px; background: white; display: flex; justify-content: space-between; align-items: center; gap: 15px;">
|
|
1661
|
+
<div style="flex: 0 0 50%;">
|
|
1662
|
+
<div style="font-size: 11px; color: #706e6b; margin-bottom: 4px; text-transform: uppercase; font-weight: 600;">Net Profit Margin</div>
|
|
1663
|
+
<div style="font-size: 24px; font-weight: 600; color: #080707; margin-bottom: 8px;">12.4%</div>
|
|
1664
|
+
<div style="font-size: 10px; color: #2e844a; font-weight: 600; margin-bottom: 8px;">18% above industry standard</div>
|
|
1665
|
+
<span style="background: #c9f2c7; color: #2e844a; padding: 4px 8px; border-radius: 3px; font-size: 11px; font-weight: 600;">PASS</span>
|
|
1666
|
+
</div>
|
|
1667
|
+
<div style="flex: 0 0 50%; height: 60px;">
|
|
1668
|
+
<svg width="100%" height="100%" viewBox="0 0 135 60" style="display: block;">
|
|
1669
|
+
<polyline points="0,52 25,48 50,45 75,39 100,33" fill="none" stroke="#2e844a" stroke-width="2"/>
|
|
1670
|
+
<circle cx="0" cy="52" r="2" fill="#2e844a"/>
|
|
1671
|
+
<circle cx="25" cy="48" r="2" fill="#2e844a"/>
|
|
1672
|
+
<circle cx="50" cy="45" r="2" fill="#2e844a"/>
|
|
1673
|
+
<circle cx="75" cy="39" r="2" fill="#2e844a"/>
|
|
1674
|
+
<circle cx="100" cy="33" r="3" fill="#2e844a"/>
|
|
1675
|
+
<text x="105" y="33" font-size="10" fill="#2e844a" alignment-baseline="middle" font-weight="600">12.4%</text>
|
|
1676
|
+
</svg>
|
|
1677
|
+
</div>
|
|
1678
|
+
</div>
|
|
1679
|
+
|
|
1680
|
+
<!-- ROA Card -->
|
|
1681
|
+
<div style="border: 1px solid #d8dde6; border-radius: 4px; padding: 15px; background: white; display: flex; justify-content: space-between; align-items: center; gap: 15px;">
|
|
1682
|
+
<div style="flex: 0 0 50%;">
|
|
1683
|
+
<div style="font-size: 11px; color: #706e6b; margin-bottom: 4px; text-transform: uppercase; font-weight: 600;">Return on Assets</div>
|
|
1684
|
+
<div style="font-size: 24px; font-weight: 600; color: #080707; margin-bottom: 8px;">8.7%</div>
|
|
1685
|
+
<div style="font-size: 10px; color: #ca8a04; font-weight: 600; margin-bottom: 8px;">25% below industry standard</div>
|
|
1686
|
+
<span style="background: #c9f2c7; color: #2e844a; padding: 4px 8px; border-radius: 3px; font-size: 11px; font-weight: 600;">PASS</span>
|
|
1687
|
+
</div>
|
|
1688
|
+
<div style="flex: 0 0 50%; height: 60px;">
|
|
1689
|
+
<svg width="100%" height="100%" viewBox="0 0 135 60" style="display: block;">
|
|
1690
|
+
<polyline points="0,48 25,42 50,45 75,37 100,30" fill="none" stroke="#2e844a" stroke-width="2"/>
|
|
1691
|
+
<circle cx="0" cy="48" r="2" fill="#2e844a"/>
|
|
1692
|
+
<circle cx="25" cy="42" r="2" fill="#2e844a"/>
|
|
1693
|
+
<circle cx="50" cy="45" r="2" fill="#2e844a"/>
|
|
1694
|
+
<circle cx="75" cy="37" r="2" fill="#2e844a"/>
|
|
1695
|
+
<circle cx="100" cy="30" r="3" fill="#2e844a"/>
|
|
1696
|
+
<text x="105" y="30" font-size="10" fill="#2e844a" alignment-baseline="middle" font-weight="600">8.7%</text>
|
|
1697
|
+
</svg>
|
|
1698
|
+
</div>
|
|
1699
|
+
</div>
|
|
1700
|
+
|
|
1701
|
+
<!-- ROE Card -->
|
|
1702
|
+
<div style="border: 1px solid #d8dde6; border-radius: 4px; padding: 15px; background: white; display: flex; justify-content: space-between; align-items: center; gap: 15px;">
|
|
1703
|
+
<div style="flex: 0 0 50%;">
|
|
1704
|
+
<div style="font-size: 11px; color: #706e6b; margin-bottom: 4px; text-transform: uppercase; font-weight: 600;">Return on Equity</div>
|
|
1705
|
+
<div style="font-size: 24px; font-weight: 600; color: #080707; margin-bottom: 8px;">15.3%</div>
|
|
1706
|
+
<div style="font-size: 10px; color: #2e844a; font-weight: 600; margin-bottom: 8px;">8% above industry standard</div>
|
|
1707
|
+
<span style="background: #c9f2c7; color: #2e844a; padding: 4px 8px; border-radius: 3px; font-size: 11px; font-weight: 600;">PASS</span>
|
|
1708
|
+
</div>
|
|
1709
|
+
<div style="flex: 0 0 50%; height: 60px;">
|
|
1710
|
+
<svg width="100%" height="100%" viewBox="0 0 135 60" style="display: block;">
|
|
1711
|
+
<polyline points="0,45 25,42 50,48 75,39 100,30" fill="none" stroke="#2e844a" stroke-width="2"/>
|
|
1712
|
+
<circle cx="0" cy="45" r="2" fill="#2e844a"/>
|
|
1713
|
+
<circle cx="25" cy="42" r="2" fill="#2e844a"/>
|
|
1714
|
+
<circle cx="50" cy="48" r="2" fill="#2e844a"/>
|
|
1715
|
+
<circle cx="75" cy="39" r="2" fill="#2e844a"/>
|
|
1716
|
+
<circle cx="100" cy="30" r="3" fill="#2e844a"/>
|
|
1717
|
+
<text x="105" y="30" font-size="10" fill="#2e844a" alignment-baseline="middle" font-weight="600">15.3%</text>
|
|
1718
|
+
</svg>
|
|
1719
|
+
</div>
|
|
1720
|
+
</div>
|
|
1721
|
+
</div>
|
|
1722
|
+
</div>
|
|
1723
|
+
<!-- End Actual Analysis Content -->
|
|
1724
|
+
</div>
|
|
1725
|
+
</div>
|
|
1726
|
+
</div>
|
|
1727
|
+
</div>
|
|
1728
|
+
</div>
|
|
1729
|
+
|
|
1730
|
+
<!-- Right Column - Sidebar -->
|
|
1731
|
+
<div class="sf-sidebar">
|
|
1732
|
+
<!-- Key Metrics -->
|
|
1733
|
+
<div class="sf-section">
|
|
1734
|
+
<div class="sf-section-header">Key Account Metrics</div>
|
|
1735
|
+
<div class="sf-section-body">
|
|
1736
|
+
<div class="sf-field">
|
|
1737
|
+
<div class="sf-field-label">Total Revenue (YTD)</div>
|
|
1738
|
+
<div class="sf-field-value" style="font-size: 20px; color: #2e844a; font-weight: 600;">$1,250,000</div>
|
|
1739
|
+
</div>
|
|
1740
|
+
<div class="sf-field" style="margin-top: 15px;">
|
|
1741
|
+
<div class="sf-field-label">Open Opportunities</div>
|
|
1742
|
+
<div class="sf-field-value" style="font-size: 20px; font-weight: 600;">8</div>
|
|
1743
|
+
</div>
|
|
1744
|
+
<div class="sf-field" style="margin-top: 15px;">
|
|
1745
|
+
<div class="sf-field-label">Total Pipeline Value</div>
|
|
1746
|
+
<div class="sf-field-value" style="font-size: 20px; font-weight: 600;">$2,100,000</div>
|
|
1747
|
+
</div>
|
|
1748
|
+
<div class="sf-field" style="margin-top: 15px;">
|
|
1749
|
+
<div class="sf-field-label">Customer Since</div>
|
|
1750
|
+
<div class="sf-field-value">June 2019</div>
|
|
1751
|
+
</div>
|
|
1752
|
+
<div class="sf-field" style="margin-top: 15px;">
|
|
1753
|
+
<div class="sf-field-label">Support Tier</div>
|
|
1754
|
+
<div class="sf-field-value">Premium</div>
|
|
1755
|
+
</div>
|
|
1756
|
+
</div>
|
|
1757
|
+
</div>
|
|
1758
|
+
|
|
1759
|
+
<!-- Recent Activity -->
|
|
1760
|
+
<div class="sf-section" style="margin-top: 15px;">
|
|
1761
|
+
<div class="sf-section-header">Activity Timeline</div>
|
|
1762
|
+
<div class="sf-section-body">
|
|
1763
|
+
<div style="margin-bottom: 12px;">
|
|
1764
|
+
<div style="font-weight: 600; font-size: 12px; color: #080707;">Email Sent</div>
|
|
1765
|
+
<div style="font-size: 11px; color: #706e6b; margin-top: 2px;">Today at 10:30 AM</div>
|
|
1766
|
+
<div style="font-size: 12px; margin-top: 4px;">Q1 Review Meeting Follow-up</div>
|
|
1767
|
+
</div>
|
|
1768
|
+
<div style="margin-bottom: 12px;">
|
|
1769
|
+
<div style="font-weight: 600; font-size: 12px; color: #080707;">Meeting Completed</div>
|
|
1770
|
+
<div style="font-size: 11px; color: #706e6b; margin-top: 2px;">Yesterday at 2:00 PM</div>
|
|
1771
|
+
<div style="font-size: 12px; margin-top: 4px;">Quarterly Business Review</div>
|
|
1772
|
+
</div>
|
|
1773
|
+
<div style="margin-bottom: 12px;">
|
|
1774
|
+
<div style="font-weight: 600; font-size: 12px; color: #080707;">Opportunity Updated</div>
|
|
1775
|
+
<div style="font-size: 11px; color: #706e6b; margin-top: 2px;">2 days ago</div>
|
|
1776
|
+
<div style="font-size: 12px; margin-top: 4px;">Wealth Management Platform moved to Negotiation</div>
|
|
1777
|
+
</div>
|
|
1778
|
+
</div>
|
|
1779
|
+
</div>
|
|
1780
|
+
|
|
1781
|
+
<!-- Contact Info -->
|
|
1782
|
+
<div class="sf-section" style="margin-top: 15px;">
|
|
1783
|
+
<div class="sf-section-header">Primary Contact</div>
|
|
1784
|
+
<div class="sf-section-body">
|
|
1785
|
+
<div class="sf-field">
|
|
1786
|
+
<div class="sf-field-label">Name</div>
|
|
1787
|
+
<div class="sf-field-value"><a href="#" class="sf-link">Sarah Johnson</a></div>
|
|
1788
|
+
</div>
|
|
1789
|
+
<div class="sf-field" style="margin-top: 10px;">
|
|
1790
|
+
<div class="sf-field-label">Title</div>
|
|
1791
|
+
<div class="sf-field-value">VP of Operations</div>
|
|
1792
|
+
</div>
|
|
1793
|
+
<div class="sf-field" style="margin-top: 10px;">
|
|
1794
|
+
<div class="sf-field-label">Email</div>
|
|
1795
|
+
<div class="sf-field-value"><a href="#" class="sf-link">sjohnson@enterprisefinancial.com</a></div>
|
|
1796
|
+
</div>
|
|
1797
|
+
<div class="sf-field" style="margin-top: 10px;">
|
|
1798
|
+
<div class="sf-field-label">Phone</div>
|
|
1799
|
+
<div class="sf-field-value">(415) 555-0199</div>
|
|
1800
|
+
</div>
|
|
1801
|
+
</div>
|
|
1802
|
+
</div>
|
|
1803
|
+
</div>
|
|
1804
|
+
|
|
1805
|
+
</div>
|
|
1806
|
+
</div>
|
|
1807
|
+
|
|
1808
|
+
<!-- Iframe Expansion Modal Overlay (just for background) -->
|
|
1809
|
+
<div class="sf-iframe-modal-overlay" id="iframeModal" onclick="closeIframeModal(event)"></div>
|
|
1810
|
+
|
|
1811
|
+
<!-- Chat Widget -->
|
|
1812
|
+
<button class="chat-widget-button" id="chatButton" onclick="toggleChat()">
|
|
1813
|
+
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
1814
|
+
<path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z"/>
|
|
1815
|
+
<path d="M7 9h10v2H7zm0-3h10v2H7z"/>
|
|
1816
|
+
</svg>
|
|
1817
|
+
</button>
|
|
1818
|
+
|
|
1819
|
+
<div class="chat-widget-window" id="chatWindow">
|
|
1820
|
+
<div class="chat-widget-header">
|
|
1821
|
+
<div class="chat-widget-title">
|
|
1822
|
+
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
1823
|
+
<path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z"/>
|
|
1824
|
+
</svg>
|
|
1825
|
+
Sea Assistant
|
|
1826
|
+
</div>
|
|
1827
|
+
<div class="chat-widget-header-actions">
|
|
1828
|
+
<a href="https://app.sea.dev/deals/28eq483grdz4gbfkhsili/j62iaw4d5piudvlnjexzi" target="_blank" class="chat-widget-sea-link" title="Open in Sea.dev">↗</a>
|
|
1829
|
+
<button class="chat-widget-expand" onclick="toggleExpand()" title="Expand">⊡</button>
|
|
1830
|
+
<button class="chat-widget-close" onclick="toggleChat()">×</button>
|
|
1831
|
+
</div>
|
|
1832
|
+
</div>
|
|
1833
|
+
|
|
1834
|
+
<div class="chat-messages" id="chatMessages">
|
|
1835
|
+
<div class="chat-message assistant">
|
|
1836
|
+
<div class="chat-message-content">
|
|
1837
|
+
Hi, how can I help?
|
|
1838
|
+
</div>
|
|
1839
|
+
</div>
|
|
1840
|
+
</div>
|
|
1841
|
+
|
|
1842
|
+
<div class="chat-input-container">
|
|
1843
|
+
<input
|
|
1844
|
+
type="text"
|
|
1845
|
+
class="chat-input"
|
|
1846
|
+
id="chatInput"
|
|
1847
|
+
placeholder="Type your message..."
|
|
1848
|
+
onkeypress="handleChatKeypress(event)"
|
|
1849
|
+
/>
|
|
1850
|
+
<button class="chat-send-button" onclick="sendMessage()">
|
|
1851
|
+
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
1852
|
+
<path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
|
|
1853
|
+
</svg>
|
|
1854
|
+
</button>
|
|
1855
|
+
</div>
|
|
1856
|
+
</div>
|
|
1857
|
+
|
|
1858
|
+
<!-- OpenAI SDK -->
|
|
1859
|
+
<script src="https://cdn.jsdelivr.net/npm/openai@4.20.1/+esm" type="module"></script>
|
|
1860
|
+
|
|
1861
|
+
<script type="module">
|
|
1862
|
+
import OpenAI from 'https://cdn.jsdelivr.net/npm/openai@4.20.1/+esm';
|
|
1863
|
+
|
|
1864
|
+
// Initialize OpenAI
|
|
1865
|
+
const openai = new OpenAI({
|
|
1866
|
+
apiKey: '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',
|
|
1867
|
+
dangerouslyAllowBrowser: true
|
|
1868
|
+
});
|
|
1869
|
+
|
|
1870
|
+
// Make openai globally available
|
|
1871
|
+
window.openai = openai;
|
|
1872
|
+
window.conversationHistory = [];
|
|
1873
|
+
</script>
|
|
1874
|
+
|
|
1875
|
+
<script>
|
|
1876
|
+
// Switch main tabs (Opportunities, Contacts, Cases, etc.)
|
|
1877
|
+
function switchMainTab(tabName) {
|
|
1878
|
+
// Hide all main tab contents
|
|
1879
|
+
const tabContents = document.querySelectorAll('.sf-section > .sf-tab-content');
|
|
1880
|
+
tabContents.forEach(content => {
|
|
1881
|
+
content.classList.remove('active');
|
|
1882
|
+
});
|
|
1883
|
+
|
|
1884
|
+
// Remove active class from all tabs
|
|
1885
|
+
const tabs = document.querySelectorAll('.sf-tabs > .sf-tab');
|
|
1886
|
+
tabs.forEach(tab => {
|
|
1887
|
+
tab.classList.remove('active');
|
|
1888
|
+
});
|
|
1889
|
+
|
|
1890
|
+
// Show selected tab content
|
|
1891
|
+
const selectedContent = document.getElementById(tabName + '-content');
|
|
1892
|
+
if (selectedContent) {
|
|
1893
|
+
selectedContent.classList.add('active');
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
// Add active class to clicked tab
|
|
1897
|
+
event.target.classList.add('active');
|
|
1898
|
+
|
|
1899
|
+
// Toggle full-width layout for financials tab
|
|
1900
|
+
const mainContent = document.getElementById('mainContent');
|
|
1901
|
+
const accountDetails = document.getElementById('accountDetailsSection');
|
|
1902
|
+
|
|
1903
|
+
if (tabName === 'financials') {
|
|
1904
|
+
mainContent.classList.add('full-width');
|
|
1905
|
+
// Collapse account details when Financials tab is clicked
|
|
1906
|
+
if (accountDetails) {
|
|
1907
|
+
accountDetails.classList.add('collapsed');
|
|
1908
|
+
}
|
|
1909
|
+
} else {
|
|
1910
|
+
mainContent.classList.remove('full-width');
|
|
1911
|
+
// Expand account details for other tabs
|
|
1912
|
+
if (accountDetails) {
|
|
1913
|
+
accountDetails.classList.remove('collapsed');
|
|
1914
|
+
}
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
|
|
1918
|
+
// Switch financial sub-tabs (Upload, Spread, Results)
|
|
1919
|
+
function switchFinancialTab(tabName) {
|
|
1920
|
+
// Hide all financial tab contents
|
|
1921
|
+
const financialContents = document.querySelectorAll('#financials-content .sf-tab-content');
|
|
1922
|
+
financialContents.forEach(content => {
|
|
1923
|
+
content.classList.remove('active');
|
|
1924
|
+
});
|
|
1925
|
+
|
|
1926
|
+
// Remove active class from all financial tabs
|
|
1927
|
+
const financialTabs = document.querySelectorAll('.sf-financial-tab');
|
|
1928
|
+
financialTabs.forEach(tab => {
|
|
1929
|
+
tab.classList.remove('active');
|
|
1930
|
+
});
|
|
1931
|
+
|
|
1932
|
+
// Show selected financial tab content
|
|
1933
|
+
const selectedContent = document.getElementById(tabName + '-content');
|
|
1934
|
+
if (selectedContent) {
|
|
1935
|
+
selectedContent.classList.add('active');
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1938
|
+
// Add active class to clicked tab
|
|
1939
|
+
event.target.classList.add('active');
|
|
1940
|
+
}
|
|
1941
|
+
|
|
1942
|
+
|
|
1943
|
+
// Expand iframe to modal
|
|
1944
|
+
function expandIframe() {
|
|
1945
|
+
// Find the iframe container (either upload-widget or spread-viewer)
|
|
1946
|
+
const uploadWidget = document.getElementById('upload-widget');
|
|
1947
|
+
const spreadViewer = document.querySelector('.sf-spread-viewer');
|
|
1948
|
+
|
|
1949
|
+
let container = null;
|
|
1950
|
+
|
|
1951
|
+
// Check which container has the iframe
|
|
1952
|
+
if (uploadWidget && !uploadWidget.classList.contains('hidden')) {
|
|
1953
|
+
container = uploadWidget;
|
|
1954
|
+
} else if (spreadViewer) {
|
|
1955
|
+
container = spreadViewer;
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1958
|
+
if (!container) return;
|
|
1959
|
+
|
|
1960
|
+
// Add expanded class to container
|
|
1961
|
+
container.classList.add('expanded');
|
|
1962
|
+
|
|
1963
|
+
// Show modal overlay
|
|
1964
|
+
const modal = document.getElementById('iframeModal');
|
|
1965
|
+
if (modal) {
|
|
1966
|
+
modal.classList.add('active');
|
|
1967
|
+
// Prevent body scroll when modal is open
|
|
1968
|
+
document.body.style.overflow = 'hidden';
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1971
|
+
|
|
1972
|
+
// Close iframe modal
|
|
1973
|
+
function closeIframeModal(event) {
|
|
1974
|
+
// Remove expanded class from all containers
|
|
1975
|
+
const uploadWidget = document.getElementById('upload-widget');
|
|
1976
|
+
const spreadViewer = document.querySelector('.sf-spread-viewer');
|
|
1977
|
+
|
|
1978
|
+
if (uploadWidget) {
|
|
1979
|
+
uploadWidget.classList.remove('expanded');
|
|
1980
|
+
}
|
|
1981
|
+
if (spreadViewer) {
|
|
1982
|
+
spreadViewer.classList.remove('expanded');
|
|
1983
|
+
}
|
|
1984
|
+
|
|
1985
|
+
// Hide modal overlay
|
|
1986
|
+
const modal = document.getElementById('iframeModal');
|
|
1987
|
+
if (modal) {
|
|
1988
|
+
modal.classList.remove('active');
|
|
1989
|
+
// Restore body scroll
|
|
1990
|
+
document.body.style.overflow = '';
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
|
|
1994
|
+
// Close modal on Escape key
|
|
1995
|
+
document.addEventListener('keydown', function(event) {
|
|
1996
|
+
if (event.key === 'Escape') {
|
|
1997
|
+
closeIframeModal();
|
|
1998
|
+
}
|
|
1999
|
+
});
|
|
2000
|
+
|
|
2001
|
+
// Demo function to show financial results (would be triggered after actual upload)
|
|
2002
|
+
function showFinancialResults() {
|
|
2003
|
+
const noData = document.querySelector('.sf-no-data');
|
|
2004
|
+
const results = document.getElementById('financial-results');
|
|
2005
|
+
|
|
2006
|
+
if (noData) noData.style.display = 'none';
|
|
2007
|
+
if (results) results.style.display = 'block';
|
|
2008
|
+
}
|
|
2009
|
+
|
|
2010
|
+
// Toggle user menu dropdown
|
|
2011
|
+
function toggleUserMenu() {
|
|
2012
|
+
const dropdown = document.getElementById('userDropdown');
|
|
2013
|
+
dropdown.classList.toggle('active');
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
// Close dropdown when clicking outside
|
|
2017
|
+
document.addEventListener('click', function(event) {
|
|
2018
|
+
const userMenu = document.querySelector('.sf-user-menu');
|
|
2019
|
+
const dropdown = document.getElementById('userDropdown');
|
|
2020
|
+
if (dropdown && !userMenu.contains(event.target)) {
|
|
2021
|
+
dropdown.classList.remove('active');
|
|
2022
|
+
}
|
|
2023
|
+
});
|
|
2024
|
+
|
|
2025
|
+
// Toggle embedded features (AI Financials tab and Chat button)
|
|
2026
|
+
function toggleEmbedded() {
|
|
2027
|
+
const isChecked = document.getElementById('embeddedToggle').checked;
|
|
2028
|
+
const chatButton = document.getElementById('chatButton');
|
|
2029
|
+
const chatWindow = document.getElementById('chatWindow');
|
|
2030
|
+
const aiFinancialsTab = document.querySelector('.sf-financial-tab[onclick*="ai"]');
|
|
2031
|
+
const analysisErrorState = document.getElementById('analysis-error-state');
|
|
2032
|
+
const analysisActualContent = document.getElementById('analysis-actual-content');
|
|
2033
|
+
|
|
2034
|
+
if (chatButton) {
|
|
2035
|
+
chatButton.style.display = isChecked ? 'flex' : 'none';
|
|
2036
|
+
}
|
|
2037
|
+
if (chatWindow && !isChecked) {
|
|
2038
|
+
chatWindow.classList.remove('open');
|
|
2039
|
+
}
|
|
2040
|
+
if (aiFinancialsTab) {
|
|
2041
|
+
aiFinancialsTab.style.display = isChecked ? 'block' : 'none';
|
|
2042
|
+
}
|
|
2043
|
+
|
|
2044
|
+
// Toggle Financial Analysis content
|
|
2045
|
+
if (analysisErrorState && analysisActualContent) {
|
|
2046
|
+
if (isChecked) {
|
|
2047
|
+
analysisErrorState.style.display = 'none';
|
|
2048
|
+
analysisActualContent.style.display = 'block';
|
|
2049
|
+
} else {
|
|
2050
|
+
analysisErrorState.style.display = 'block';
|
|
2051
|
+
analysisActualContent.style.display = 'none';
|
|
2052
|
+
}
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
// If AI tab is hidden and currently active, switch to Input tab
|
|
2056
|
+
if (!isChecked) {
|
|
2057
|
+
const aiContent = document.getElementById('ai-content');
|
|
2058
|
+
if (aiContent && aiContent.classList.contains('active')) {
|
|
2059
|
+
switchFinancialTab('input');
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
// Populate Input Financials tab
|
|
2065
|
+
function toggleInputFinancials() {
|
|
2066
|
+
const isChecked = document.getElementById('inputFinancialsToggle').checked;
|
|
2067
|
+
|
|
2068
|
+
if (isChecked) {
|
|
2069
|
+
// Financial data from the provided dataset (using the latest period)
|
|
2070
|
+
const financialData = {
|
|
2071
|
+
revenue: '4489000000',
|
|
2072
|
+
refunds: '0',
|
|
2073
|
+
cogs: '2813000000',
|
|
2074
|
+
sga: '1184000000',
|
|
2075
|
+
ebit: '492000000',
|
|
2076
|
+
ebitda: '550000000',
|
|
2077
|
+
adjustedEbitda: '550000000',
|
|
2078
|
+
netIncome: '348000000',
|
|
2079
|
+
period: '2025-03-29',
|
|
2080
|
+
fiscalYearEnd: '2025-03-29'
|
|
2081
|
+
};
|
|
2082
|
+
|
|
2083
|
+
// Find and populate inputs in the Input Financials tab
|
|
2084
|
+
const inputTab = document.getElementById('input-content');
|
|
2085
|
+
if (inputTab) {
|
|
2086
|
+
// Get all input fields
|
|
2087
|
+
const allInputs = inputTab.querySelectorAll('input[type="text"], input[type="date"]');
|
|
2088
|
+
|
|
2089
|
+
// Populate based on labels or placeholders
|
|
2090
|
+
allInputs.forEach(input => {
|
|
2091
|
+
const label = input.previousElementSibling?.textContent || '';
|
|
2092
|
+
const placeholder = input.placeholder || '';
|
|
2093
|
+
|
|
2094
|
+
// Fiscal Year End Date
|
|
2095
|
+
if (input.type === 'date' || label.includes('FISCAL YEAR END DATE')) {
|
|
2096
|
+
input.value = financialData.fiscalYearEnd;
|
|
2097
|
+
}
|
|
2098
|
+
// Financial Period
|
|
2099
|
+
else if (label.includes('FINANCIAL PERIOD') || placeholder.includes('Q4') || placeholder.includes('FY')) {
|
|
2100
|
+
input.value = financialData.period;
|
|
2101
|
+
}
|
|
2102
|
+
// Currency (skip)
|
|
2103
|
+
else if (label.includes('CURRENCY')) {
|
|
2104
|
+
// Keep default USD
|
|
2105
|
+
}
|
|
2106
|
+
// Skip readonly fields
|
|
2107
|
+
else if (input.readOnly) {
|
|
2108
|
+
// Skip calculated fields
|
|
2109
|
+
}
|
|
2110
|
+
});
|
|
2111
|
+
|
|
2112
|
+
// Find all number inputs by placeholder
|
|
2113
|
+
const numberInputs = inputTab.querySelectorAll('input[placeholder="0"], input[placeholder="(0)"]');
|
|
2114
|
+
|
|
2115
|
+
// Map inputs to their parent labels to populate correctly (including readonly/calculated fields)
|
|
2116
|
+
numberInputs.forEach(input => {
|
|
2117
|
+
const parentDiv = input.closest('div');
|
|
2118
|
+
const label = parentDiv?.querySelector('label')?.textContent || '';
|
|
2119
|
+
|
|
2120
|
+
// Balance Sheet - Assets
|
|
2121
|
+
if (label.includes('Cash')) {
|
|
2122
|
+
input.value = '125,000,000';
|
|
2123
|
+
} else if (label.includes('Accounts Receivable')) {
|
|
2124
|
+
input.value = '85,000,000';
|
|
2125
|
+
} else if (label.includes('Inventory')) {
|
|
2126
|
+
input.value = '45,000,000';
|
|
2127
|
+
} else if (label.includes('Prepaid')) {
|
|
2128
|
+
input.value = '12,000,000';
|
|
2129
|
+
} else if (label.includes('Other Current Assets') && !label.includes('Total')) {
|
|
2130
|
+
input.value = '8,000,000';
|
|
2131
|
+
} else if (label.includes('Total Current Assets')) {
|
|
2132
|
+
input.value = '275,000,000';
|
|
2133
|
+
input.readOnly = false; // Force populate
|
|
2134
|
+
} else if (label.includes('Property, Plant')) {
|
|
2135
|
+
input.value = '350,000,000';
|
|
2136
|
+
} else if (label.includes('Accumulated Depreciation')) {
|
|
2137
|
+
input.value = '(120,000,000)';
|
|
2138
|
+
} else if (label.includes('Intangible')) {
|
|
2139
|
+
input.value = '75,000,000';
|
|
2140
|
+
} else if (label.includes('Goodwill')) {
|
|
2141
|
+
input.value = '95,000,000';
|
|
2142
|
+
} else if (label.includes('Other Non-Current Assets') && !label.includes('Total')) {
|
|
2143
|
+
input.value = '15,000,000';
|
|
2144
|
+
} else if (label.includes('Total Non-Current Assets')) {
|
|
2145
|
+
input.value = '415,000,000';
|
|
2146
|
+
input.readOnly = false;
|
|
2147
|
+
} else if (label.includes('TOTAL ASSETS')) {
|
|
2148
|
+
input.value = '690,000,000';
|
|
2149
|
+
input.readOnly = false;
|
|
2150
|
+
}
|
|
2151
|
+
|
|
2152
|
+
// Balance Sheet - Liabilities
|
|
2153
|
+
else if (label.includes('Accounts Payable')) {
|
|
2154
|
+
input.value = '65,000,000';
|
|
2155
|
+
} else if (label.includes('Accrued Expenses')) {
|
|
2156
|
+
input.value = '35,000,000';
|
|
2157
|
+
} else if (label.includes('Short-term Debt')) {
|
|
2158
|
+
input.value = '25,000,000';
|
|
2159
|
+
} else if (label.includes('Current Portion') && label.includes('Long-term')) {
|
|
2160
|
+
input.value = '15,000,000';
|
|
2161
|
+
} else if (label.includes('Unearned Revenue')) {
|
|
2162
|
+
input.value = '20,000,000';
|
|
2163
|
+
} else if (label.includes('Other Current Liabilities')) {
|
|
2164
|
+
input.value = '10,000,000';
|
|
2165
|
+
} else if (label.includes('Total Current Liabilities')) {
|
|
2166
|
+
input.value = '170,000,000';
|
|
2167
|
+
input.readOnly = false;
|
|
2168
|
+
} else if (label.includes('Long-term Debt') && !label.includes('Current')) {
|
|
2169
|
+
input.value = '200,000,000';
|
|
2170
|
+
} else if (label.includes('Deferred Tax')) {
|
|
2171
|
+
input.value = '18,000,000';
|
|
2172
|
+
} else if (label.includes('Other Non-Current Liabilities')) {
|
|
2173
|
+
input.value = '12,000,000';
|
|
2174
|
+
} else if (label.includes('Total Non-Current Liabilities')) {
|
|
2175
|
+
input.value = '230,000,000';
|
|
2176
|
+
input.readOnly = false;
|
|
2177
|
+
} else if (label.includes('TOTAL LIABILITIES')) {
|
|
2178
|
+
input.value = '400,000,000';
|
|
2179
|
+
input.readOnly = false;
|
|
2180
|
+
}
|
|
2181
|
+
|
|
2182
|
+
// Balance Sheet - Equity
|
|
2183
|
+
else if (label.includes('Common Stock')) {
|
|
2184
|
+
input.value = '50,000,000';
|
|
2185
|
+
} else if (label.includes('Additional Paid')) {
|
|
2186
|
+
input.value = '100,000,000';
|
|
2187
|
+
} else if (label.includes('Retained Earnings')) {
|
|
2188
|
+
input.value = '140,000,000';
|
|
2189
|
+
} else if (label.includes('Treasury Stock')) {
|
|
2190
|
+
input.value = '0';
|
|
2191
|
+
} else if (label.includes('TOTAL EQUITY') || label.includes("TOTAL SHAREHOLDERS' EQUITY")) {
|
|
2192
|
+
input.value = '290,000,000';
|
|
2193
|
+
input.readOnly = false;
|
|
2194
|
+
}
|
|
2195
|
+
|
|
2196
|
+
// Income Statement
|
|
2197
|
+
else if (label.includes('REVENUE') && !label.includes('Unearned') && !label.includes('NET')) {
|
|
2198
|
+
input.value = Number(financialData.revenue).toLocaleString();
|
|
2199
|
+
} else if (label.includes('REFUNDS')) {
|
|
2200
|
+
input.value = Number(financialData.refunds).toLocaleString();
|
|
2201
|
+
} else if (label.includes('NET REVENUE')) {
|
|
2202
|
+
input.value = Number(financialData.revenue).toLocaleString();
|
|
2203
|
+
input.readOnly = false;
|
|
2204
|
+
} else if (label.includes('COGS')) {
|
|
2205
|
+
input.value = Number(financialData.cogs).toLocaleString();
|
|
2206
|
+
} else if (label.includes('GROSS PROFIT')) {
|
|
2207
|
+
input.value = '1,676,000,000';
|
|
2208
|
+
input.readOnly = false;
|
|
2209
|
+
} else if (label.includes('SG&A')) {
|
|
2210
|
+
input.value = Number(financialData.sga).toLocaleString();
|
|
2211
|
+
} else if (label.includes('R&D')) {
|
|
2212
|
+
input.value = '0';
|
|
2213
|
+
} else if (label.includes('Other Operating')) {
|
|
2214
|
+
input.value = '0';
|
|
2215
|
+
} else if (label.includes('EBIT') && !label.includes('EBITDA')) {
|
|
2216
|
+
input.value = Number(financialData.ebit).toLocaleString();
|
|
2217
|
+
input.readOnly = false;
|
|
2218
|
+
} else if (label.includes('Interest Income')) {
|
|
2219
|
+
input.value = '5,000,000';
|
|
2220
|
+
} else if (label.includes('Interest Expense')) {
|
|
2221
|
+
input.value = '(18,000,000)';
|
|
2222
|
+
} else if (label.includes('Other Income')) {
|
|
2223
|
+
input.value = '2,000,000';
|
|
2224
|
+
} else if (label.includes('PRE-TAX INCOME')) {
|
|
2225
|
+
input.value = '481,000,000';
|
|
2226
|
+
input.readOnly = false;
|
|
2227
|
+
} else if (label.includes('Income Tax')) {
|
|
2228
|
+
input.value = '(133,000,000)';
|
|
2229
|
+
} else if (label.includes('NET INCOME')) {
|
|
2230
|
+
input.value = Number(financialData.netIncome).toLocaleString();
|
|
2231
|
+
input.readOnly = false;
|
|
2232
|
+
} else if (label.includes('Depreciation')) {
|
|
2233
|
+
input.value = '45,000,000';
|
|
2234
|
+
} else if (label.includes('Amortization')) {
|
|
2235
|
+
input.value = '13,000,000';
|
|
2236
|
+
} else if (label.includes('EBITDA') && !label.includes('ADJUSTED')) {
|
|
2237
|
+
input.value = Number(financialData.ebitda).toLocaleString();
|
|
2238
|
+
input.readOnly = false;
|
|
2239
|
+
} else if (label.includes('ADJUSTED EBITDA')) {
|
|
2240
|
+
input.value = Number(financialData.adjustedEbitda).toLocaleString();
|
|
2241
|
+
input.readOnly = false;
|
|
2242
|
+
}
|
|
2243
|
+
});
|
|
2244
|
+
}
|
|
2245
|
+
} else {
|
|
2246
|
+
// Clear form fields
|
|
2247
|
+
const inputTab = document.getElementById('input-content');
|
|
2248
|
+
if (inputTab) {
|
|
2249
|
+
const allInputs = inputTab.querySelectorAll('input[type="text"]:not([readonly]), input[type="date"]');
|
|
2250
|
+
allInputs.forEach(input => {
|
|
2251
|
+
input.value = '';
|
|
2252
|
+
});
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
|
|
2257
|
+
// Chat Widget Functions
|
|
2258
|
+
function toggleChat() {
|
|
2259
|
+
const chatWindow = document.getElementById('chatWindow');
|
|
2260
|
+
const chatButton = document.getElementById('chatButton');
|
|
2261
|
+
|
|
2262
|
+
chatWindow.classList.toggle('open');
|
|
2263
|
+
chatButton.classList.toggle('open');
|
|
2264
|
+
|
|
2265
|
+
if (chatWindow.classList.contains('open')) {
|
|
2266
|
+
document.getElementById('chatInput').focus();
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
|
|
2270
|
+
function toggleExpand() {
|
|
2271
|
+
const chatWindow = document.getElementById('chatWindow');
|
|
2272
|
+
chatWindow.classList.toggle('expanded');
|
|
2273
|
+
}
|
|
2274
|
+
|
|
2275
|
+
function handleChatKeypress(event) {
|
|
2276
|
+
if (event.key === 'Enter') {
|
|
2277
|
+
sendMessage();
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
|
|
2281
|
+
async function sendMessage() {
|
|
2282
|
+
console.log('sendMessage called');
|
|
2283
|
+
const input = document.getElementById('chatInput');
|
|
2284
|
+
const message = input.value.trim();
|
|
2285
|
+
console.log('Message:', message);
|
|
2286
|
+
|
|
2287
|
+
if (!message) {
|
|
2288
|
+
console.log('Empty message, returning');
|
|
2289
|
+
return;
|
|
2290
|
+
}
|
|
2291
|
+
|
|
2292
|
+
// Add user message
|
|
2293
|
+
console.log('Adding user message');
|
|
2294
|
+
addChatMessage('user', message);
|
|
2295
|
+
input.value = '';
|
|
2296
|
+
|
|
2297
|
+
// Add to conversation history
|
|
2298
|
+
window.conversationHistory.push({
|
|
2299
|
+
role: 'user',
|
|
2300
|
+
content: message
|
|
2301
|
+
});
|
|
2302
|
+
|
|
2303
|
+
// Show loading
|
|
2304
|
+
addLoadingMessage();
|
|
2305
|
+
|
|
2306
|
+
try {
|
|
2307
|
+
// Get AI response with streaming
|
|
2308
|
+
removeLoadingMessage();
|
|
2309
|
+
const streamingMessageId = addStreamingMessage();
|
|
2310
|
+
|
|
2311
|
+
const response = await generateAIResponseStreaming(message, streamingMessageId);
|
|
2312
|
+
console.log('Final response:', response);
|
|
2313
|
+
|
|
2314
|
+
// Add to conversation history
|
|
2315
|
+
window.conversationHistory.push({
|
|
2316
|
+
role: 'assistant',
|
|
2317
|
+
content: response
|
|
2318
|
+
});
|
|
2319
|
+
} catch (error) {
|
|
2320
|
+
console.error('Error getting AI response:', error);
|
|
2321
|
+
removeLoadingMessage();
|
|
2322
|
+
addChatMessage('assistant', 'I apologize, but I encountered an error. Please try again.');
|
|
2323
|
+
}
|
|
2324
|
+
}
|
|
2325
|
+
|
|
2326
|
+
function addChatMessage(role, content) {
|
|
2327
|
+
const messagesContainer = document.getElementById('chatMessages');
|
|
2328
|
+
const messageDiv = document.createElement('div');
|
|
2329
|
+
messageDiv.className = `chat-message ${role}`;
|
|
2330
|
+
|
|
2331
|
+
const contentDiv = document.createElement('div');
|
|
2332
|
+
contentDiv.className = 'chat-message-content';
|
|
2333
|
+
contentDiv.innerHTML = formatMessageContent(content);
|
|
2334
|
+
|
|
2335
|
+
messageDiv.appendChild(contentDiv);
|
|
2336
|
+
messagesContainer.appendChild(messageDiv);
|
|
2337
|
+
|
|
2338
|
+
// Scroll to bottom
|
|
2339
|
+
messagesContainer.scrollTop = messagesContainer.scrollHeight;
|
|
2340
|
+
}
|
|
2341
|
+
|
|
2342
|
+
function addLoadingMessage() {
|
|
2343
|
+
const messagesContainer = document.getElementById('chatMessages');
|
|
2344
|
+
const messageDiv = document.createElement('div');
|
|
2345
|
+
messageDiv.className = 'chat-message assistant';
|
|
2346
|
+
messageDiv.id = 'loading-message';
|
|
2347
|
+
|
|
2348
|
+
const contentDiv = document.createElement('div');
|
|
2349
|
+
contentDiv.className = 'chat-message-content';
|
|
2350
|
+
contentDiv.innerHTML = '<div class="chat-loading"><div class="chat-loading-dot"></div><div class="chat-loading-dot"></div><div class="chat-loading-dot"></div></div>';
|
|
2351
|
+
|
|
2352
|
+
messageDiv.appendChild(contentDiv);
|
|
2353
|
+
messagesContainer.appendChild(messageDiv);
|
|
2354
|
+
messagesContainer.scrollTop = messagesContainer.scrollHeight;
|
|
2355
|
+
}
|
|
2356
|
+
|
|
2357
|
+
function removeLoadingMessage() {
|
|
2358
|
+
const loadingMessage = document.getElementById('loading-message');
|
|
2359
|
+
if (loadingMessage) {
|
|
2360
|
+
loadingMessage.remove();
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2363
|
+
|
|
2364
|
+
function addStreamingMessage() {
|
|
2365
|
+
const messagesContainer = document.getElementById('chatMessages');
|
|
2366
|
+
const messageDiv = document.createElement('div');
|
|
2367
|
+
const messageId = 'streaming-message-' + Date.now();
|
|
2368
|
+
messageDiv.className = 'chat-message assistant';
|
|
2369
|
+
messageDiv.id = messageId;
|
|
2370
|
+
|
|
2371
|
+
const contentDiv = document.createElement('div');
|
|
2372
|
+
contentDiv.className = 'chat-message-content';
|
|
2373
|
+
contentDiv.innerHTML = '';
|
|
2374
|
+
|
|
2375
|
+
messageDiv.appendChild(contentDiv);
|
|
2376
|
+
messagesContainer.appendChild(messageDiv);
|
|
2377
|
+
messagesContainer.scrollTop = messagesContainer.scrollHeight;
|
|
2378
|
+
|
|
2379
|
+
return messageId;
|
|
2380
|
+
}
|
|
2381
|
+
|
|
2382
|
+
function updateStreamingMessage(messageId, content) {
|
|
2383
|
+
const messageDiv = document.getElementById(messageId);
|
|
2384
|
+
if (messageDiv) {
|
|
2385
|
+
const contentDiv = messageDiv.querySelector('.chat-message-content');
|
|
2386
|
+
contentDiv.innerHTML = formatMessageContent(content);
|
|
2387
|
+
|
|
2388
|
+
// Auto-scroll to bottom
|
|
2389
|
+
const messagesContainer = document.getElementById('chatMessages');
|
|
2390
|
+
messagesContainer.scrollTop = messagesContainer.scrollHeight;
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2394
|
+
function formatMessageContent(content) {
|
|
2395
|
+
// Convert markdown-like formatting
|
|
2396
|
+
let formatted = content
|
|
2397
|
+
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
|
|
2398
|
+
.replace(/\n/g, '<br>');
|
|
2399
|
+
|
|
2400
|
+
return formatted;
|
|
2401
|
+
}
|
|
2402
|
+
|
|
2403
|
+
// Tool Definitions for OpenAI Function Calling
|
|
2404
|
+
const tools = [
|
|
2405
|
+
{
|
|
2406
|
+
type: 'function',
|
|
2407
|
+
function: {
|
|
2408
|
+
name: 'get_account_info',
|
|
2409
|
+
description: 'Get information about the Enterprise Financial Group account',
|
|
2410
|
+
parameters: {
|
|
2411
|
+
type: 'object',
|
|
2412
|
+
properties: {},
|
|
2413
|
+
required: []
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
},
|
|
2417
|
+
{
|
|
2418
|
+
type: 'function',
|
|
2419
|
+
function: {
|
|
2420
|
+
name: 'get_financial_data',
|
|
2421
|
+
description: 'Get financial statement data including income statement and balance sheet',
|
|
2422
|
+
parameters: {
|
|
2423
|
+
type: 'object',
|
|
2424
|
+
properties: {
|
|
2425
|
+
statement_type: {
|
|
2426
|
+
type: 'string',
|
|
2427
|
+
enum: ['income_statement', 'balance_sheet', 'both'],
|
|
2428
|
+
description: 'Which financial statement to retrieve'
|
|
2429
|
+
}
|
|
2430
|
+
},
|
|
2431
|
+
required: []
|
|
2432
|
+
}
|
|
2433
|
+
}
|
|
2434
|
+
},
|
|
2435
|
+
{
|
|
2436
|
+
type: 'function',
|
|
2437
|
+
function: {
|
|
2438
|
+
name: 'get_financial_analysis',
|
|
2439
|
+
description: 'Get financial ratio analysis and industry comparisons',
|
|
2440
|
+
parameters: {
|
|
2441
|
+
type: 'object',
|
|
2442
|
+
properties: {},
|
|
2443
|
+
required: []
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
},
|
|
2447
|
+
{
|
|
2448
|
+
type: 'function',
|
|
2449
|
+
function: {
|
|
2450
|
+
name: 'get_opportunities',
|
|
2451
|
+
description: 'Get information about sales opportunities',
|
|
2452
|
+
parameters: {
|
|
2453
|
+
type: 'object',
|
|
2454
|
+
properties: {},
|
|
2455
|
+
required: []
|
|
2456
|
+
}
|
|
2457
|
+
}
|
|
2458
|
+
}
|
|
2459
|
+
];
|
|
2460
|
+
|
|
2461
|
+
// Tool Execution Functions
|
|
2462
|
+
function executeToolCall(toolName, args) {
|
|
2463
|
+
console.log('Executing tool:', toolName, 'with args:', args);
|
|
2464
|
+
|
|
2465
|
+
const inputFinancialsChecked = document.getElementById('inputFinancialsToggle')?.checked;
|
|
2466
|
+
|
|
2467
|
+
switch(toolName) {
|
|
2468
|
+
case 'get_account_info':
|
|
2469
|
+
return {
|
|
2470
|
+
name: 'Enterprise Financial Group',
|
|
2471
|
+
type: 'Customer - Direct',
|
|
2472
|
+
annualRevenue: '$45,000,000',
|
|
2473
|
+
industry: 'Financial Services',
|
|
2474
|
+
pipelineValue: '$2,100,000',
|
|
2475
|
+
contact: 'Sarah Johnson - VP of Operations'
|
|
2476
|
+
};
|
|
2477
|
+
|
|
2478
|
+
case 'get_financial_data':
|
|
2479
|
+
if (!inputFinancialsChecked) {
|
|
2480
|
+
return { error: 'Financial data not available. Please enable Input Financials from the user menu.' };
|
|
2481
|
+
}
|
|
2482
|
+
return {
|
|
2483
|
+
incomeStatement: {
|
|
2484
|
+
revenue: 4489000000,
|
|
2485
|
+
cogs: -2813000000,
|
|
2486
|
+
sga: -1184000000,
|
|
2487
|
+
ebit: 492000000,
|
|
2488
|
+
ebitda: 550000000,
|
|
2489
|
+
adjustedEbitda: 550000000,
|
|
2490
|
+
netIncome: 348000000,
|
|
2491
|
+
grossProfit: 1676000000,
|
|
2492
|
+
period: '2025-03-29'
|
|
2493
|
+
},
|
|
2494
|
+
balanceSheet: {
|
|
2495
|
+
cash: 125000000,
|
|
2496
|
+
accountsReceivable: 85000000,
|
|
2497
|
+
inventory: 45000000,
|
|
2498
|
+
totalCurrentAssets: 275000000,
|
|
2499
|
+
ppe: 350000000,
|
|
2500
|
+
totalAssets: 690000000,
|
|
2501
|
+
totalLiabilities: 400000000,
|
|
2502
|
+
totalEquity: 290000000
|
|
2503
|
+
}
|
|
2504
|
+
};
|
|
2505
|
+
|
|
2506
|
+
case 'get_financial_analysis':
|
|
2507
|
+
if (!inputFinancialsChecked) {
|
|
2508
|
+
return { error: 'Financial analysis not available. Please enable Input Financials from the user menu.' };
|
|
2509
|
+
}
|
|
2510
|
+
return {
|
|
2511
|
+
ratios: {
|
|
2512
|
+
currentRatio: 2.1,
|
|
2513
|
+
quickRatio: 1.8,
|
|
2514
|
+
debtToEquity: 1.9,
|
|
2515
|
+
debtToEbitda: 2.8,
|
|
2516
|
+
dscr: 1.45,
|
|
2517
|
+
interestCoverage: 5.2,
|
|
2518
|
+
netProfitMargin: 0.124,
|
|
2519
|
+
grossMargin: 0.373,
|
|
2520
|
+
roa: 0.087,
|
|
2521
|
+
roe: 0.153
|
|
2522
|
+
},
|
|
2523
|
+
industryComparison: {
|
|
2524
|
+
currentRatio: '15% above industry standard',
|
|
2525
|
+
quickRatio: '12% above industry standard',
|
|
2526
|
+
debtToEquity: '10% below industry standard',
|
|
2527
|
+
dscr: '20% above industry standard',
|
|
2528
|
+
interestCoverage: '30% above industry standard',
|
|
2529
|
+
netProfitMargin: '18% above industry standard'
|
|
2530
|
+
}
|
|
2531
|
+
};
|
|
2532
|
+
|
|
2533
|
+
case 'get_opportunities':
|
|
2534
|
+
return {
|
|
2535
|
+
total: 8,
|
|
2536
|
+
totalValue: '$2,100,000',
|
|
2537
|
+
opportunities: [
|
|
2538
|
+
{ name: 'Wealth Management Platform', amount: '$250,000', stage: 'Negotiation', probability: '75%' },
|
|
2539
|
+
{ name: 'Investment Portfolio System', amount: '$180,000', stage: 'Proposal', probability: '50%' },
|
|
2540
|
+
{ name: 'Risk Assessment Tools', amount: '$320,000', stage: 'Closed Won', probability: '100%' }
|
|
2541
|
+
]
|
|
2542
|
+
};
|
|
2543
|
+
|
|
2544
|
+
default:
|
|
2545
|
+
return { error: 'Unknown tool: ' + toolName };
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2548
|
+
|
|
2549
|
+
// Generate AI response using OpenAI with streaming
|
|
2550
|
+
async function generateAIResponseStreaming(userMessage, streamingMessageId) {
|
|
2551
|
+
console.log('generateAIResponseStreaming called with:', userMessage);
|
|
2552
|
+
|
|
2553
|
+
const systemPrompt = `You are Sea Assistant, a helpful AI assistant for a CRM system. You help users with:
|
|
2554
|
+
- Account information for Enterprise Financial Group
|
|
2555
|
+
- Financial data analysis (when available)
|
|
2556
|
+
- Sales opportunities and pipeline information
|
|
2557
|
+
- Contact details
|
|
2558
|
+
- Activity tracking
|
|
2559
|
+
|
|
2560
|
+
When financial data is available, you can access detailed income statements, balance sheets, and financial ratios.
|
|
2561
|
+
|
|
2562
|
+
Format your responses with HTML for better readability:
|
|
2563
|
+
- Use <strong> for emphasis
|
|
2564
|
+
- Use <br> for line breaks
|
|
2565
|
+
- Use bullet points with •
|
|
2566
|
+
- Keep responses concise but informative
|
|
2567
|
+
|
|
2568
|
+
Available data context:
|
|
2569
|
+
- Account: Enterprise Financial Group (Financial Services industry)
|
|
2570
|
+
- Current opportunities: 8 open deals worth $2.1M total
|
|
2571
|
+
- Primary contact: Sarah Johnson (VP of Operations)`;
|
|
2572
|
+
|
|
2573
|
+
const messages = [
|
|
2574
|
+
{ role: 'system', content: systemPrompt },
|
|
2575
|
+
...window.conversationHistory
|
|
2576
|
+
];
|
|
2577
|
+
|
|
2578
|
+
try {
|
|
2579
|
+
console.log('Calling OpenAI API with streaming...');
|
|
2580
|
+
const stream = await window.openai.chat.completions.create({
|
|
2581
|
+
model: 'gpt-4o-mini',
|
|
2582
|
+
messages: messages,
|
|
2583
|
+
tools: tools,
|
|
2584
|
+
tool_choice: 'auto',
|
|
2585
|
+
stream: true
|
|
2586
|
+
});
|
|
2587
|
+
|
|
2588
|
+
console.log('Stream created');
|
|
2589
|
+
let fullContent = '';
|
|
2590
|
+
let toolCalls = [];
|
|
2591
|
+
let currentToolCall = null;
|
|
2592
|
+
|
|
2593
|
+
for await (const chunk of stream) {
|
|
2594
|
+
const delta = chunk.choices[0]?.delta;
|
|
2595
|
+
|
|
2596
|
+
// Handle tool calls
|
|
2597
|
+
if (delta?.tool_calls) {
|
|
2598
|
+
for (const toolCallDelta of delta.tool_calls) {
|
|
2599
|
+
if (toolCallDelta.index !== undefined) {
|
|
2600
|
+
if (!toolCalls[toolCallDelta.index]) {
|
|
2601
|
+
toolCalls[toolCallDelta.index] = {
|
|
2602
|
+
id: toolCallDelta.id || '',
|
|
2603
|
+
type: 'function',
|
|
2604
|
+
function: { name: '', arguments: '' }
|
|
2605
|
+
};
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2608
|
+
const toolCall = toolCalls[toolCallDelta.index];
|
|
2609
|
+
if (toolCallDelta.id) toolCall.id = toolCallDelta.id;
|
|
2610
|
+
if (toolCallDelta.function?.name) toolCall.function.name = toolCallDelta.function.name;
|
|
2611
|
+
if (toolCallDelta.function?.arguments) toolCall.function.arguments += toolCallDelta.function.arguments;
|
|
2612
|
+
}
|
|
2613
|
+
}
|
|
2614
|
+
}
|
|
2615
|
+
|
|
2616
|
+
// Handle content
|
|
2617
|
+
if (delta?.content) {
|
|
2618
|
+
fullContent += delta.content;
|
|
2619
|
+
updateStreamingMessage(streamingMessageId, fullContent);
|
|
2620
|
+
}
|
|
2621
|
+
}
|
|
2622
|
+
|
|
2623
|
+
// If there were tool calls, execute them and get final response
|
|
2624
|
+
if (toolCalls.length > 0) {
|
|
2625
|
+
console.log('Tool calls detected:', toolCalls);
|
|
2626
|
+
updateStreamingMessage(streamingMessageId, fullContent + '<br><br><em>Fetching data...</em>');
|
|
2627
|
+
|
|
2628
|
+
// Add assistant message with tool calls to history
|
|
2629
|
+
messages.push({
|
|
2630
|
+
role: 'assistant',
|
|
2631
|
+
content: fullContent || null,
|
|
2632
|
+
tool_calls: toolCalls
|
|
2633
|
+
});
|
|
2634
|
+
|
|
2635
|
+
// Execute each tool call
|
|
2636
|
+
for (const toolCall of toolCalls) {
|
|
2637
|
+
const functionName = toolCall.function.name;
|
|
2638
|
+
const functionArgs = JSON.parse(toolCall.function.arguments);
|
|
2639
|
+
|
|
2640
|
+
console.log(`Executing tool: ${functionName}`);
|
|
2641
|
+
const toolResult = executeToolCall(functionName, functionArgs);
|
|
2642
|
+
|
|
2643
|
+
// Add tool result to messages
|
|
2644
|
+
messages.push({
|
|
2645
|
+
role: 'tool',
|
|
2646
|
+
tool_call_id: toolCall.id,
|
|
2647
|
+
content: JSON.stringify(toolResult)
|
|
2648
|
+
});
|
|
2649
|
+
}
|
|
2650
|
+
|
|
2651
|
+
// Get final response with tool results (streaming)
|
|
2652
|
+
console.log('Getting final response with tool results...');
|
|
2653
|
+
const finalStream = await window.openai.chat.completions.create({
|
|
2654
|
+
model: 'gpt-4o-mini',
|
|
2655
|
+
messages: messages,
|
|
2656
|
+
stream: true
|
|
2657
|
+
});
|
|
2658
|
+
|
|
2659
|
+
fullContent = '';
|
|
2660
|
+
for await (const chunk of finalStream) {
|
|
2661
|
+
const delta = chunk.choices[0]?.delta;
|
|
2662
|
+
if (delta?.content) {
|
|
2663
|
+
fullContent += delta.content;
|
|
2664
|
+
updateStreamingMessage(streamingMessageId, fullContent);
|
|
2665
|
+
}
|
|
2666
|
+
}
|
|
2667
|
+
}
|
|
2668
|
+
|
|
2669
|
+
console.log('Streaming complete. Final content:', fullContent);
|
|
2670
|
+
return fullContent;
|
|
2671
|
+
} catch (error) {
|
|
2672
|
+
console.error('Error in generateAIResponseStreaming:', error);
|
|
2673
|
+
throw error;
|
|
2674
|
+
}
|
|
2675
|
+
}
|
|
2676
|
+
</script>
|
|
2677
|
+
</body>
|
|
2678
|
+
</html>
|