@burdenoff/microfe-proserviceworld 2026.703.1 → 2026.706.2

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.
Files changed (79) hide show
  1. package/dist/index.js +2 -3
  2. package/dist/node_modules/clsx/dist/clsx.js +18 -0
  3. package/dist/node_modules/clsx/dist/clsx.js.map +1 -0
  4. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js +1716 -0
  5. package/dist/node_modules/tailwind-merge/dist/bundle-mjs.js.map +1 -0
  6. package/dist/proserviceworld/ProServiceWorldRoot.js +92 -136
  7. package/dist/proserviceworld/ProServiceWorldRoot.js.map +1 -1
  8. package/dist/proserviceworld/ProServiceWorldRoutes.js +18 -26
  9. package/dist/proserviceworld/ProServiceWorldRoutes.js.map +1 -1
  10. package/dist/proserviceworld/components/DiscussionThread.js +76 -0
  11. package/dist/proserviceworld/components/DiscussionThread.js.map +1 -0
  12. package/dist/proserviceworld/components/ui.js +273 -0
  13. package/dist/proserviceworld/components/ui.js.map +1 -0
  14. package/dist/proserviceworld/hooks/useEntityComments.js +56 -0
  15. package/dist/proserviceworld/hooks/useEntityComments.js.map +1 -0
  16. package/dist/proserviceworld/hooks/useFiles.js +45 -0
  17. package/dist/proserviceworld/hooks/useFiles.js.map +1 -0
  18. package/dist/proserviceworld/hooks/useProServiceWorldApi.js +416 -0
  19. package/dist/proserviceworld/hooks/useProServiceWorldApi.js.map +1 -0
  20. package/dist/proserviceworld/index.js +0 -1
  21. package/dist/proserviceworld/pages/AnalyticsPage.js +163 -475
  22. package/dist/proserviceworld/pages/AnalyticsPage.js.map +1 -1
  23. package/dist/proserviceworld/pages/ClientDetailPage.js +243 -0
  24. package/dist/proserviceworld/pages/ClientDetailPage.js.map +1 -0
  25. package/dist/proserviceworld/pages/ClientsPage.js +295 -0
  26. package/dist/proserviceworld/pages/ClientsPage.js.map +1 -0
  27. package/dist/proserviceworld/pages/CompliancePage.js +307 -0
  28. package/dist/proserviceworld/pages/CompliancePage.js.map +1 -0
  29. package/dist/proserviceworld/pages/ConflictsPage.js +234 -0
  30. package/dist/proserviceworld/pages/ConflictsPage.js.map +1 -0
  31. package/dist/proserviceworld/pages/DashboardPage.js +179 -632
  32. package/dist/proserviceworld/pages/DashboardPage.js.map +1 -1
  33. package/dist/proserviceworld/pages/DocumentsPage.js +235 -539
  34. package/dist/proserviceworld/pages/DocumentsPage.js.map +1 -1
  35. package/dist/proserviceworld/pages/EngagementDetailPage.js +449 -0
  36. package/dist/proserviceworld/pages/EngagementDetailPage.js.map +1 -0
  37. package/dist/proserviceworld/pages/EngagementsPage.js +256 -0
  38. package/dist/proserviceworld/pages/EngagementsPage.js.map +1 -0
  39. package/dist/proserviceworld/pages/InvoicesPage.js +303 -0
  40. package/dist/proserviceworld/pages/InvoicesPage.js.map +1 -0
  41. package/dist/proserviceworld/pages/MattersPage.js +275 -0
  42. package/dist/proserviceworld/pages/MattersPage.js.map +1 -0
  43. package/dist/proserviceworld/pages/PracticeAreasPage.js +176 -0
  44. package/dist/proserviceworld/pages/PracticeAreasPage.js.map +1 -0
  45. package/dist/proserviceworld/pages/TimePage.js +310 -0
  46. package/dist/proserviceworld/pages/TimePage.js.map +1 -0
  47. package/dist/proserviceworld/utils/cn.js +10 -0
  48. package/dist/proserviceworld/utils/cn.js.map +1 -0
  49. package/dist/proserviceworld/utils/nav.js +11 -0
  50. package/dist/proserviceworld/utils/nav.js.map +1 -0
  51. package/package.json +1 -1
  52. package/dist/proserviceworld/pages/AdminReportsPage.js +0 -579
  53. package/dist/proserviceworld/pages/AdminReportsPage.js.map +0 -1
  54. package/dist/proserviceworld/pages/AdminUsersPage.js +0 -468
  55. package/dist/proserviceworld/pages/AdminUsersPage.js.map +0 -1
  56. package/dist/proserviceworld/pages/BookingsPage.js +0 -446
  57. package/dist/proserviceworld/pages/BookingsPage.js.map +0 -1
  58. package/dist/proserviceworld/pages/MessagesPage.js +0 -238
  59. package/dist/proserviceworld/pages/MessagesPage.js.map +0 -1
  60. package/dist/proserviceworld/pages/PaymentsPage.js +0 -537
  61. package/dist/proserviceworld/pages/PaymentsPage.js.map +0 -1
  62. package/dist/proserviceworld/pages/ProjectsPage.js +0 -627
  63. package/dist/proserviceworld/pages/ProjectsPage.js.map +0 -1
  64. package/dist/proserviceworld/pages/ProviderDetailPage.js +0 -538
  65. package/dist/proserviceworld/pages/ProviderDetailPage.js.map +0 -1
  66. package/dist/proserviceworld/pages/ProvidersPage.js +0 -347
  67. package/dist/proserviceworld/pages/ProvidersPage.js.map +0 -1
  68. package/dist/proserviceworld/pages/ReviewsPage.js +0 -356
  69. package/dist/proserviceworld/pages/ReviewsPage.js.map +0 -1
  70. package/dist/proserviceworld/pages/ServiceDetailsPage.js +0 -631
  71. package/dist/proserviceworld/pages/ServiceDetailsPage.js.map +0 -1
  72. package/dist/proserviceworld/pages/ServicesPage.js +0 -344
  73. package/dist/proserviceworld/pages/ServicesPage.js.map +0 -1
  74. package/dist/proserviceworld/pages/VerificationPage.js +0 -370
  75. package/dist/proserviceworld/pages/VerificationPage.js.map +0 -1
  76. package/dist/proserviceworld/store/proserviceworldStore.js +0 -2490
  77. package/dist/proserviceworld/store/proserviceworldStore.js.map +0 -1
  78. package/dist/proserviceworld/utils/i18n.js +0 -15
  79. package/dist/proserviceworld/utils/i18n.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ProServiceWorldRoot.js","names":[],"sources":["../../src/proserviceworld/ProServiceWorldRoot.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useCallback, useEffect } from 'react';\nimport { LayoutDashboard, FileText, Settings, Users } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell';\nimport { ProServiceWorldProvider } from './providers/ProServiceWorldProvider';\nimport { FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';\nimport type { NavItem, ProServiceWorldRootProps } from './types';\nimport { ProServiceWorldRoutes } from './ProServiceWorldRoutes';\nimport { joinPath } from './utils/navigation';\nimport { tWithFallback } from './utils/i18n';\n\nexport const ProServiceWorldRoot: FC<ProServiceWorldRootProps> = (props) => {\n const { registerNavItems, registerFooterItems, basePath = '/' } = props;\n const { t } = useI18n();\n const tr = useCallback(\n (key: string, fallback: string): string => tWithFallback(t, key, fallback),\n [t]\n );\n\n useEffect(() => {\n if (!registerNavItems) return;\n const navItem: NavItem = {\n id: 'proserviceworld',\n label: tr('proserviceworld.nav.root', 'ProServiceWorld'),\n path: basePath,\n icon: <LayoutDashboard size={20} />,\n order: 80, // Dynamic order handled elsewhere or fixed\n group: 'products',\n children: [\n {\n id: 'proserviceworld-dashboard',\n label: tr('proserviceworld.nav.dashboard', 'Dashboard'),\n path: basePath,\n icon: <LayoutDashboard size={16} />,\n order: 0,\n },\n {\n id: 'proserviceworld-admin',\n label: tr('proserviceworld.nav.admin.section', 'Admin'),\n path: joinPath(basePath, 'admin'),\n icon: <Settings size={16} />,\n children: [\n {\n id: 'proserviceworld-admin-reports',\n label: tr('proserviceworld.nav.admin.reports', 'Reports'),\n path: joinPath(basePath, 'reports'),\n icon: <FileText size={16} />,\n },\n {\n id: 'proserviceworld-admin-users',\n label: tr('proserviceworld.nav.admin.users', 'Users'),\n path: joinPath(basePath, 'users'),\n icon: <Users size={16} />,\n },\n ],\n },\n {\n id: 'proserviceworld-analytics',\n label: tr('proserviceworld.nav.analytics', 'Analytics'),\n path: joinPath(basePath, 'analytics'),\n icon: <FileText size={16} />,\n },\n {\n id: 'proserviceworld-bookings',\n label: tr('proserviceworld.nav.bookings', 'Bookings'),\n path: joinPath(basePath, 'bookings'),\n icon: <FileText size={16} />,\n },\n {\n id: 'proserviceworld-documents',\n label: tr('proserviceworld.nav.documents', 'Documents'),\n path: joinPath(basePath, 'documents'),\n icon: <FileText size={16} />,\n },\n {\n id: 'proserviceworld-messages',\n label: tr('proserviceworld.nav.messages', 'Messages'),\n path: joinPath(basePath, 'messages'),\n icon: <FileText size={16} />,\n },\n {\n id: 'proserviceworld-notifications',\n label: tr('proserviceworld.nav.notifications', 'Notifications'),\n path: joinPath(basePath, 'notifications'),\n icon: <FileText size={16} />,\n },\n {\n id: 'proserviceworld-payments',\n label: tr('proserviceworld.nav.payments', 'Payments'),\n path: joinPath(basePath, 'payments'),\n icon: <FileText size={16} />,\n },\n {\n id: 'proserviceworld-projects',\n label: tr('proserviceworld.nav.projects', 'Projects'),\n path: joinPath(basePath, 'projects'),\n icon: <FileText size={16} />,\n },\n {\n id: 'proserviceworld-provider-detail',\n label: tr('proserviceworld.nav.providerDetail', 'Provider Detail'),\n path: joinPath(basePath, 'provider-detail'),\n icon: <FileText size={16} />,\n },\n {\n id: 'proserviceworld-providers',\n label: tr('proserviceworld.nav.providers', 'Providers'),\n path: joinPath(basePath, 'providers'),\n icon: <FileText size={16} />,\n },\n {\n id: 'proserviceworld-reviews',\n label: tr('proserviceworld.nav.reviews', 'Reviews'),\n path: joinPath(basePath, 'reviews'),\n icon: <FileText size={16} />,\n },\n {\n id: 'proserviceworld-service-details',\n label: tr('proserviceworld.nav.serviceDetails', 'Service Details'),\n path: joinPath(basePath, 'service-details'),\n icon: <FileText size={16} />,\n },\n {\n id: 'proserviceworld-services',\n label: tr('proserviceworld.nav.services', 'Services'),\n path: joinPath(basePath, 'services'),\n icon: <FileText size={16} />,\n },\n {\n id: 'proserviceworld-verification',\n label: tr('proserviceworld.nav.verification', 'Verification'),\n path: joinPath(basePath, 'verification'),\n icon: <FileText size={16} />,\n },\n ],\n };\n return registerNavItems(navItem);\n }, [registerNavItems, basePath, tr]);\n\n useEffect(() => {\n if (!registerFooterItems) return;\n return registerFooterItems([\n {\n id: 'proserviceworld-status',\n label: tr('proserviceworld.footer.ready', 'ProServiceWorld Ready'),\n type: 'status',\n section: 'left',\n order: 10,\n },\n ]);\n }, [registerFooterItems, tr]);\n\n return (\n <FeatureFlagProvider workspaceId={null} gateway=\"global\" defaultEnabled={true}>\n <ProServiceWorldProvider {...props}>\n <ProServiceWorldRoutes />\n </ProServiceWorldProvider>\n </FeatureFlagProvider>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"ProServiceWorldRoot.js","names":[],"sources":["../../src/proserviceworld/ProServiceWorldRoot.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useEffect } from 'react';\nimport {\n LayoutDashboard,\n Building2,\n Briefcase,\n FolderKanban,\n Clock,\n Receipt,\n ShieldCheck,\n GitBranch,\n FileText,\n LayoutGrid,\n BarChart2,\n} from 'lucide-react';\nimport { FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { ProServiceWorldProvider } from './providers/ProServiceWorldProvider';\nimport type { NavItem, ProServiceWorldRootProps } from './types';\nimport { ProServiceWorldRoutes } from './ProServiceWorldRoutes';\nimport { joinPath } from './utils/navigation';\n\n/**\n * The authoritative sidebar navigation is registered by the host app shell\n * (proserviceworld-app NavRegistration). These items are only used when the MFE\n * is mounted standalone with `registerNavItems` provided — they mirror the\n * shell's canonical professional-services routes exactly.\n */\nconst NAV: { id: string; label: string; path: string; icon: FC<{ size?: number }> }[] = [\n { id: 'dashboard', label: 'Dashboard', path: '', icon: LayoutDashboard },\n { id: 'clients', label: 'Clients', path: 'clients', icon: Building2 },\n { id: 'engagements', label: 'Engagements', path: 'engagements', icon: Briefcase },\n { id: 'matters', label: 'Matters', path: 'matters', icon: FolderKanban },\n { id: 'time', label: 'Time', path: 'time', icon: Clock },\n { id: 'invoices', label: 'Invoices', path: 'invoices', icon: Receipt },\n { id: 'compliance', label: 'Compliance', path: 'compliance', icon: ShieldCheck },\n { id: 'conflicts', label: 'Conflict Checks', path: 'conflicts', icon: GitBranch },\n { id: 'documents', label: 'Documents', path: 'documents', icon: FileText },\n { id: 'practice-areas', label: 'Practice Areas', path: 'practice-areas', icon: LayoutGrid },\n { id: 'analytics', label: 'Analytics', path: 'analytics', icon: BarChart2 },\n];\n\nexport const ProServiceWorldRoot: FC<ProServiceWorldRootProps> = (props) => {\n const { registerNavItems, basePath = '/' } = props;\n\n useEffect(() => {\n if (!registerNavItems) return;\n const navItem: NavItem = {\n id: 'proserviceworld',\n label: 'ProServiceWorld',\n path: basePath,\n icon: <LayoutDashboard size={20} />,\n order: 80,\n group: 'products',\n children: NAV.map((n, i) => ({\n id: `proserviceworld-${n.id}`,\n label: n.label,\n path: joinPath(basePath, n.path),\n icon: <n.icon size={16} />,\n order: i,\n })),\n };\n return registerNavItems(navItem);\n }, [registerNavItems, basePath]);\n\n return (\n <FeatureFlagProvider workspaceId={null} gateway=\"global\" defaultEnabled={true}>\n <ProServiceWorldProvider {...props}>\n <ProServiceWorldRoutes />\n </ProServiceWorldProvider>\n </FeatureFlagProvider>\n );\n};\n"],"mappings":";;;;;;;;AA2BA,IAAM,IAAkF;CACtF;EAAE,IAAI;EAAa,OAAO;EAAa,MAAM;EAAI,MAAM;EAAiB;CACxE;EAAE,IAAI;EAAW,OAAO;EAAW,MAAM;EAAW,MAAM;EAAW;CACrE;EAAE,IAAI;EAAe,OAAO;EAAe,MAAM;EAAe,MAAM;EAAW;CACjF;EAAE,IAAI;EAAW,OAAO;EAAW,MAAM;EAAW,MAAM;EAAc;CACxE;EAAE,IAAI;EAAQ,OAAO;EAAQ,MAAM;EAAQ,MAAM;EAAO;CACxD;EAAE,IAAI;EAAY,OAAO;EAAY,MAAM;EAAY,MAAM;EAAS;CACtE;EAAE,IAAI;EAAc,OAAO;EAAc,MAAM;EAAc,MAAM;EAAa;CAChF;EAAE,IAAI;EAAa,OAAO;EAAmB,MAAM;EAAa,MAAM;EAAW;CACjF;EAAE,IAAI;EAAa,OAAO;EAAa,MAAM;EAAa,MAAM;EAAU;CAC1E;EAAE,IAAI;EAAkB,OAAO;EAAkB,MAAM;EAAkB,MAAM;EAAY;CAC3F;EAAE,IAAI;EAAa,OAAO;EAAa,MAAM;EAAa,MAAM;EAAW;CAC5E,EAEY,KAAqD,MAAU;CAC1E,IAAM,EAAE,qBAAkB,cAAW,QAAQ;AAsB7C,QApBA,QAAgB;AACT,QAgBL,QAAO,EAfkB;GACvB,IAAI;GACJ,OAAO;GACP,MAAM;GACN,MAAM,kBAAC,GAAD,EAAiB,MAAM,IAAM,CAAA;GACnC,OAAO;GACP,OAAO;GACP,UAAU,EAAI,KAAK,GAAG,OAAO;IAC3B,IAAI,mBAAmB,EAAE;IACzB,OAAO,EAAE;IACT,MAAM,EAAS,GAAU,EAAE,KAAK;IAChC,MAAM,kBAAC,EAAE,MAAH,EAAQ,MAAM,IAAM,CAAA;IAC1B,OAAO;IACR,EAAE;GACJ,CAC+B;IAC/B,CAAC,GAAkB,EAAS,CAAC,EAG9B,kBAAC,GAAD;EAAqB,aAAa;EAAM,SAAQ;EAAS,gBAAgB;YACvE,kBAAC,GAAD;GAAyB,GAAI;aAC3B,kBAAC,GAAD,EAAyB,CAAA;GACD,CAAA;EACN,CAAA"}
@@ -4,77 +4,69 @@ import { Loader2 as r } from "lucide-react";
4
4
  import { Navigate as i, Route as a, Routes as o } from "react-router-dom";
5
5
  import { jsx as s, jsxs as c } from "react/jsx-runtime";
6
6
  //#region src/proserviceworld/ProServiceWorldRoutes.tsx
7
- var l = n(() => import("./pages/AdminUsersPage.js").then((e) => ({ default: e.AdminUsersPage }))), u = n(() => import("./pages/AnalyticsPage.js").then((e) => ({ default: e.AnalyticsPage }))), d = n(() => import("./pages/BookingsPage.js").then((e) => ({ default: e.BookingsPage }))), f = n(() => import("./pages/AdminReportsPage.js").then((e) => ({ default: e.AdminReportsPage }))), p = n(() => import("./pages/DocumentsPage.js").then((e) => ({ default: e.DocumentsPage }))), m = n(() => import("./pages/MessagesPage.js").then((e) => ({ default: e.MessagesPage }))), h = n(() => import("./pages/PaymentsPage.js").then((e) => ({ default: e.PaymentsPage }))), g = n(() => import("./pages/ProjectsPage.js").then((e) => ({ default: e.ProjectsPage }))), _ = n(() => import("./pages/ProviderDetailPage.js").then((e) => ({ default: e.ProviderDetailPage }))), v = n(() => import("./pages/ProvidersPage.js").then((e) => ({ default: e.ProvidersPage }))), y = n(() => import("./pages/ReviewsPage.js").then((e) => ({ default: e.ReviewsPage }))), b = n(() => import("./pages/ServiceDetailsPage.js").then((e) => ({ default: e.ServiceDetailsPage }))), x = n(() => import("./pages/ServicesPage.js").then((e) => ({ default: e.ServicesPage }))), S = n(() => import("./pages/VerificationPage.js").then((e) => ({ default: e.VerificationPage })));
8
- function C() {
7
+ var l = n(() => import("./pages/ClientsPage.js").then((e) => ({ default: e.ClientsPage }))), u = n(() => import("./pages/ClientDetailPage.js").then((e) => ({ default: e.ClientDetailPage }))), d = n(() => import("./pages/EngagementsPage.js").then((e) => ({ default: e.EngagementsPage }))), f = n(() => import("./pages/EngagementDetailPage.js").then((e) => ({ default: e.EngagementDetailPage }))), p = n(() => import("./pages/MattersPage.js").then((e) => ({ default: e.MattersPage }))), m = n(() => import("./pages/TimePage.js").then((e) => ({ default: e.TimePage }))), h = n(() => import("./pages/InvoicesPage.js").then((e) => ({ default: e.InvoicesPage }))), g = n(() => import("./pages/CompliancePage.js").then((e) => ({ default: e.CompliancePage }))), _ = n(() => import("./pages/ConflictsPage.js").then((e) => ({ default: e.ConflictsPage }))), v = n(() => import("./pages/DocumentsPage.js").then((e) => ({ default: e.DocumentsPage }))), y = n(() => import("./pages/PracticeAreasPage.js").then((e) => ({ default: e.PracticeAreasPage }))), b = n(() => import("./pages/AnalyticsPage.js").then((e) => ({ default: e.AnalyticsPage })));
8
+ function x() {
9
9
  return /* @__PURE__ */ s("div", {
10
10
  className: "flex min-h-[320px] items-center justify-center",
11
- children: /* @__PURE__ */ s(r, { className: "h-8 w-8 animate-spin text-primary" })
11
+ children: /* @__PURE__ */ s(r, { className: "h-8 w-8 animate-spin text-accent" })
12
12
  });
13
13
  }
14
- function w() {
14
+ function S() {
15
15
  return /* @__PURE__ */ s(t, {
16
- fallback: /* @__PURE__ */ s(C, {}),
16
+ fallback: /* @__PURE__ */ s(x, {}),
17
17
  children: /* @__PURE__ */ c(o, { children: [
18
18
  /* @__PURE__ */ s(a, {
19
19
  index: !0,
20
20
  element: /* @__PURE__ */ s(e, {})
21
21
  }),
22
22
  /* @__PURE__ */ s(a, {
23
- path: "admin/users",
23
+ path: "clients",
24
24
  element: /* @__PURE__ */ s(l, {})
25
25
  }),
26
26
  /* @__PURE__ */ s(a, {
27
- path: "analytics",
27
+ path: "clients/:id",
28
28
  element: /* @__PURE__ */ s(u, {})
29
29
  }),
30
30
  /* @__PURE__ */ s(a, {
31
- path: "bookings",
31
+ path: "engagements",
32
32
  element: /* @__PURE__ */ s(d, {})
33
33
  }),
34
34
  /* @__PURE__ */ s(a, {
35
- path: "admin/reports",
35
+ path: "engagements/:id",
36
36
  element: /* @__PURE__ */ s(f, {})
37
37
  }),
38
38
  /* @__PURE__ */ s(a, {
39
- path: "documents",
39
+ path: "matters",
40
40
  element: /* @__PURE__ */ s(p, {})
41
41
  }),
42
42
  /* @__PURE__ */ s(a, {
43
- path: "messages",
43
+ path: "time",
44
44
  element: /* @__PURE__ */ s(m, {})
45
45
  }),
46
46
  /* @__PURE__ */ s(a, {
47
- path: "payments",
47
+ path: "invoices",
48
48
  element: /* @__PURE__ */ s(h, {})
49
49
  }),
50
50
  /* @__PURE__ */ s(a, {
51
- path: "projects",
51
+ path: "compliance",
52
52
  element: /* @__PURE__ */ s(g, {})
53
53
  }),
54
54
  /* @__PURE__ */ s(a, {
55
- path: "provider-detail",
55
+ path: "conflicts",
56
56
  element: /* @__PURE__ */ s(_, {})
57
57
  }),
58
58
  /* @__PURE__ */ s(a, {
59
- path: "providers",
59
+ path: "documents",
60
60
  element: /* @__PURE__ */ s(v, {})
61
61
  }),
62
62
  /* @__PURE__ */ s(a, {
63
- path: "reviews",
63
+ path: "practice-areas",
64
64
  element: /* @__PURE__ */ s(y, {})
65
65
  }),
66
66
  /* @__PURE__ */ s(a, {
67
- path: "service-details",
67
+ path: "analytics",
68
68
  element: /* @__PURE__ */ s(b, {})
69
69
  }),
70
- /* @__PURE__ */ s(a, {
71
- path: "services",
72
- element: /* @__PURE__ */ s(x, {})
73
- }),
74
- /* @__PURE__ */ s(a, {
75
- path: "verification",
76
- element: /* @__PURE__ */ s(S, {})
77
- }),
78
70
  /* @__PURE__ */ s(a, {
79
71
  path: "*",
80
72
  element: /* @__PURE__ */ s(i, {
@@ -86,6 +78,6 @@ function w() {
86
78
  });
87
79
  }
88
80
  //#endregion
89
- export { w as ProServiceWorldRoutes };
81
+ export { S as ProServiceWorldRoutes };
90
82
 
91
83
  //# sourceMappingURL=ProServiceWorldRoutes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ProServiceWorldRoutes.js","names":[],"sources":["../../src/proserviceworld/ProServiceWorldRoutes.tsx"],"sourcesContent":["import { lazy, Suspense } from 'react';\nimport { Navigate, Route, Routes } from 'react-router-dom';\nimport { Loader2 } from 'lucide-react';\nimport { DashboardPage as IndexPage } from './pages/DashboardPage';\n\nconst AdminUsersPage = lazy(() =>\n import('./pages/AdminUsersPage').then((m) => ({ default: m.AdminUsersPage }))\n);\nconst AnalyticsPage = lazy(() =>\n import('./pages/AnalyticsPage').then((m) => ({ default: m.AnalyticsPage }))\n);\nconst BookingsPage = lazy(() =>\n import('./pages/BookingsPage').then((m) => ({ default: m.BookingsPage }))\n);\nconst AdminReportsPage = lazy(() =>\n import('./pages/AdminReportsPage').then((m) => ({ default: m.AdminReportsPage }))\n);\nconst DocumentsPage = lazy(() =>\n import('./pages/DocumentsPage').then((m) => ({ default: m.DocumentsPage }))\n);\nconst MessagesPage = lazy(() =>\n import('./pages/MessagesPage').then((m) => ({ default: m.MessagesPage }))\n);\nconst PaymentsPage = lazy(() =>\n import('./pages/PaymentsPage').then((m) => ({ default: m.PaymentsPage }))\n);\nconst ProjectsPage = lazy(() =>\n import('./pages/ProjectsPage').then((m) => ({ default: m.ProjectsPage }))\n);\nconst ProviderDetailPage = lazy(() =>\n import('./pages/ProviderDetailPage').then((m) => ({ default: m.ProviderDetailPage }))\n);\nconst ProvidersPage = lazy(() =>\n import('./pages/ProvidersPage').then((m) => ({ default: m.ProvidersPage }))\n);\nconst ReviewsPage = lazy(() =>\n import('./pages/ReviewsPage').then((m) => ({ default: m.ReviewsPage }))\n);\nconst ServiceDetailsPage = lazy(() =>\n import('./pages/ServiceDetailsPage').then((m) => ({ default: m.ServiceDetailsPage }))\n);\nconst ServicesPage = lazy(() =>\n import('./pages/ServicesPage').then((m) => ({ default: m.ServicesPage }))\n);\nconst VerificationPage = lazy(() =>\n import('./pages/VerificationPage').then((m) => ({ default: m.VerificationPage }))\n);\n\nfunction PageLoader() {\n return (\n <div className=\"flex min-h-[320px] items-center justify-center\">\n <Loader2 className=\"h-8 w-8 animate-spin text-primary\" />\n </div>\n );\n}\n\nexport function ProServiceWorldRoutes() {\n return (\n <Suspense fallback={<PageLoader />}>\n <Routes>\n <Route index element={<IndexPage />} />\n <Route path=\"admin/users\" element={<AdminUsersPage />} />\n <Route path=\"analytics\" element={<AnalyticsPage />} />\n <Route path=\"bookings\" element={<BookingsPage />} />\n <Route path=\"admin/reports\" element={<AdminReportsPage />} />\n <Route path=\"documents\" element={<DocumentsPage />} />\n <Route path=\"messages\" element={<MessagesPage />} />\n <Route path=\"payments\" element={<PaymentsPage />} />\n <Route path=\"projects\" element={<ProjectsPage />} />\n <Route path=\"provider-detail\" element={<ProviderDetailPage />} />\n <Route path=\"providers\" element={<ProvidersPage />} />\n <Route path=\"reviews\" element={<ReviewsPage />} />\n <Route path=\"service-details\" element={<ServiceDetailsPage />} />\n <Route path=\"services\" element={<ServicesPage />} />\n <Route path=\"verification\" element={<VerificationPage />} />\n <Route path=\"*\" element={<Navigate to=\"\" replace />} />\n </Routes>\n </Suspense>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ProServiceWorldRoutes.js","names":[],"sources":["../../src/proserviceworld/ProServiceWorldRoutes.tsx"],"sourcesContent":["import { lazy, Suspense } from 'react';\nimport { Navigate, Route, Routes } from 'react-router-dom';\nimport { Loader2 } from 'lucide-react';\nimport { DashboardPage } from './pages/DashboardPage';\n\nconst ClientsPage = lazy(() =>\n import('./pages/ClientsPage').then((m) => ({ default: m.ClientsPage }))\n);\nconst ClientDetailPage = lazy(() =>\n import('./pages/ClientDetailPage').then((m) => ({ default: m.ClientDetailPage }))\n);\nconst EngagementsPage = lazy(() =>\n import('./pages/EngagementsPage').then((m) => ({ default: m.EngagementsPage }))\n);\nconst EngagementDetailPage = lazy(() =>\n import('./pages/EngagementDetailPage').then((m) => ({ default: m.EngagementDetailPage }))\n);\nconst MattersPage = lazy(() =>\n import('./pages/MattersPage').then((m) => ({ default: m.MattersPage }))\n);\nconst TimePage = lazy(() => import('./pages/TimePage').then((m) => ({ default: m.TimePage })));\nconst InvoicesPage = lazy(() =>\n import('./pages/InvoicesPage').then((m) => ({ default: m.InvoicesPage }))\n);\nconst CompliancePage = lazy(() =>\n import('./pages/CompliancePage').then((m) => ({ default: m.CompliancePage }))\n);\nconst ConflictsPage = lazy(() =>\n import('./pages/ConflictsPage').then((m) => ({ default: m.ConflictsPage }))\n);\nconst DocumentsPage = lazy(() =>\n import('./pages/DocumentsPage').then((m) => ({ default: m.DocumentsPage }))\n);\nconst PracticeAreasPage = lazy(() =>\n import('./pages/PracticeAreasPage').then((m) => ({ default: m.PracticeAreasPage }))\n);\nconst AnalyticsPage = lazy(() =>\n import('./pages/AnalyticsPage').then((m) => ({ default: m.AnalyticsPage }))\n);\n\nfunction PageLoader() {\n return (\n <div className=\"flex min-h-[320px] items-center justify-center\">\n <Loader2 className=\"h-8 w-8 animate-spin text-accent\" />\n </div>\n );\n}\n\nexport function ProServiceWorldRoutes() {\n return (\n <Suspense fallback={<PageLoader />}>\n <Routes>\n <Route index element={<DashboardPage />} />\n <Route path=\"clients\" element={<ClientsPage />} />\n <Route path=\"clients/:id\" element={<ClientDetailPage />} />\n <Route path=\"engagements\" element={<EngagementsPage />} />\n <Route path=\"engagements/:id\" element={<EngagementDetailPage />} />\n <Route path=\"matters\" element={<MattersPage />} />\n <Route path=\"time\" element={<TimePage />} />\n <Route path=\"invoices\" element={<InvoicesPage />} />\n <Route path=\"compliance\" element={<CompliancePage />} />\n <Route path=\"conflicts\" element={<ConflictsPage />} />\n <Route path=\"documents\" element={<DocumentsPage />} />\n <Route path=\"practice-areas\" element={<PracticeAreasPage />} />\n <Route path=\"analytics\" element={<AnalyticsPage />} />\n <Route path=\"*\" element={<Navigate to=\"\" replace />} />\n </Routes>\n </Suspense>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ import { useProServiceWorld as e } from "../providers/ProServiceWorldProvider.js";
2
+ import { Banner as t, Empty as n, LoadingBlock as r, SectionCard as i, TextArea as a, fmtDate as o } from "./ui.js";
3
+ import { useAddEntityComment as s, useEntityComments as c } from "../hooks/useEntityComments.js";
4
+ import { useState as l } from "react";
5
+ import { MessageSquare as u, Send as d } from "lucide-react";
6
+ import { jsx as f, jsxs as p } from "react/jsx-runtime";
7
+ import { Button as m } from "@burdenoff/fe-libs/ui";
8
+ //#region src/proserviceworld/components/DiscussionThread.tsx
9
+ var h = ({ entityType: h, entityId: g, title: _ = "Discussion" }) => {
10
+ let { currentUser: v } = e(), { data: y, isLoading: b, error: x } = c(h, g), S = s(h, g), [C, w] = l(""), [T, E] = l(null), D = () => {
11
+ E(null);
12
+ let e = C.trim();
13
+ e && S.mutate(e, {
14
+ onSuccess: () => w(""),
15
+ onError: (e) => E(e instanceof Error ? e.message : "Failed to post.")
16
+ });
17
+ }, O = (e) => v && e === v.id ? "You" : "Team member";
18
+ return /* @__PURE__ */ f(i, {
19
+ title: _,
20
+ description: "Notes & discussion — shared across the platform via Conversations.",
21
+ children: /* @__PURE__ */ p("div", {
22
+ className: "space-y-3",
23
+ children: [
24
+ T && /* @__PURE__ */ f(t, {
25
+ tone: "danger",
26
+ onClose: () => E(null),
27
+ children: T
28
+ }),
29
+ /* @__PURE__ */ p("div", {
30
+ className: "flex items-start gap-2",
31
+ children: [/* @__PURE__ */ f(a, {
32
+ value: C,
33
+ onChange: (e) => w(e.target.value),
34
+ placeholder: "Add a note…",
35
+ className: "min-h-[44px] flex-1",
36
+ onKeyDown: (e) => {
37
+ (e.metaKey || e.ctrlKey) && e.key === "Enter" && D();
38
+ }
39
+ }), /* @__PURE__ */ f(m, {
40
+ onClick: D,
41
+ disabled: S.isPending || !C.trim(),
42
+ "aria-label": "Post note",
43
+ children: /* @__PURE__ */ f(d, { className: "h-4 w-4" })
44
+ })]
45
+ }),
46
+ b ? /* @__PURE__ */ f(r, { label: "Loading discussion…" }) : x ? /* @__PURE__ */ f("p", {
47
+ className: "text-sm text-status-error-text",
48
+ children: "Couldn't load discussion."
49
+ }) : !y || y.items.length === 0 ? /* @__PURE__ */ f(n, {
50
+ title: "No notes yet",
51
+ description: "Start the discussion for this record.",
52
+ icon: /* @__PURE__ */ f(u, { className: "h-7 w-7" })
53
+ }) : /* @__PURE__ */ f("ul", {
54
+ className: "space-y-2.5",
55
+ children: y.items.map((e) => /* @__PURE__ */ p("li", {
56
+ className: "rounded-lg border border-border-seam bg-bg-canvas p-3",
57
+ children: [/* @__PURE__ */ p("div", {
58
+ className: "mb-1 flex items-center justify-between text-xs text-text-tertiary",
59
+ children: [/* @__PURE__ */ f("span", {
60
+ className: "font-medium text-text-secondary",
61
+ children: O(e.authorId)
62
+ }), /* @__PURE__ */ f("span", { children: o(e.createdAt) })]
63
+ }), /* @__PURE__ */ f("p", {
64
+ className: "whitespace-pre-wrap text-sm text-text-primary",
65
+ children: e.content?.text ?? ""
66
+ })]
67
+ }, e.id))
68
+ })
69
+ ]
70
+ })
71
+ });
72
+ };
73
+ //#endregion
74
+ export { h as DiscussionThread };
75
+
76
+ //# sourceMappingURL=DiscussionThread.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DiscussionThread.js","names":[],"sources":["../../../src/proserviceworld/components/DiscussionThread.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useState } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { MessageSquare, Send } from 'lucide-react';\nimport { useEntityComments, useAddEntityComment } from '../hooks/useEntityComments';\nimport { useProServiceWorld } from '../providers/ProServiceWorldProvider';\nimport { SectionCard, TextArea, Banner, LoadingBlock, Empty, fmtDate } from './ui';\n\n/**\n * Discussion / notes for a Psw entity, backed entirely by wspace-conversations\n * (createEntityComment / getEntityComments) — no product-owned comments table.\n */\nexport const DiscussionThread: FC<{ entityType: string; entityId: string; title?: string }> = ({\n entityType,\n entityId,\n title = 'Discussion',\n}) => {\n const { currentUser } = useProServiceWorld();\n const { data, isLoading, error } = useEntityComments(entityType, entityId);\n const add = useAddEntityComment(entityType, entityId);\n const [text, setText] = useState('');\n const [err, setErr] = useState<string | null>(null);\n\n const submit = () => {\n setErr(null);\n const body = text.trim();\n if (!body) return;\n add.mutate(body, { onSuccess: () => setText(''), onError: (e) => setErr(e instanceof Error ? e.message : 'Failed to post.') });\n };\n\n const authorLabel = (authorId: string) =>\n currentUser && authorId === currentUser.id ? 'You' : 'Team member';\n\n return (\n <SectionCard title={title} description=\"Notes & discussion — shared across the platform via Conversations.\">\n <div className=\"space-y-3\">\n {err && <Banner tone=\"danger\" onClose={() => setErr(null)}>{err}</Banner>}\n <div className=\"flex items-start gap-2\">\n <TextArea\n value={text}\n onChange={(e) => setText(e.target.value)}\n placeholder=\"Add a note…\"\n className=\"min-h-[44px] flex-1\"\n onKeyDown={(e) => {\n if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') submit();\n }}\n />\n <Button onClick={submit} disabled={add.isPending || !text.trim()} aria-label=\"Post note\">\n <Send className=\"h-4 w-4\" />\n </Button>\n </div>\n\n {isLoading ? (\n <LoadingBlock label=\"Loading discussion…\" />\n ) : error ? (\n <p className=\"text-sm text-status-error-text\">Couldn't load discussion.</p>\n ) : !data || data.items.length === 0 ? (\n <Empty title=\"No notes yet\" description=\"Start the discussion for this record.\" icon={<MessageSquare className=\"h-7 w-7\" />} />\n ) : (\n <ul className=\"space-y-2.5\">\n {data.items.map((c) => (\n <li key={c.id} className=\"rounded-lg border border-border-seam bg-bg-canvas p-3\">\n <div className=\"mb-1 flex items-center justify-between text-xs text-text-tertiary\">\n <span className=\"font-medium text-text-secondary\">{authorLabel(c.authorId)}</span>\n <span>{fmtDate(c.createdAt)}</span>\n </div>\n <p className=\"whitespace-pre-wrap text-sm text-text-primary\">{c.content?.text ?? ''}</p>\n </li>\n ))}\n </ul>\n )}\n </div>\n </SectionCard>\n );\n};\n"],"mappings":";;;;;;;;AAYA,IAAa,KAAkF,EAC7F,eACA,aACA,WAAQ,mBACJ;CACJ,IAAM,EAAE,mBAAgB,GAAoB,EACtC,EAAE,SAAM,cAAW,aAAU,EAAkB,GAAY,EAAS,EACpE,IAAM,EAAoB,GAAY,EAAS,EAC/C,CAAC,GAAM,KAAW,EAAS,GAAG,EAC9B,CAAC,GAAK,KAAU,EAAwB,KAAK,EAE7C,UAAe;AACnB,IAAO,KAAK;EACZ,IAAM,IAAO,EAAK,MAAM;AACnB,OACL,EAAI,OAAO,GAAM;GAAE,iBAAiB,EAAQ,GAAG;GAAE,UAAU,MAAM,EAAO,aAAa,QAAQ,EAAE,UAAU,kBAAkB;GAAE,CAAC;IAG1H,KAAe,MACnB,KAAe,MAAa,EAAY,KAAK,QAAQ;AAEvD,QACE,kBAAC,GAAD;EAAoB;EAAO,aAAY;YACrC,kBAAC,OAAD;GAAK,WAAU;aAAf;IACG,KAAO,kBAAC,GAAD;KAAQ,MAAK;KAAS,eAAe,EAAO,KAAK;eAAG;KAAa,CAAA;IACzE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MACE,OAAO;MACP,WAAW,MAAM,EAAQ,EAAE,OAAO,MAAM;MACxC,aAAY;MACZ,WAAU;MACV,YAAY,MAAM;AAChB,QAAK,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,WAAS,GAAQ;;MAE7D,CAAA,EACF,kBAAC,GAAD;MAAQ,SAAS;MAAQ,UAAU,EAAI,aAAa,CAAC,EAAK,MAAM;MAAE,cAAW;gBAC3E,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA;MACrB,CAAA,CACL;;IAEL,IACC,kBAAC,GAAD,EAAc,OAAM,uBAAwB,CAAA,GAC1C,IACF,kBAAC,KAAD;KAAG,WAAU;eAAiC;KAA6B,CAAA,GACzE,CAAC,KAAQ,EAAK,MAAM,WAAW,IACjC,kBAAC,GAAD;KAAO,OAAM;KAAe,aAAY;KAAwC,MAAM,kBAAC,GAAD,EAAe,WAAU,WAAY,CAAA;KAAI,CAAA,GAE/H,kBAAC,MAAD;KAAI,WAAU;eACX,EAAK,MAAM,KAAK,MACf,kBAAC,MAAD;MAAe,WAAU;gBAAzB,CACE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,QAAD;QAAM,WAAU;kBAAmC,EAAY,EAAE,SAAS;QAAQ,CAAA,EAClF,kBAAC,QAAD,EAAA,UAAO,EAAQ,EAAE,UAAU,EAAQ,CAAA,CAC/B;UACN,kBAAC,KAAD;OAAG,WAAU;iBAAiD,EAAE,SAAS,QAAQ;OAAO,CAAA,CACrF;QANI,EAAE,GAMN,CACL;KACC,CAAA;IAEH;;EACM,CAAA"}
@@ -0,0 +1,273 @@
1
+ import { cn as e } from "../utils/cn.js";
2
+ import { useEffect as t } from "react";
3
+ import { AlertCircle as n, CheckCircle2 as r, Info as i, Loader2 as a, X as o } from "lucide-react";
4
+ import { jsx as s, jsxs as c } from "react/jsx-runtime";
5
+ import { Button as l } from "@burdenoff/fe-libs/ui";
6
+ //#region src/proserviceworld/components/ui.tsx
7
+ var u = (e) => (e ?? "").toLowerCase().replace(/_/g, " ").replace(/\b\w/g, (e) => e.toUpperCase()), d = (e) => {
8
+ if (!e) return "—";
9
+ let t = new Date(e);
10
+ return Number.isNaN(t.getTime()) ? "—" : t.toLocaleDateString(void 0, {
11
+ year: "numeric",
12
+ month: "short",
13
+ day: "numeric"
14
+ });
15
+ }, f = (e, t = "USD") => {
16
+ let n = e ?? 0;
17
+ try {
18
+ return new Intl.NumberFormat(void 0, {
19
+ style: "currency",
20
+ currency: t,
21
+ maximumFractionDigits: 0
22
+ }).format(n);
23
+ } catch {
24
+ return `${t} ${n.toLocaleString()}`;
25
+ }
26
+ }, p = (e) => `${(e ?? 0).toLocaleString(void 0, { maximumFractionDigits: 1 })}h`, m = (e) => p((e ?? 0) / 60), h = {
27
+ neutral: "bg-bg-sunken text-text-secondary",
28
+ success: "bg-status-success-bg-subtle text-status-success-text",
29
+ warning: "bg-status-warning-bg-subtle text-status-warning-text",
30
+ danger: "bg-status-error-bg-subtle text-status-error-text",
31
+ info: "bg-bg-sunken text-text-link",
32
+ accent: "bg-bg-sunken text-accent"
33
+ }, g = {
34
+ ACTIVE: "success",
35
+ PROSPECT: "info",
36
+ INACTIVE: "neutral",
37
+ ARCHIVED: "neutral",
38
+ PROPOSAL: "info",
39
+ ACCEPTED: "accent",
40
+ IN_PROGRESS: "accent",
41
+ REVIEW: "warning",
42
+ DELIVERED: "success",
43
+ INVOICED: "success",
44
+ CLOSED: "neutral",
45
+ CANCELLED: "danger",
46
+ OPEN: "accent",
47
+ ON_HOLD: "warning",
48
+ LOW: "neutral",
49
+ MEDIUM: "info",
50
+ HIGH: "warning",
51
+ CRITICAL: "danger",
52
+ DRAFT: "neutral",
53
+ INTERNAL_REVIEW: "info",
54
+ CLIENT_REVIEW: "warning",
55
+ REJECTED: "danger",
56
+ FINAL: "success",
57
+ SUBMITTED: "info",
58
+ APPROVED: "success",
59
+ BILLED: "accent",
60
+ SENT: "info",
61
+ PAID: "success",
62
+ OVERDUE: "danger",
63
+ PENDING: "warning",
64
+ IN_REVIEW: "info",
65
+ PASSED: "success",
66
+ FAILED: "danger",
67
+ WAIVED: "neutral",
68
+ CLEAR: "success",
69
+ POTENTIAL_CONFLICT: "warning",
70
+ CONFLICT: "danger",
71
+ COMPLETED: "success"
72
+ }, _ = ({ status: t, className: n }) => /* @__PURE__ */ s("span", {
73
+ className: e("inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium whitespace-nowrap", h[g[t] ?? "neutral"], n),
74
+ children: u(t)
75
+ }), v = ({ title: e, subtitle: t, actions: n, icon: r }) => /* @__PURE__ */ c("div", {
76
+ className: "flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between",
77
+ children: [/* @__PURE__ */ c("div", {
78
+ className: "flex items-start gap-3",
79
+ children: [r ? /* @__PURE__ */ s("div", {
80
+ className: "mt-0.5 text-accent",
81
+ children: r
82
+ }) : null, /* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("h1", {
83
+ className: "text-xl font-semibold text-text-primary sm:text-2xl",
84
+ children: e
85
+ }), t ? /* @__PURE__ */ s("p", {
86
+ className: "mt-1 max-w-2xl text-sm text-text-secondary",
87
+ children: t
88
+ }) : null] })]
89
+ }), n ? /* @__PURE__ */ s("div", {
90
+ className: "flex flex-wrap items-center gap-2",
91
+ children: n
92
+ }) : null]
93
+ }), y = ({ label: t, value: n, hint: r, icon: i, tone: a = "neutral" }) => /* @__PURE__ */ c("div", {
94
+ className: "rounded-xl border border-border-seam bg-bg-surface p-4",
95
+ children: [
96
+ /* @__PURE__ */ c("div", {
97
+ className: "flex items-center justify-between",
98
+ children: [/* @__PURE__ */ s("span", {
99
+ className: "text-xs font-medium uppercase tracking-wide text-text-tertiary",
100
+ children: t
101
+ }), i ? /* @__PURE__ */ s("span", {
102
+ className: e("rounded-lg p-1.5", h[a]),
103
+ children: i
104
+ }) : null]
105
+ }),
106
+ /* @__PURE__ */ s("div", {
107
+ className: "mt-2 text-2xl font-semibold text-text-primary",
108
+ children: n
109
+ }),
110
+ r ? /* @__PURE__ */ s("div", {
111
+ className: "mt-1 text-xs text-text-tertiary",
112
+ children: r
113
+ }) : null
114
+ ]
115
+ }), b = ({ title: t, description: n, action: r, children: i, className: a }) => /* @__PURE__ */ c("section", {
116
+ className: e("rounded-xl border border-border-seam bg-bg-surface", a),
117
+ children: [(t || r) && /* @__PURE__ */ c("header", {
118
+ className: "flex items-center justify-between gap-3 border-b border-border-seam px-4 py-3",
119
+ children: [/* @__PURE__ */ c("div", { children: [t ? /* @__PURE__ */ s("h2", {
120
+ className: "text-sm font-semibold text-text-primary",
121
+ children: t
122
+ }) : null, n ? /* @__PURE__ */ s("p", {
123
+ className: "text-xs text-text-tertiary",
124
+ children: n
125
+ }) : null] }), r]
126
+ }), /* @__PURE__ */ s("div", {
127
+ className: "p-4",
128
+ children: i
129
+ })]
130
+ }), x = "w-full rounded-lg border border-border-seam bg-bg-canvas px-3 py-2 text-sm text-text-primary placeholder:text-text-tertiary focus:border-accent focus:outline-none focus:ring-2 focus:ring-accent/30 disabled:opacity-50", S = ({ label: t, required: n, hint: r, children: i, className: a }) => /* @__PURE__ */ c("label", {
131
+ className: e("block", a),
132
+ children: [
133
+ /* @__PURE__ */ c("span", {
134
+ className: "mb-1 block text-xs font-medium text-text-secondary",
135
+ children: [t, n ? /* @__PURE__ */ s("span", {
136
+ className: "text-status-error-text",
137
+ children: " *"
138
+ }) : null]
139
+ }),
140
+ i,
141
+ r ? /* @__PURE__ */ s("span", {
142
+ className: "mt-1 block text-xs text-text-tertiary",
143
+ children: r
144
+ }) : null
145
+ ]
146
+ }), C = ({ className: t, ...n }) => /* @__PURE__ */ s("input", {
147
+ className: e(x, t),
148
+ ...n
149
+ }), w = ({ className: t, ...n }) => /* @__PURE__ */ s("textarea", {
150
+ className: e(x, "min-h-[80px] resize-y", t),
151
+ ...n
152
+ }), T = ({ className: t, children: n, ...r }) => /* @__PURE__ */ s("select", {
153
+ className: e(x, "appearance-none pr-8"),
154
+ ...r,
155
+ children: n
156
+ }), E = (e) => e.map((e) => /* @__PURE__ */ s("option", {
157
+ value: e,
158
+ children: u(e)
159
+ }, e)), D = ({ tone: t = "info", children: a, onClose: l }) => {
160
+ let u = t === "success" ? r : t === "danger" ? n : i;
161
+ return /* @__PURE__ */ c("div", {
162
+ className: e("flex items-start gap-2 rounded-lg px-3 py-2 text-sm", t === "success" ? h.success : t === "danger" ? h.danger : "bg-bg-sunken text-text-secondary"),
163
+ children: [
164
+ /* @__PURE__ */ s(u, { className: "mt-0.5 h-4 w-4 shrink-0" }),
165
+ /* @__PURE__ */ s("div", {
166
+ className: "flex-1",
167
+ children: a
168
+ }),
169
+ l ? /* @__PURE__ */ s("button", {
170
+ type: "button",
171
+ onClick: l,
172
+ className: "opacity-70 hover:opacity-100",
173
+ "aria-label": "Dismiss",
174
+ children: /* @__PURE__ */ s(o, { className: "h-4 w-4" })
175
+ }) : null
176
+ ]
177
+ });
178
+ }, O = ({ open: n, onClose: r, title: i, children: a, footer: l, wide: u }) => (t(() => {
179
+ if (!n) return;
180
+ let e = (e) => {
181
+ e.key === "Escape" && r();
182
+ };
183
+ return document.addEventListener("keydown", e), document.body.style.overflow = "hidden", () => {
184
+ document.removeEventListener("keydown", e), document.body.style.overflow = "";
185
+ };
186
+ }, [n, r]), n ? /* @__PURE__ */ c("div", {
187
+ className: "fixed inset-0 z-50 flex items-end justify-center sm:items-center",
188
+ role: "dialog",
189
+ "aria-modal": "true",
190
+ "aria-label": i,
191
+ children: [/* @__PURE__ */ s("div", {
192
+ className: "absolute inset-0 bg-black/50 backdrop-blur-sm",
193
+ onClick: r
194
+ }), /* @__PURE__ */ c("div", {
195
+ className: e("relative flex max-h-[92vh] w-full flex-col overflow-hidden rounded-t-2xl border border-border-seam bg-bg-surface shadow-xl sm:max-h-[88vh] sm:rounded-2xl", u ? "sm:max-w-3xl" : "sm:max-w-lg"),
196
+ children: [
197
+ /* @__PURE__ */ c("header", {
198
+ className: "flex items-center justify-between border-b border-border-seam px-4 py-3",
199
+ children: [/* @__PURE__ */ s("h2", {
200
+ className: "text-base font-semibold text-text-primary",
201
+ children: i
202
+ }), /* @__PURE__ */ s("button", {
203
+ type: "button",
204
+ onClick: r,
205
+ className: "rounded-lg p-1 text-text-tertiary hover:bg-bg-sunken hover:text-text-primary",
206
+ "aria-label": "Close",
207
+ children: /* @__PURE__ */ s(o, { className: "h-5 w-5" })
208
+ })]
209
+ }),
210
+ /* @__PURE__ */ s("div", {
211
+ className: "flex-1 overflow-y-auto px-4 py-4",
212
+ children: a
213
+ }),
214
+ l ? /* @__PURE__ */ s("footer", {
215
+ className: "flex items-center justify-end gap-2 border-t border-border-seam px-4 py-3",
216
+ children: l
217
+ }) : null
218
+ ]
219
+ })]
220
+ }) : null), k = ({ label: e = "Loading…" }) => /* @__PURE__ */ c("div", {
221
+ className: "flex min-h-[220px] flex-col items-center justify-center gap-3 text-text-tertiary",
222
+ children: [/* @__PURE__ */ s(a, { className: "h-7 w-7 animate-spin text-accent" }), /* @__PURE__ */ s("span", {
223
+ className: "text-sm",
224
+ children: e
225
+ })]
226
+ }), A = ({ error: e, onRetry: t }) => /* @__PURE__ */ c("div", {
227
+ className: "flex min-h-[220px] flex-col items-center justify-center gap-3 text-center",
228
+ children: [
229
+ /* @__PURE__ */ s(n, { className: "h-8 w-8 text-status-error-text" }),
230
+ /* @__PURE__ */ s("p", {
231
+ className: "max-w-md text-sm text-text-secondary",
232
+ children: e instanceof Error ? e.message : "Something went wrong."
233
+ }),
234
+ t ? /* @__PURE__ */ s(l, {
235
+ variant: "outline",
236
+ size: "sm",
237
+ onClick: t,
238
+ children: "Try again"
239
+ }) : null
240
+ ]
241
+ }), j = ({ title: e, description: t, icon: n, action: r }) => /* @__PURE__ */ c("div", {
242
+ className: "flex min-h-[220px] flex-col items-center justify-center gap-3 rounded-xl border border-dashed border-border-seam bg-bg-surface/50 px-6 py-10 text-center",
243
+ children: [
244
+ n ? /* @__PURE__ */ s("div", {
245
+ className: "text-text-tertiary",
246
+ children: n
247
+ }) : null,
248
+ /* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("p", {
249
+ className: "text-sm font-medium text-text-primary",
250
+ children: e
251
+ }), t ? /* @__PURE__ */ s("p", {
252
+ className: "mt-1 max-w-sm text-sm text-text-tertiary",
253
+ children: t
254
+ }) : null] }),
255
+ r
256
+ ]
257
+ }), M = ({ children: e }) => /* @__PURE__ */ s("div", {
258
+ className: "overflow-x-auto rounded-xl border border-border-seam",
259
+ children: /* @__PURE__ */ s("table", {
260
+ className: "w-full min-w-[560px] text-left text-sm",
261
+ children: e
262
+ })
263
+ }), N = ({ children: t, className: n }) => /* @__PURE__ */ s("th", {
264
+ className: e("bg-bg-sunken px-4 py-2.5 text-xs font-semibold uppercase tracking-wide text-text-tertiary", n),
265
+ children: t
266
+ }), P = ({ children: t, className: n }) => /* @__PURE__ */ s("td", {
267
+ className: e("border-t border-border-seam px-4 py-3 text-text-secondary", n),
268
+ children: t
269
+ });
270
+ //#endregion
271
+ export { D as Banner, j as Empty, A as ErrorState, S as Field, k as LoadingBlock, y as MetricCard, O as Modal, T as NativeSelect, v as PageHeader, b as SectionCard, _ as StatusPill, M as TableWrap, P as Td, w as TextArea, C as TextInput, N as Th, E as enumOptions, d as fmtDate, p as fmtHours, m as fmtMinutesAsHours, f as fmtMoney, u as humanize };
272
+
273
+ //# sourceMappingURL=ui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ui.js","names":[],"sources":["../../../src/proserviceworld/components/ui.tsx"],"sourcesContent":["/**\n * ProServiceWorld shared UI kit.\n *\n * Self-contained, token-driven primitives (no raw colors) shared by every page:\n * page header, metric cards, section cards, a mobile-friendly modal, token-styled\n * native form controls, status pills, inline banners, and empty/loading/error\n * states. Actions reuse the fe-libs Button (brand variants); everything else is\n * built from semantic tokens so theming works across light/dark/any theme.\n */\n\nimport type { FC, ReactNode } from 'react';\nimport { useEffect } from 'react';\nimport { Button } from '@burdenoff/fe-libs/ui';\nimport { AlertCircle, CheckCircle2, Info, Loader2, X } from 'lucide-react';\nimport { cn } from '../utils/cn';\n\n// ---------------------------------------------------------------------------\n// Formatters\n// ---------------------------------------------------------------------------\nexport const humanize = (v: string | null | undefined): string =>\n (v ?? '')\n .toLowerCase()\n .replace(/_/g, ' ')\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n\nexport const fmtDate = (iso: string | null | undefined): string => {\n if (!iso) return '—';\n const d = new Date(iso);\n return Number.isNaN(d.getTime())\n ? '—'\n : d.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });\n};\n\nexport const fmtMoney = (amount: number | null | undefined, currency = 'USD'): string => {\n const n = amount ?? 0;\n try {\n return new Intl.NumberFormat(undefined, {\n style: 'currency',\n currency,\n maximumFractionDigits: 0,\n }).format(n);\n } catch {\n return `${currency} ${n.toLocaleString()}`;\n }\n};\n\nexport const fmtHours = (h: number | null | undefined): string =>\n `${(h ?? 0).toLocaleString(undefined, { maximumFractionDigits: 1 })}h`;\nexport const fmtMinutesAsHours = (m: number | null | undefined): string => fmtHours((m ?? 0) / 60);\n\n// ---------------------------------------------------------------------------\n// Status tone mapping\n// ---------------------------------------------------------------------------\nexport type Tone = 'neutral' | 'success' | 'warning' | 'danger' | 'info' | 'accent';\n\nconst TONE_CLASS: Record<Tone, string> = {\n neutral: 'bg-bg-sunken text-text-secondary',\n success: 'bg-status-success-bg-subtle text-status-success-text',\n warning: 'bg-status-warning-bg-subtle text-status-warning-text',\n danger: 'bg-status-error-bg-subtle text-status-error-text',\n info: 'bg-bg-sunken text-text-link',\n accent: 'bg-bg-sunken text-accent',\n};\n\nconst STATUS_TONE: Record<string, Tone> = {\n // clients / generic\n ACTIVE: 'success',\n PROSPECT: 'info',\n INACTIVE: 'neutral',\n ARCHIVED: 'neutral',\n // engagements\n PROPOSAL: 'info',\n ACCEPTED: 'accent',\n IN_PROGRESS: 'accent',\n REVIEW: 'warning',\n DELIVERED: 'success',\n INVOICED: 'success',\n CLOSED: 'neutral',\n CANCELLED: 'danger',\n // matters\n OPEN: 'accent',\n ON_HOLD: 'warning',\n // priority\n LOW: 'neutral',\n MEDIUM: 'info',\n HIGH: 'warning',\n CRITICAL: 'danger',\n // deliverable / doc\n DRAFT: 'neutral',\n INTERNAL_REVIEW: 'info',\n CLIENT_REVIEW: 'warning',\n REJECTED: 'danger',\n FINAL: 'success',\n // time\n SUBMITTED: 'info',\n APPROVED: 'success',\n BILLED: 'accent',\n // invoice\n SENT: 'info',\n PAID: 'success',\n OVERDUE: 'danger',\n // compliance / conflict\n PENDING: 'warning',\n IN_REVIEW: 'info',\n PASSED: 'success',\n FAILED: 'danger',\n WAIVED: 'neutral',\n CLEAR: 'success',\n POTENTIAL_CONFLICT: 'warning',\n CONFLICT: 'danger',\n // milestone\n COMPLETED: 'success',\n};\n\nexport const StatusPill: FC<{ status: string; className?: string }> = ({ status, className }) => (\n <span\n className={cn(\n 'inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium whitespace-nowrap',\n TONE_CLASS[STATUS_TONE[status] ?? 'neutral'],\n className\n )}\n >\n {humanize(status)}\n </span>\n);\n\n// ---------------------------------------------------------------------------\n// Page header\n// ---------------------------------------------------------------------------\nexport const PageHeader: FC<{\n title: string;\n subtitle?: string;\n actions?: ReactNode;\n icon?: ReactNode;\n}> = ({ title, subtitle, actions, icon }) => (\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between\">\n <div className=\"flex items-start gap-3\">\n {icon ? <div className=\"mt-0.5 text-accent\">{icon}</div> : null}\n <div>\n <h1 className=\"text-xl font-semibold text-text-primary sm:text-2xl\">{title}</h1>\n {subtitle ? <p className=\"mt-1 max-w-2xl text-sm text-text-secondary\">{subtitle}</p> : null}\n </div>\n </div>\n {actions ? <div className=\"flex flex-wrap items-center gap-2\">{actions}</div> : null}\n </div>\n);\n\n// ---------------------------------------------------------------------------\n// Metric card\n// ---------------------------------------------------------------------------\nexport const MetricCard: FC<{\n label: string;\n value: ReactNode;\n hint?: string;\n icon?: ReactNode;\n tone?: Tone;\n}> = ({ label, value, hint, icon, tone = 'neutral' }) => (\n <div className=\"rounded-xl border border-border-seam bg-bg-surface p-4\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs font-medium uppercase tracking-wide text-text-tertiary\">\n {label}\n </span>\n {icon ? <span className={cn('rounded-lg p-1.5', TONE_CLASS[tone])}>{icon}</span> : null}\n </div>\n <div className=\"mt-2 text-2xl font-semibold text-text-primary\">{value}</div>\n {hint ? <div className=\"mt-1 text-xs text-text-tertiary\">{hint}</div> : null}\n </div>\n);\n\n// ---------------------------------------------------------------------------\n// Section card\n// ---------------------------------------------------------------------------\nexport const SectionCard: FC<{\n title?: string;\n description?: string;\n action?: ReactNode;\n children: ReactNode;\n className?: string;\n}> = ({ title, description, action, children, className }) => (\n <section className={cn('rounded-xl border border-border-seam bg-bg-surface', className)}>\n {(title || action) && (\n <header className=\"flex items-center justify-between gap-3 border-b border-border-seam px-4 py-3\">\n <div>\n {title ? <h2 className=\"text-sm font-semibold text-text-primary\">{title}</h2> : null}\n {description ? <p className=\"text-xs text-text-tertiary\">{description}</p> : null}\n </div>\n {action}\n </header>\n )}\n <div className=\"p-4\">{children}</div>\n </section>\n);\n\n// ---------------------------------------------------------------------------\n// Form controls (token-styled native elements — reliable inside modals)\n// ---------------------------------------------------------------------------\nconst controlClass =\n 'w-full rounded-lg border border-border-seam bg-bg-canvas px-3 py-2 text-sm text-text-primary placeholder:text-text-tertiary focus:border-accent focus:outline-none focus:ring-2 focus:ring-accent/30 disabled:opacity-50';\n\nexport const Field: FC<{\n label: string;\n required?: boolean;\n hint?: string;\n children: ReactNode;\n className?: string;\n}> = ({ label, required, hint, children, className }) => (\n <label className={cn('block', className)}>\n <span className=\"mb-1 block text-xs font-medium text-text-secondary\">\n {label}\n {required ? <span className=\"text-status-error-text\"> *</span> : null}\n </span>\n {children}\n {hint ? <span className=\"mt-1 block text-xs text-text-tertiary\">{hint}</span> : null}\n </label>\n);\n\nexport const TextInput: FC<React.InputHTMLAttributes<HTMLInputElement>> = ({\n className,\n ...props\n}) => <input className={cn(controlClass, className)} {...props} />;\nexport const TextArea: FC<React.TextareaHTMLAttributes<HTMLTextAreaElement>> = ({\n className,\n ...props\n}) => <textarea className={cn(controlClass, 'min-h-[80px] resize-y', className)} {...props} />;\nexport const NativeSelect: FC<React.SelectHTMLAttributes<HTMLSelectElement>> = ({\n className,\n children,\n ...props\n}) => (\n <select className={cn(controlClass, 'appearance-none pr-8')} {...props}>\n {children}\n </select>\n);\n\n/** Turn an enum-value list into <option>s with humanized labels. */\nexport const enumOptions = (values: readonly string[]): ReactNode =>\n values.map((v) => (\n <option key={v} value={v}>\n {humanize(v)}\n </option>\n ));\n\n// ---------------------------------------------------------------------------\n// Inline banner\n// ---------------------------------------------------------------------------\nexport const Banner: FC<{\n tone?: 'success' | 'danger' | 'info';\n children: ReactNode;\n onClose?: () => void;\n}> = ({ tone = 'info', children, onClose }) => {\n const Icon = tone === 'success' ? CheckCircle2 : tone === 'danger' ? AlertCircle : Info;\n const toneClass =\n tone === 'success'\n ? TONE_CLASS.success\n : tone === 'danger'\n ? TONE_CLASS.danger\n : 'bg-bg-sunken text-text-secondary';\n return (\n <div className={cn('flex items-start gap-2 rounded-lg px-3 py-2 text-sm', toneClass)}>\n <Icon className=\"mt-0.5 h-4 w-4 shrink-0\" />\n <div className=\"flex-1\">{children}</div>\n {onClose ? (\n <button\n type=\"button\"\n onClick={onClose}\n className=\"opacity-70 hover:opacity-100\"\n aria-label=\"Dismiss\"\n >\n <X className=\"h-4 w-4\" />\n </button>\n ) : null}\n </div>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Modal (centered on desktop, full-height sheet on mobile)\n// ---------------------------------------------------------------------------\nexport const Modal: FC<{\n open: boolean;\n onClose: () => void;\n title: string;\n children: ReactNode;\n footer?: ReactNode;\n wide?: boolean;\n}> = ({ open, onClose, title, children, footer, wide }) => {\n useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose();\n };\n document.addEventListener('keydown', onKey);\n document.body.style.overflow = 'hidden';\n return () => {\n document.removeEventListener('keydown', onKey);\n document.body.style.overflow = '';\n };\n }, [open, onClose]);\n\n if (!open) return null;\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-end justify-center sm:items-center\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label={title}\n >\n <div className=\"absolute inset-0 bg-black/50 backdrop-blur-sm\" onClick={onClose} />\n <div\n className={cn(\n 'relative flex max-h-[92vh] w-full flex-col overflow-hidden rounded-t-2xl border border-border-seam bg-bg-surface shadow-xl sm:max-h-[88vh] sm:rounded-2xl',\n wide ? 'sm:max-w-3xl' : 'sm:max-w-lg'\n )}\n >\n <header className=\"flex items-center justify-between border-b border-border-seam px-4 py-3\">\n <h2 className=\"text-base font-semibold text-text-primary\">{title}</h2>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"rounded-lg p-1 text-text-tertiary hover:bg-bg-sunken hover:text-text-primary\"\n aria-label=\"Close\"\n >\n <X className=\"h-5 w-5\" />\n </button>\n </header>\n <div className=\"flex-1 overflow-y-auto px-4 py-4\">{children}</div>\n {footer ? (\n <footer className=\"flex items-center justify-end gap-2 border-t border-border-seam px-4 py-3\">\n {footer}\n </footer>\n ) : null}\n </div>\n </div>\n );\n};\n\n// ---------------------------------------------------------------------------\n// States\n// ---------------------------------------------------------------------------\nexport const LoadingBlock: FC<{ label?: string }> = ({ label = 'Loading…' }) => (\n <div className=\"flex min-h-[220px] flex-col items-center justify-center gap-3 text-text-tertiary\">\n <Loader2 className=\"h-7 w-7 animate-spin text-accent\" />\n <span className=\"text-sm\">{label}</span>\n </div>\n);\n\nexport const ErrorState: FC<{ error: unknown; onRetry?: () => void }> = ({ error, onRetry }) => (\n <div className=\"flex min-h-[220px] flex-col items-center justify-center gap-3 text-center\">\n <AlertCircle className=\"h-8 w-8 text-status-error-text\" />\n <p className=\"max-w-md text-sm text-text-secondary\">\n {error instanceof Error ? error.message : 'Something went wrong.'}\n </p>\n {onRetry ? (\n <Button variant=\"outline\" size=\"sm\" onClick={onRetry}>\n Try again\n </Button>\n ) : null}\n </div>\n);\n\nexport const Empty: FC<{\n title: string;\n description?: string;\n icon?: ReactNode;\n action?: ReactNode;\n}> = ({ title, description, icon, action }) => (\n <div className=\"flex min-h-[220px] flex-col items-center justify-center gap-3 rounded-xl border border-dashed border-border-seam bg-bg-surface/50 px-6 py-10 text-center\">\n {icon ? <div className=\"text-text-tertiary\">{icon}</div> : null}\n <div>\n <p className=\"text-sm font-medium text-text-primary\">{title}</p>\n {description ? (\n <p className=\"mt-1 max-w-sm text-sm text-text-tertiary\">{description}</p>\n ) : null}\n </div>\n {action}\n </div>\n);\n\n// ---------------------------------------------------------------------------\n// Simple responsive table wrapper (scrolls horizontally on small screens)\n// ---------------------------------------------------------------------------\nexport const TableWrap: FC<{ children: ReactNode }> = ({ children }) => (\n <div className=\"overflow-x-auto rounded-xl border border-border-seam\">\n <table className=\"w-full min-w-[560px] text-left text-sm\">{children}</table>\n </div>\n);\nexport const Th: FC<{ children?: ReactNode; className?: string }> = ({ children, className }) => (\n <th\n className={cn(\n 'bg-bg-sunken px-4 py-2.5 text-xs font-semibold uppercase tracking-wide text-text-tertiary',\n className\n )}\n >\n {children}\n </th>\n);\nexport const Td: FC<{ children?: ReactNode; className?: string }> = ({ children, className }) => (\n <td className={cn('border-t border-border-seam px-4 py-3 text-text-secondary', className)}>\n {children}\n </td>\n);\n"],"mappings":"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"}