@burdenoff/microfe-housingvista 2026.625.2 → 2026.626.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.
@@ -10,9 +10,9 @@ import { useMemo as l, useState as u } from "react";
10
10
  import { ArrowDownRight as d, ArrowUpRight as f, BarChart3 as p, Building as m, Calendar as h, DollarSign as g, Eye as _, PieChart as v, Plus as y, Target as b, TrendingUp as x } from "lucide-react";
11
11
  import { useNavigate as S } from "react-router-dom";
12
12
  import { jsx as C, jsxs as w } from "react/jsx-runtime";
13
- import { EmphasisPanel as T } from "@burdenoff/fe-libs/ui";
13
+ import { EmphasisPanel as T, NextSteps as E } from "@burdenoff/fe-libs/ui";
14
14
  //#region src/housingvista/pages/investments/InvestmentsPage.tsx
15
- var E = [
15
+ var D = [
16
16
  {
17
17
  value: "all",
18
18
  label: "All"
@@ -30,7 +30,7 @@ var E = [
30
30
  label: "Funding"
31
31
  }
32
32
  ];
33
- function D(e) {
33
+ function O(e) {
34
34
  switch (e) {
35
35
  case "active": return "success";
36
36
  case "funding": return "warning";
@@ -41,26 +41,26 @@ function D(e) {
41
41
  default: return "default";
42
42
  }
43
43
  }
44
- function O(e) {
44
+ function k(e) {
45
45
  return e > 0 ? "text-emerald-600 dark:text-emerald-400" : e < 0 ? "text-red-600 dark:text-red-400" : "text-text-secondary";
46
46
  }
47
- function k() {
48
- let k = S(), { data: A } = c(), [j, M] = u(""), [N, P] = u("all"), F = l(() => A.filter((e) => {
49
- let t = e.property.title.toLowerCase().includes(j.toLowerCase()) || e.id.toLowerCase().includes(j.toLowerCase()), n = N === "all" || e.status === N;
47
+ function A() {
48
+ let A = S(), { data: j } = c(), [M, N] = u(""), [P, F] = u("all"), I = l(() => j.filter((e) => {
49
+ let t = e.property.title.toLowerCase().includes(M.toLowerCase()) || e.id.toLowerCase().includes(M.toLowerCase()), n = P === "all" || e.status === P;
50
50
  return t && n;
51
51
  }), [
52
- A,
53
52
  j,
54
- N
55
- ]), I = l(() => {
56
- let e = A.reduce((e, t) => e + t.investors.reduce((e, t) => e + t.investmentAmount, 0), 0), t = A.reduce((e, t) => e + t.returns.reduce((e, t) => e + t.amount, 0), 0);
53
+ M,
54
+ P
55
+ ]), L = l(() => {
56
+ let e = j.reduce((e, t) => e + t.investors.reduce((e, t) => e + t.investmentAmount, 0), 0), t = j.reduce((e, t) => e + t.returns.reduce((e, t) => e + t.amount, 0), 0);
57
57
  return {
58
58
  totalInvested: e,
59
59
  currentValue: e + t,
60
60
  totalReturns: t,
61
- activeCount: A.filter((e) => e.status === "active").length
61
+ activeCount: j.filter((e) => e.status === "active").length
62
62
  };
63
- }, [A]);
63
+ }, [j]);
64
64
  return /* @__PURE__ */ w(r, {
65
65
  title: "Investments",
66
66
  description: "Track your real estate investment portfolio and performance",
@@ -77,7 +77,7 @@ function k() {
77
77
  children: [
78
78
  /* @__PURE__ */ C(i, {
79
79
  label: "Total Invested",
80
- value: I.totalInvested,
80
+ value: L.totalInvested,
81
81
  prefix: "$",
82
82
  icon: /* @__PURE__ */ C(g, { className: "h-4 w-4" }),
83
83
  trend: "up",
@@ -85,7 +85,7 @@ function k() {
85
85
  }),
86
86
  /* @__PURE__ */ C(i, {
87
87
  label: "Current Value",
88
- value: I.currentValue,
88
+ value: L.currentValue,
89
89
  prefix: "$",
90
90
  icon: /* @__PURE__ */ C(x, { className: "h-4 w-4" }),
91
91
  trend: "up",
@@ -93,7 +93,7 @@ function k() {
93
93
  }),
94
94
  /* @__PURE__ */ C(i, {
95
95
  label: "Total Returns",
96
- value: I.totalReturns,
96
+ value: L.totalReturns,
97
97
  prefix: "$",
98
98
  icon: /* @__PURE__ */ C(v, { className: "h-4 w-4" }),
99
99
  trend: "up",
@@ -101,42 +101,68 @@ function k() {
101
101
  }),
102
102
  /* @__PURE__ */ C(i, {
103
103
  label: "Active Investments",
104
- value: I.activeCount,
104
+ value: L.activeCount,
105
105
  icon: /* @__PURE__ */ C(p, { className: "h-4 w-4" })
106
106
  })
107
107
  ]
108
108
  })
109
109
  }),
110
+ /* @__PURE__ */ C(E, {
111
+ storageKey: "housingvista-investments",
112
+ steps: [
113
+ {
114
+ id: "review-active",
115
+ label: "Review your active investments",
116
+ description: "Filter to the active deals currently paying returns.",
117
+ onClick: () => F("active")
118
+ },
119
+ {
120
+ id: "find-funding",
121
+ label: "Find funding opportunities",
122
+ description: "See deals still raising capital that you can join.",
123
+ onClick: () => F("funding")
124
+ },
125
+ {
126
+ id: "open-detail",
127
+ label: "Open an investment for full details",
128
+ description: "Drill into returns, investors, and risk for any holding.",
129
+ onClick: () => {
130
+ let e = j[0];
131
+ e && A(`/investments/${e.id}`);
132
+ }
133
+ }
134
+ ]
135
+ }),
110
136
  /* @__PURE__ */ C("div", {
111
137
  className: "flex flex-wrap items-center gap-2",
112
- children: E.map((t) => /* @__PURE__ */ C("button", {
113
- onClick: () => P(t.value),
114
- className: e("rounded-md px-3 py-1.5 text-sm font-medium transition-colors", N === t.value ? "bg-foreground text-background" : "bg-bg-sunken text-text-secondary hover:text-text-primary"),
138
+ children: D.map((t) => /* @__PURE__ */ C("button", {
139
+ onClick: () => F(t.value),
140
+ className: e("rounded-md px-3 py-1.5 text-sm font-medium transition-colors", P === t.value ? "bg-foreground text-background" : "bg-bg-sunken text-text-secondary hover:text-text-primary"),
115
141
  children: t.label
116
142
  }, t.value))
117
143
  }),
118
144
  /* @__PURE__ */ C(s, {
119
- searchValue: j,
120
- onSearchChange: M,
145
+ searchValue: M,
146
+ onSearchChange: N,
121
147
  searchPlaceholder: "Search by property or investment ID..."
122
148
  }),
123
149
  /* @__PURE__ */ w("p", {
124
150
  className: "text-sm text-text-secondary",
125
151
  children: [
126
152
  "Showing ",
127
- F.length,
153
+ I.length,
128
154
  " of ",
129
- A.length,
155
+ j.length,
130
156
  " investments"
131
157
  ]
132
158
  }),
133
- F.length > 0 ? /* @__PURE__ */ C("div", {
159
+ I.length > 0 ? /* @__PURE__ */ C("div", {
134
160
  className: "space-y-4",
135
- children: F.map((r) => {
161
+ children: I.map((r) => {
136
162
  let i = r.investors.reduce((e, t) => e + t.investmentAmount, 0), o = r.returns.reduce((e, t) => e + t.amount, 0), s = i + o, c = i > 0 ? o / i * 100 : 0;
137
163
  return /* @__PURE__ */ C("div", {
138
164
  className: "cursor-pointer rounded-lg border border-border-subtle bg-bg-surface p-5 shadow-sm transition-shadow hover:shadow-md",
139
- onClick: () => k(`/investments/${r.id}`),
165
+ onClick: () => A(`/investments/${r.id}`),
140
166
  children: /* @__PURE__ */ w("div", {
141
167
  className: "flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between",
142
168
  children: [/* @__PURE__ */ C("div", {
@@ -158,7 +184,7 @@ function k() {
158
184
  }),
159
185
  /* @__PURE__ */ C(a, {
160
186
  label: r.status,
161
- variant: D(r.status)
187
+ variant: O(r.status)
162
188
  }),
163
189
  /* @__PURE__ */ C(a, {
164
190
  label: r.investmentType.replace("_", " "),
@@ -187,7 +213,7 @@ function k() {
187
213
  className: "text-text-secondary",
188
214
  children: "Total Return"
189
215
  }), /* @__PURE__ */ w("div", {
190
- className: e("font-medium", O(o)),
216
+ className: e("font-medium", k(o)),
191
217
  children: [/* @__PURE__ */ w("div", {
192
218
  className: "flex items-center gap-1",
193
219
  children: [
@@ -246,7 +272,7 @@ function k() {
246
272
  className: "flex shrink-0 gap-2",
247
273
  children: /* @__PURE__ */ w("button", {
248
274
  onClick: (e) => {
249
- e.stopPropagation(), k(`/investments/${r.id}`);
275
+ e.stopPropagation(), A(`/investments/${r.id}`);
250
276
  },
251
277
  className: "inline-flex items-center gap-1 rounded-md border border-border-subtle px-3 py-1.5 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
252
278
  children: [/* @__PURE__ */ C(_, { className: "h-4 w-4" }), "View Details"]
@@ -269,6 +295,6 @@ function k() {
269
295
  });
270
296
  }
271
297
  //#endregion
272
- export { k as InvestmentsPage };
298
+ export { A as InvestmentsPage };
273
299
 
274
300
  //# sourceMappingURL=InvestmentsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"InvestmentsPage.js","names":[],"sources":["../../../../src/housingvista/pages/investments/InvestmentsPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n DollarSign,\n TrendingUp,\n PieChart,\n BarChart3,\n Plus,\n Building,\n ArrowUpRight,\n ArrowDownRight,\n Eye,\n Target,\n Calendar,\n} from 'lucide-react';\nimport { EmphasisPanel } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components';\nimport { StatCard } from '../../components';\nimport { FilterBar } from '../../components';\nimport { StatusBadge } from '../../components';\nimport { EmptyState } from '../../components';\nimport { useInvestments } from '../../hooks';\nimport { cn, formatCurrency, formatDate } from '../../utils/helpers';\nimport type { Investment, InvestmentStatus } from '../../types';\n\nconst statusTabs: { value: InvestmentStatus | 'all'; label: string }[] = [\n { value: 'all', label: 'All' },\n { value: 'active', label: 'Active' },\n { value: 'closed', label: 'Completed' },\n { value: 'funding', label: 'Funding' },\n];\n\nfunction getStatusVariant(status: InvestmentStatus): 'success' | 'warning' | 'error' | 'info' | 'muted' | 'default' {\n switch (status) {\n case 'active':\n return 'success';\n case 'funding':\n return 'warning';\n case 'closed':\n case 'mature':\n return 'info';\n case 'draft':\n case 'open':\n return 'muted';\n default:\n return 'default';\n }\n}\n\nfunction getReturnColor(returnValue: number) {\n if (returnValue > 0) return 'text-emerald-600 dark:text-emerald-400';\n if (returnValue < 0) return 'text-red-600 dark:text-red-400';\n return 'text-text-secondary';\n}\n\nexport function InvestmentsPage() {\n const navigate = useNavigate();\n const { data: investments } = useInvestments();\n const [search, setSearch] = useState('');\n const [activeTab, setActiveTab] = useState<InvestmentStatus | 'all'>('all');\n\n const filtered = useMemo(() => {\n return investments.filter((inv) => {\n const matchesSearch =\n inv.property.title.toLowerCase().includes(search.toLowerCase()) ||\n inv.id.toLowerCase().includes(search.toLowerCase());\n const matchesTab = activeTab === 'all' || inv.status === activeTab;\n return matchesSearch && matchesTab;\n });\n }, [investments, search, activeTab]);\n\n const portfolioStats = useMemo(() => {\n const totalInvested = investments.reduce((sum, inv) => {\n return sum + inv.investors.reduce((s, i) => s + i.investmentAmount, 0);\n }, 0);\n const totalReturns = investments.reduce((sum, inv) => {\n return sum + inv.returns.reduce((s, r) => s + r.amount, 0);\n }, 0);\n const currentValue = totalInvested + totalReturns;\n const activeCount = investments.filter((inv) => inv.status === 'active').length;\n return { totalInvested, currentValue, totalReturns, activeCount };\n }, [investments]);\n\n return (\n <PageLayout\n title=\"Investments\"\n description=\"Track your real estate investment portfolio and performance\"\n purpose=\"Follow every real-estate investment you hold in one portfolio — how much you put in, what it is worth now, the returns it has paid, and its risk level. Use it to judge performance and decide where to put your next dollar.\"\n actions={\n <button className=\"inline-flex items-center gap-2 rounded-md bg-foreground px-4 py-2 text-sm font-medium text-background transition-colors hover:bg-foreground/90\">\n <Plus className=\"h-4 w-4\" />\n New Investment\n </button>\n }\n >\n {/* Portfolio Summary Stats — primary insight zone (one EmphasisPanel per page) */}\n <EmphasisPanel className=\"p-4\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n label=\"Total Invested\"\n value={portfolioStats.totalInvested}\n prefix=\"$\"\n icon={<DollarSign className=\"h-4 w-4\" />}\n trend=\"up\"\n change={12}\n />\n <StatCard\n label=\"Current Value\"\n value={portfolioStats.currentValue}\n prefix=\"$\"\n icon={<TrendingUp className=\"h-4 w-4\" />}\n trend=\"up\"\n change={8}\n />\n <StatCard\n label=\"Total Returns\"\n value={portfolioStats.totalReturns}\n prefix=\"$\"\n icon={<PieChart className=\"h-4 w-4\" />}\n trend=\"up\"\n change={15}\n />\n <StatCard\n label=\"Active Investments\"\n value={portfolioStats.activeCount}\n icon={<BarChart3 className=\"h-4 w-4\" />}\n />\n </div>\n </EmphasisPanel>\n\n {/* Filter Tabs */}\n <div className=\"flex flex-wrap items-center gap-2\">\n {statusTabs.map((tab) => (\n <button\n key={tab.value}\n onClick={() => setActiveTab(tab.value)}\n className={cn(\n 'rounded-md px-3 py-1.5 text-sm font-medium transition-colors',\n activeTab === tab.value\n ? 'bg-foreground text-background'\n : 'bg-bg-sunken text-text-secondary hover:text-text-primary'\n )}\n >\n {tab.label}\n </button>\n ))}\n </div>\n\n {/* Search */}\n <FilterBar\n searchValue={search}\n onSearchChange={setSearch}\n searchPlaceholder=\"Search by property or investment ID...\"\n />\n\n {/* Results count */}\n <p className=\"text-sm text-text-secondary\">\n Showing {filtered.length} of {investments.length} investments\n </p>\n\n {/* Investment Cards */}\n {filtered.length > 0 ? (\n <div className=\"space-y-4\">\n {filtered.map((investment) => {\n const totalInvested = investment.investors.reduce((s, i) => s + i.investmentAmount, 0);\n const totalReturns = investment.returns.reduce((s, r) => s + r.amount, 0);\n const currentValue = totalInvested + totalReturns;\n const returnPercentage = totalInvested > 0 ? (totalReturns / totalInvested) * 100 : 0;\n\n return (\n <div\n key={investment.id}\n className=\"cursor-pointer rounded-lg border border-border-subtle bg-bg-surface p-5 shadow-sm transition-shadow hover:shadow-md\"\n onClick={() => navigate(`/investments/${investment.id}`)}\n >\n <div className=\"flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"flex-1\">\n <div className=\"flex items-start gap-3\">\n <div className=\"rounded-lg bg-bg-sunken p-2\">\n <Building className=\"h-5 w-5 text-text-secondary\" />\n </div>\n <div className=\"flex-1\">\n <div className=\"mb-2 flex flex-wrap items-center gap-2\">\n <h3 className=\"text-lg font-semibold text-text-primary\">{investment.property.title}</h3>\n <StatusBadge label={investment.status} variant={getStatusVariant(investment.status)} />\n <StatusBadge label={investment.investmentType.replace('_', ' ')} variant=\"muted\" />\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 text-sm sm:grid-cols-2 lg:grid-cols-4\">\n <div>\n <p className=\"text-text-secondary\">Invested Amount</p>\n <p className=\"text-lg font-medium text-text-primary\">{formatCurrency(totalInvested)}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Current Value</p>\n <p className=\"text-lg font-medium text-text-primary\">{formatCurrency(currentValue)}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Total Return</p>\n <div className={cn('font-medium', getReturnColor(totalReturns))}>\n <div className=\"flex items-center gap-1\">\n {totalReturns > 0 && <ArrowUpRight className=\"h-3 w-3\" />}\n {totalReturns < 0 && <ArrowDownRight className=\"h-3 w-3\" />}\n {formatCurrency(totalReturns)}\n </div>\n <div className=\"text-sm\">{returnPercentage.toFixed(1)}%</div>\n </div>\n </div>\n <div>\n <p className=\"text-text-secondary\">Risk Level</p>\n <p className=\"font-medium capitalize text-text-primary\">{investment.riskLevel}</p>\n </div>\n </div>\n\n <div className=\"mt-3 flex flex-wrap items-center gap-5 text-xs text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <TrendingUp className=\"h-3 w-3\" />\n Start: {formatDate(investment.startDate.toISOString())}\n </span>\n <span className=\"flex items-center gap-1\">\n <Target className=\"h-3 w-3\" />\n Type: {investment.investmentType.replace('_', ' ')}\n </span>\n <span className=\"flex items-center gap-1\">\n <Calendar className=\"h-3 w-3\" />\n Returns: {investment.returns.length} payments\n </span>\n </div>\n </div>\n </div>\n </div>\n\n <div className=\"flex shrink-0 gap-2\">\n <button\n onClick={(e) => {\n e.stopPropagation();\n navigate(`/investments/${investment.id}`);\n }}\n className=\"inline-flex items-center gap-1 rounded-md border border-border-subtle px-3 py-1.5 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n <Eye className=\"h-4 w-4\" />\n View Details\n </button>\n </div>\n </div>\n </div>\n );\n })}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-search\"\n icon={<PieChart className=\"h-12 w-12\" />}\n title=\"No investments found\"\n description=\"Try adjusting your search criteria or explore new investment opportunities.\"\n action={\n <button className=\"inline-flex items-center gap-2 rounded-md bg-foreground px-4 py-2 text-sm font-medium text-background transition-colors hover:bg-foreground/90\">\n <Plus className=\"h-4 w-4\" />\n Explore Investments\n </button>\n }\n />\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"InvestmentsPage.js","names":[],"sources":["../../../../src/housingvista/pages/investments/InvestmentsPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n DollarSign,\n TrendingUp,\n PieChart,\n BarChart3,\n Plus,\n Building,\n ArrowUpRight,\n ArrowDownRight,\n Eye,\n Target,\n Calendar,\n} from 'lucide-react';\nimport { EmphasisPanel, NextSteps } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components';\nimport { StatCard } from '../../components';\nimport { FilterBar } from '../../components';\nimport { StatusBadge } from '../../components';\nimport { EmptyState } from '../../components';\nimport { useInvestments } from '../../hooks';\nimport { cn, formatCurrency, formatDate } from '../../utils/helpers';\nimport type { Investment, InvestmentStatus } from '../../types';\n\nconst statusTabs: { value: InvestmentStatus | 'all'; label: string }[] = [\n { value: 'all', label: 'All' },\n { value: 'active', label: 'Active' },\n { value: 'closed', label: 'Completed' },\n { value: 'funding', label: 'Funding' },\n];\n\nfunction getStatusVariant(status: InvestmentStatus): 'success' | 'warning' | 'error' | 'info' | 'muted' | 'default' {\n switch (status) {\n case 'active':\n return 'success';\n case 'funding':\n return 'warning';\n case 'closed':\n case 'mature':\n return 'info';\n case 'draft':\n case 'open':\n return 'muted';\n default:\n return 'default';\n }\n}\n\nfunction getReturnColor(returnValue: number) {\n if (returnValue > 0) return 'text-emerald-600 dark:text-emerald-400';\n if (returnValue < 0) return 'text-red-600 dark:text-red-400';\n return 'text-text-secondary';\n}\n\nexport function InvestmentsPage() {\n const navigate = useNavigate();\n const { data: investments } = useInvestments();\n const [search, setSearch] = useState('');\n const [activeTab, setActiveTab] = useState<InvestmentStatus | 'all'>('all');\n\n const filtered = useMemo(() => {\n return investments.filter((inv) => {\n const matchesSearch =\n inv.property.title.toLowerCase().includes(search.toLowerCase()) ||\n inv.id.toLowerCase().includes(search.toLowerCase());\n const matchesTab = activeTab === 'all' || inv.status === activeTab;\n return matchesSearch && matchesTab;\n });\n }, [investments, search, activeTab]);\n\n const portfolioStats = useMemo(() => {\n const totalInvested = investments.reduce((sum, inv) => {\n return sum + inv.investors.reduce((s, i) => s + i.investmentAmount, 0);\n }, 0);\n const totalReturns = investments.reduce((sum, inv) => {\n return sum + inv.returns.reduce((s, r) => s + r.amount, 0);\n }, 0);\n const currentValue = totalInvested + totalReturns;\n const activeCount = investments.filter((inv) => inv.status === 'active').length;\n return { totalInvested, currentValue, totalReturns, activeCount };\n }, [investments]);\n\n return (\n <PageLayout\n title=\"Investments\"\n description=\"Track your real estate investment portfolio and performance\"\n purpose=\"Follow every real-estate investment you hold in one portfolio — how much you put in, what it is worth now, the returns it has paid, and its risk level. Use it to judge performance and decide where to put your next dollar.\"\n actions={\n <button className=\"inline-flex items-center gap-2 rounded-md bg-foreground px-4 py-2 text-sm font-medium text-background transition-colors hover:bg-foreground/90\">\n <Plus className=\"h-4 w-4\" />\n New Investment\n </button>\n }\n >\n {/* Portfolio Summary Stats — primary insight zone (one EmphasisPanel per page) */}\n <EmphasisPanel className=\"p-4\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n label=\"Total Invested\"\n value={portfolioStats.totalInvested}\n prefix=\"$\"\n icon={<DollarSign className=\"h-4 w-4\" />}\n trend=\"up\"\n change={12}\n />\n <StatCard\n label=\"Current Value\"\n value={portfolioStats.currentValue}\n prefix=\"$\"\n icon={<TrendingUp className=\"h-4 w-4\" />}\n trend=\"up\"\n change={8}\n />\n <StatCard\n label=\"Total Returns\"\n value={portfolioStats.totalReturns}\n prefix=\"$\"\n icon={<PieChart className=\"h-4 w-4\" />}\n trend=\"up\"\n change={15}\n />\n <StatCard\n label=\"Active Investments\"\n value={portfolioStats.activeCount}\n icon={<BarChart3 className=\"h-4 w-4\" />}\n />\n </div>\n </EmphasisPanel>\n\n <NextSteps\n storageKey=\"housingvista-investments\"\n steps={[\n {\n id: 'review-active',\n label: 'Review your active investments',\n description: 'Filter to the active deals currently paying returns.',\n onClick: () => setActiveTab('active'),\n },\n {\n id: 'find-funding',\n label: 'Find funding opportunities',\n description: 'See deals still raising capital that you can join.',\n onClick: () => setActiveTab('funding'),\n },\n {\n id: 'open-detail',\n label: 'Open an investment for full details',\n description: 'Drill into returns, investors, and risk for any holding.',\n onClick: () => {\n const first = investments[0];\n if (first) navigate(`/investments/${first.id}`);\n },\n },\n ]}\n />\n\n {/* Filter Tabs */}\n <div className=\"flex flex-wrap items-center gap-2\">\n {statusTabs.map((tab) => (\n <button\n key={tab.value}\n onClick={() => setActiveTab(tab.value)}\n className={cn(\n 'rounded-md px-3 py-1.5 text-sm font-medium transition-colors',\n activeTab === tab.value\n ? 'bg-foreground text-background'\n : 'bg-bg-sunken text-text-secondary hover:text-text-primary'\n )}\n >\n {tab.label}\n </button>\n ))}\n </div>\n\n {/* Search */}\n <FilterBar\n searchValue={search}\n onSearchChange={setSearch}\n searchPlaceholder=\"Search by property or investment ID...\"\n />\n\n {/* Results count */}\n <p className=\"text-sm text-text-secondary\">\n Showing {filtered.length} of {investments.length} investments\n </p>\n\n {/* Investment Cards */}\n {filtered.length > 0 ? (\n <div className=\"space-y-4\">\n {filtered.map((investment) => {\n const totalInvested = investment.investors.reduce((s, i) => s + i.investmentAmount, 0);\n const totalReturns = investment.returns.reduce((s, r) => s + r.amount, 0);\n const currentValue = totalInvested + totalReturns;\n const returnPercentage = totalInvested > 0 ? (totalReturns / totalInvested) * 100 : 0;\n\n return (\n <div\n key={investment.id}\n className=\"cursor-pointer rounded-lg border border-border-subtle bg-bg-surface p-5 shadow-sm transition-shadow hover:shadow-md\"\n onClick={() => navigate(`/investments/${investment.id}`)}\n >\n <div className=\"flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between\">\n <div className=\"flex-1\">\n <div className=\"flex items-start gap-3\">\n <div className=\"rounded-lg bg-bg-sunken p-2\">\n <Building className=\"h-5 w-5 text-text-secondary\" />\n </div>\n <div className=\"flex-1\">\n <div className=\"mb-2 flex flex-wrap items-center gap-2\">\n <h3 className=\"text-lg font-semibold text-text-primary\">{investment.property.title}</h3>\n <StatusBadge label={investment.status} variant={getStatusVariant(investment.status)} />\n <StatusBadge label={investment.investmentType.replace('_', ' ')} variant=\"muted\" />\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 text-sm sm:grid-cols-2 lg:grid-cols-4\">\n <div>\n <p className=\"text-text-secondary\">Invested Amount</p>\n <p className=\"text-lg font-medium text-text-primary\">{formatCurrency(totalInvested)}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Current Value</p>\n <p className=\"text-lg font-medium text-text-primary\">{formatCurrency(currentValue)}</p>\n </div>\n <div>\n <p className=\"text-text-secondary\">Total Return</p>\n <div className={cn('font-medium', getReturnColor(totalReturns))}>\n <div className=\"flex items-center gap-1\">\n {totalReturns > 0 && <ArrowUpRight className=\"h-3 w-3\" />}\n {totalReturns < 0 && <ArrowDownRight className=\"h-3 w-3\" />}\n {formatCurrency(totalReturns)}\n </div>\n <div className=\"text-sm\">{returnPercentage.toFixed(1)}%</div>\n </div>\n </div>\n <div>\n <p className=\"text-text-secondary\">Risk Level</p>\n <p className=\"font-medium capitalize text-text-primary\">{investment.riskLevel}</p>\n </div>\n </div>\n\n <div className=\"mt-3 flex flex-wrap items-center gap-5 text-xs text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <TrendingUp className=\"h-3 w-3\" />\n Start: {formatDate(investment.startDate.toISOString())}\n </span>\n <span className=\"flex items-center gap-1\">\n <Target className=\"h-3 w-3\" />\n Type: {investment.investmentType.replace('_', ' ')}\n </span>\n <span className=\"flex items-center gap-1\">\n <Calendar className=\"h-3 w-3\" />\n Returns: {investment.returns.length} payments\n </span>\n </div>\n </div>\n </div>\n </div>\n\n <div className=\"flex shrink-0 gap-2\">\n <button\n onClick={(e) => {\n e.stopPropagation();\n navigate(`/investments/${investment.id}`);\n }}\n className=\"inline-flex items-center gap-1 rounded-md border border-border-subtle px-3 py-1.5 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n <Eye className=\"h-4 w-4\" />\n View Details\n </button>\n </div>\n </div>\n </div>\n );\n })}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-search\"\n icon={<PieChart className=\"h-12 w-12\" />}\n title=\"No investments found\"\n description=\"Try adjusting your search criteria or explore new investment opportunities.\"\n action={\n <button className=\"inline-flex items-center gap-2 rounded-md bg-foreground px-4 py-2 text-sm font-medium text-background transition-colors hover:bg-foreground/90\">\n <Plus className=\"h-4 w-4\" />\n Explore Investments\n </button>\n }\n />\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -8,9 +8,9 @@ import { useMemo as a, useState as o } from "react";
8
8
  import { BookOpen as s, ClipboardCheck as c, Clock as l, FileText as u, Gavel as d, Scale as f, Search as p, Shield as m, Star as h } from "lucide-react";
9
9
  import { useNavigate as g } from "react-router-dom";
10
10
  import { jsx as _, jsxs as v } from "react/jsx-runtime";
11
- import { EmphasisPanel as y } from "@burdenoff/fe-libs/ui";
11
+ import { EmphasisPanel as y, NextSteps as b } from "@burdenoff/fe-libs/ui";
12
12
  //#region src/housingvista/pages/legal/LegalPage.tsx
13
- var b = [
13
+ var x = [
14
14
  {
15
15
  value: "all",
16
16
  label: "All"
@@ -36,7 +36,7 @@ var b = [
36
36
  label: "Document Review"
37
37
  }
38
38
  ];
39
- function x(e) {
39
+ function S(e) {
40
40
  switch (e) {
41
41
  case "title_search": return /* @__PURE__ */ _(p, { className: "h-4 w-4" });
42
42
  case "lease_review": return /* @__PURE__ */ _(u, { className: "h-4 w-4" });
@@ -46,7 +46,7 @@ function x(e) {
46
46
  default: return /* @__PURE__ */ _(f, { className: "h-4 w-4" });
47
47
  }
48
48
  }
49
- function S(e) {
49
+ function C(e) {
50
50
  switch (e) {
51
51
  case "available": return "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400";
52
52
  case "busy": return "bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400";
@@ -54,13 +54,13 @@ function S(e) {
54
54
  default: return "bg-bg-sunken text-text-secondary";
55
55
  }
56
56
  }
57
- function C({ rating: t }) {
57
+ function w({ rating: t }) {
58
58
  return /* @__PURE__ */ _("div", {
59
59
  className: "flex items-center gap-0.5",
60
60
  children: Array.from({ length: 5 }).map((n, r) => /* @__PURE__ */ _(h, { className: e("h-3 w-3", r < Math.floor(t) ? "fill-amber-400 text-amber-400" : "text-text-secondary/30") }, r))
61
61
  });
62
62
  }
63
- function w({ service: t }) {
63
+ function T({ service: t }) {
64
64
  let n = g(), [r, i] = o(!1);
65
65
  return /* @__PURE__ */ v("div", {
66
66
  className: "rounded-lg border border-border-subtle bg-bg-surface p-5 shadow-sm transition-shadow hover:shadow-md",
@@ -71,7 +71,7 @@ function w({ service: t }) {
71
71
  className: "flex items-start gap-3",
72
72
  children: [/* @__PURE__ */ _("div", {
73
73
  className: "flex h-10 w-10 items-center justify-center rounded-lg bg-bg-sunken text-text-secondary",
74
- children: x(t.category)
74
+ children: S(t.category)
75
75
  }), /* @__PURE__ */ v("div", { children: [/* @__PURE__ */ _("h3", {
76
76
  className: "text-sm font-semibold text-text-primary",
77
77
  children: t.title
@@ -80,7 +80,7 @@ function w({ service: t }) {
80
80
  children: t.providerName
81
81
  })] })]
82
82
  }), /* @__PURE__ */ _("span", {
83
- className: e("inline-flex rounded-full px-2 py-0.5 text-xs font-medium capitalize", S(t.status)),
83
+ className: e("inline-flex rounded-full px-2 py-0.5 text-xs font-medium capitalize", C(t.status)),
84
84
  children: t.status
85
85
  })]
86
86
  }),
@@ -92,7 +92,7 @@ function w({ service: t }) {
92
92
  className: "mb-3 flex items-center gap-4 text-xs",
93
93
  children: [/* @__PURE__ */ v("div", {
94
94
  className: "flex items-center gap-1.5",
95
- children: [/* @__PURE__ */ _(C, { rating: t.providerRating }), /* @__PURE__ */ _("span", {
95
+ children: [/* @__PURE__ */ _(w, { rating: t.providerRating }), /* @__PURE__ */ _("span", {
96
96
  className: "font-medium text-text-primary",
97
97
  children: t.providerRating
98
98
  })]
@@ -142,7 +142,7 @@ function w({ service: t }) {
142
142
  ]
143
143
  });
144
144
  }
145
- function T() {
145
+ function E() {
146
146
  let { data: s } = i(), [c, l] = o("all"), [u, d] = o(""), p = a(() => s.filter((e) => {
147
147
  let t = c === "all" || e.category === c, n = !u || e.title.toLowerCase().includes(u.toLowerCase()) || e.providerName.toLowerCase().includes(u.toLowerCase()) || e.description.toLowerCase().includes(u.toLowerCase());
148
148
  return t && n;
@@ -162,7 +162,7 @@ function T() {
162
162
  children: [
163
163
  /* @__PURE__ */ _(y, {
164
164
  className: "flex flex-wrap items-center gap-2 p-3",
165
- children: b.map((t) => /* @__PURE__ */ _("button", {
165
+ children: x.map((t) => /* @__PURE__ */ _("button", {
166
166
  onClick: () => l(t.value),
167
167
  className: e("rounded-full px-4 py-1.5 text-sm font-medium transition-colors", c === t.value ? "bg-foreground text-background" : "border border-border-subtle bg-bg-surface text-text-secondary hover:bg-bg-sunken hover:text-text-primary"),
168
168
  children: t.label
@@ -173,9 +173,32 @@ function T() {
173
173
  onSearchChange: d,
174
174
  searchPlaceholder: "Search legal services..."
175
175
  }),
176
+ /* @__PURE__ */ _(b, {
177
+ storageKey: "housingvista-legal",
178
+ steps: [
179
+ {
180
+ id: "verify-title",
181
+ label: "Verify a property title",
182
+ description: "The first legal check before any purchase — find a title-search expert.",
183
+ onClick: () => l("title_search")
184
+ },
185
+ {
186
+ id: "rent-agreement",
187
+ label: "Draft or review a rent agreement",
188
+ description: "Get a lawyer to prepare or vet your lease paperwork.",
189
+ onClick: () => l("lease_review")
190
+ },
191
+ {
192
+ id: "registration",
193
+ label: "Handle property registration",
194
+ description: "Find help to register a deal with the authorities.",
195
+ onClick: () => l("registration")
196
+ }
197
+ ]
198
+ }),
176
199
  p.length > 0 ? /* @__PURE__ */ _("div", {
177
200
  className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3",
178
- children: p.map((e) => /* @__PURE__ */ _(w, { service: e }, e.id))
201
+ children: p.map((e) => /* @__PURE__ */ _(T, { service: e }, e.id))
179
202
  }) : /* @__PURE__ */ _(n, {
180
203
  illustration: "empty-search",
181
204
  icon: /* @__PURE__ */ _(f, { className: "h-12 w-12" }),
@@ -186,6 +209,6 @@ function T() {
186
209
  });
187
210
  }
188
211
  //#endregion
189
- export { T as LegalPage };
212
+ export { E as LegalPage };
190
213
 
191
214
  //# sourceMappingURL=LegalPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LegalPage.js","names":[],"sources":["../../../../src/housingvista/pages/legal/LegalPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n Scale,\n Star,\n Clock,\n FileText,\n Search as SearchIcon,\n Shield,\n Gavel,\n BookOpen,\n ClipboardCheck,\n ExternalLink,\n} from 'lucide-react';\nimport { EmphasisPanel } from '@burdenoff/fe-libs/ui';\nimport { PageLayout, FilterBar, EmptyState } from '../../components';\nimport { useLegalServices } from '../../hooks';\nimport { cn } from '../../utils/helpers';\nimport type { LegalService } from '../../types';\n\ntype CategoryTab = 'all' | 'title_search' | 'lease_review' | 'dispute_resolution' | 'registration' | 'compliance';\n\nconst categoryTabs: { value: CategoryTab; label: string }[] = [\n { value: 'all', label: 'All' },\n { value: 'title_search', label: 'Title Verification' },\n { value: 'lease_review', label: 'Rent Agreement' },\n { value: 'dispute_resolution', label: 'Advisory' },\n { value: 'registration', label: 'Registration' },\n { value: 'compliance', label: 'Document Review' },\n];\n\nfunction getCategoryIcon(category: string) {\n switch (category) {\n case 'title_search':\n return <SearchIcon className=\"h-4 w-4\" />;\n case 'lease_review':\n return <FileText className=\"h-4 w-4\" />;\n case 'dispute_resolution':\n return <Gavel className=\"h-4 w-4\" />;\n case 'registration':\n return <ClipboardCheck className=\"h-4 w-4\" />;\n case 'compliance':\n return <BookOpen className=\"h-4 w-4\" />;\n default:\n return <Scale className=\"h-4 w-4\" />;\n }\n}\n\nfunction getStatusStyles(status: string) {\n switch (status) {\n case 'available':\n return 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400';\n case 'busy':\n return 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400';\n case 'unavailable':\n return 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400';\n default:\n return 'bg-bg-sunken text-text-secondary';\n }\n}\n\nfunction RatingStars({ rating }: { rating: number }) {\n return (\n <div className=\"flex items-center gap-0.5\">\n {Array.from({ length: 5 }).map((_, i) => (\n <Star\n key={i}\n className={cn(\n 'h-3 w-3',\n i < Math.floor(rating) ? 'fill-amber-400 text-amber-400' : 'text-text-secondary/30'\n )}\n />\n ))}\n </div>\n );\n}\n\nfunction LegalServiceCard({ service }: { service: LegalService }) {\n const navigate = useNavigate();\n const [showDocs, setShowDocs] = useState(false);\n\n return (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-5 shadow-sm transition-shadow hover:shadow-md\">\n {/* Header */}\n <div className=\"mb-3 flex items-start justify-between gap-3\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-lg bg-bg-sunken text-text-secondary\">\n {getCategoryIcon(service.category)}\n </div>\n <div>\n <h3 className=\"text-sm font-semibold text-text-primary\">{service.title}</h3>\n <p className=\"text-xs text-text-secondary\">{service.providerName}</p>\n </div>\n </div>\n <span\n className={cn(\n 'inline-flex rounded-full px-2 py-0.5 text-xs font-medium capitalize',\n getStatusStyles(service.status)\n )}\n >\n {service.status}\n </span>\n </div>\n\n {/* Description */}\n <p className=\"mb-3 text-xs text-text-secondary line-clamp-2\">{service.description}</p>\n\n {/* Rating + Duration */}\n <div className=\"mb-3 flex items-center gap-4 text-xs\">\n <div className=\"flex items-center gap-1.5\">\n <RatingStars rating={service.providerRating} />\n <span className=\"font-medium text-text-primary\">{service.providerRating}</span>\n </div>\n <span className=\"flex items-center gap-1 text-text-secondary\">\n <Clock className=\"h-3 w-3\" />\n {service.estimatedDuration}\n </span>\n </div>\n\n {/* Price + Consultation Fee */}\n <div className=\"mb-3 flex items-center justify-between text-xs\">\n <span className=\"font-semibold text-text-primary\">{service.priceRange}</span>\n {service.consultationFee > 0 ? (\n <span className=\"text-text-secondary\">Consultation: ${service.consultationFee}</span>\n ) : (\n <span className=\"text-emerald-600 dark:text-emerald-400\">Free Consultation</span>\n )}\n </div>\n\n {/* Documents Required (collapsible) */}\n {service.documentsRequired.length > 0 && (\n <div className=\"mb-3\">\n <button\n onClick={() => setShowDocs(!showDocs)}\n className=\"text-xs font-medium text-text-secondary hover:text-text-primary\"\n >\n {showDocs ? 'Hide' : 'Show'} required documents ({service.documentsRequired.length})\n </button>\n {showDocs && (\n <ul className=\"mt-1.5 space-y-1\">\n {service.documentsRequired.map((doc, i) => (\n <li key={i} className=\"flex items-center gap-1.5 text-xs text-text-secondary\">\n <span className=\"h-1 w-1 rounded-full bg-muted-foreground\" />\n {doc}\n </li>\n ))}\n </ul>\n )}\n </div>\n )}\n\n {/* Action */}\n <button\n onClick={() => navigate(`/legal/${service.id}`)}\n disabled={service.status === 'unavailable'}\n className={cn(\n 'w-full rounded-md px-4 py-2 text-xs font-medium transition-colors',\n service.status === 'unavailable'\n ? 'cursor-not-allowed bg-bg-sunken text-text-secondary'\n : 'bg-foreground text-background hover:bg-foreground/90'\n )}\n >\n {service.status === 'unavailable' ? 'Currently Unavailable' : 'Book Now'}\n </button>\n </div>\n );\n}\n\nexport function LegalPage() {\n const { data: services } = useLegalServices();\n const [activeCategory, setActiveCategory] = useState<CategoryTab>('all');\n const [search, setSearch] = useState('');\n\n const filtered = useMemo(() => {\n return services.filter((s) => {\n const matchesCategory = activeCategory === 'all' || s.category === activeCategory;\n const matchesSearch =\n !search ||\n s.title.toLowerCase().includes(search.toLowerCase()) ||\n s.providerName.toLowerCase().includes(search.toLowerCase()) ||\n s.description.toLowerCase().includes(search.toLowerCase());\n return matchesCategory && matchesSearch;\n });\n }, [services, activeCategory, search]);\n\n return (\n <PageLayout\n title=\"Legal Services\"\n description=\"Professional legal solutions for property transactions and documentation\"\n purpose=\"Connect with verified property lawyers for the legal work behind every deal — title verification, rent agreements, registration, dispute advisory, and document review. Browse by category, compare ratings and fees, and book a consultation.\"\n actions={\n <span className=\"inline-flex items-center gap-1 text-xs text-emerald-600 dark:text-emerald-400\">\n <Shield className=\"h-3.5 w-3.5\" />\n Legally Compliant\n </span>\n }\n >\n {/* Category Tabs — primary control zone (one EmphasisPanel per page) */}\n <EmphasisPanel className=\"flex flex-wrap items-center gap-2 p-3\">\n {categoryTabs.map((tab) => (\n <button\n key={tab.value}\n onClick={() => setActiveCategory(tab.value)}\n className={cn(\n 'rounded-full px-4 py-1.5 text-sm font-medium transition-colors',\n activeCategory === tab.value\n ? 'bg-foreground text-background'\n : 'border border-border-subtle bg-bg-surface text-text-secondary hover:bg-bg-sunken hover:text-text-primary'\n )}\n >\n {tab.label}\n </button>\n ))}\n </EmphasisPanel>\n\n {/* Search */}\n <FilterBar searchValue={search} onSearchChange={setSearch} searchPlaceholder=\"Search legal services...\" />\n\n {/* Service Cards */}\n {filtered.length > 0 ? (\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {filtered.map((service) => (\n <LegalServiceCard key={service.id} service={service} />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-search\"\n icon={<Scale className=\"h-12 w-12\" />}\n title=\"No legal services found\"\n description=\"Try adjusting your search or category filter.\"\n />\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"LegalPage.js","names":[],"sources":["../../../../src/housingvista/pages/legal/LegalPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n Scale,\n Star,\n Clock,\n FileText,\n Search as SearchIcon,\n Shield,\n Gavel,\n BookOpen,\n ClipboardCheck,\n ExternalLink,\n} from 'lucide-react';\nimport { EmphasisPanel, NextSteps } from '@burdenoff/fe-libs/ui';\nimport { PageLayout, FilterBar, EmptyState } from '../../components';\nimport { useLegalServices } from '../../hooks';\nimport { cn } from '../../utils/helpers';\nimport type { LegalService } from '../../types';\n\ntype CategoryTab = 'all' | 'title_search' | 'lease_review' | 'dispute_resolution' | 'registration' | 'compliance';\n\nconst categoryTabs: { value: CategoryTab; label: string }[] = [\n { value: 'all', label: 'All' },\n { value: 'title_search', label: 'Title Verification' },\n { value: 'lease_review', label: 'Rent Agreement' },\n { value: 'dispute_resolution', label: 'Advisory' },\n { value: 'registration', label: 'Registration' },\n { value: 'compliance', label: 'Document Review' },\n];\n\nfunction getCategoryIcon(category: string) {\n switch (category) {\n case 'title_search':\n return <SearchIcon className=\"h-4 w-4\" />;\n case 'lease_review':\n return <FileText className=\"h-4 w-4\" />;\n case 'dispute_resolution':\n return <Gavel className=\"h-4 w-4\" />;\n case 'registration':\n return <ClipboardCheck className=\"h-4 w-4\" />;\n case 'compliance':\n return <BookOpen className=\"h-4 w-4\" />;\n default:\n return <Scale className=\"h-4 w-4\" />;\n }\n}\n\nfunction getStatusStyles(status: string) {\n switch (status) {\n case 'available':\n return 'bg-emerald-100 text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400';\n case 'busy':\n return 'bg-amber-100 text-amber-700 dark:bg-amber-900/30 dark:text-amber-400';\n case 'unavailable':\n return 'bg-red-100 text-red-700 dark:bg-red-900/30 dark:text-red-400';\n default:\n return 'bg-bg-sunken text-text-secondary';\n }\n}\n\nfunction RatingStars({ rating }: { rating: number }) {\n return (\n <div className=\"flex items-center gap-0.5\">\n {Array.from({ length: 5 }).map((_, i) => (\n <Star\n key={i}\n className={cn(\n 'h-3 w-3',\n i < Math.floor(rating) ? 'fill-amber-400 text-amber-400' : 'text-text-secondary/30'\n )}\n />\n ))}\n </div>\n );\n}\n\nfunction LegalServiceCard({ service }: { service: LegalService }) {\n const navigate = useNavigate();\n const [showDocs, setShowDocs] = useState(false);\n\n return (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-5 shadow-sm transition-shadow hover:shadow-md\">\n {/* Header */}\n <div className=\"mb-3 flex items-start justify-between gap-3\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-lg bg-bg-sunken text-text-secondary\">\n {getCategoryIcon(service.category)}\n </div>\n <div>\n <h3 className=\"text-sm font-semibold text-text-primary\">{service.title}</h3>\n <p className=\"text-xs text-text-secondary\">{service.providerName}</p>\n </div>\n </div>\n <span\n className={cn(\n 'inline-flex rounded-full px-2 py-0.5 text-xs font-medium capitalize',\n getStatusStyles(service.status)\n )}\n >\n {service.status}\n </span>\n </div>\n\n {/* Description */}\n <p className=\"mb-3 text-xs text-text-secondary line-clamp-2\">{service.description}</p>\n\n {/* Rating + Duration */}\n <div className=\"mb-3 flex items-center gap-4 text-xs\">\n <div className=\"flex items-center gap-1.5\">\n <RatingStars rating={service.providerRating} />\n <span className=\"font-medium text-text-primary\">{service.providerRating}</span>\n </div>\n <span className=\"flex items-center gap-1 text-text-secondary\">\n <Clock className=\"h-3 w-3\" />\n {service.estimatedDuration}\n </span>\n </div>\n\n {/* Price + Consultation Fee */}\n <div className=\"mb-3 flex items-center justify-between text-xs\">\n <span className=\"font-semibold text-text-primary\">{service.priceRange}</span>\n {service.consultationFee > 0 ? (\n <span className=\"text-text-secondary\">Consultation: ${service.consultationFee}</span>\n ) : (\n <span className=\"text-emerald-600 dark:text-emerald-400\">Free Consultation</span>\n )}\n </div>\n\n {/* Documents Required (collapsible) */}\n {service.documentsRequired.length > 0 && (\n <div className=\"mb-3\">\n <button\n onClick={() => setShowDocs(!showDocs)}\n className=\"text-xs font-medium text-text-secondary hover:text-text-primary\"\n >\n {showDocs ? 'Hide' : 'Show'} required documents ({service.documentsRequired.length})\n </button>\n {showDocs && (\n <ul className=\"mt-1.5 space-y-1\">\n {service.documentsRequired.map((doc, i) => (\n <li key={i} className=\"flex items-center gap-1.5 text-xs text-text-secondary\">\n <span className=\"h-1 w-1 rounded-full bg-muted-foreground\" />\n {doc}\n </li>\n ))}\n </ul>\n )}\n </div>\n )}\n\n {/* Action */}\n <button\n onClick={() => navigate(`/legal/${service.id}`)}\n disabled={service.status === 'unavailable'}\n className={cn(\n 'w-full rounded-md px-4 py-2 text-xs font-medium transition-colors',\n service.status === 'unavailable'\n ? 'cursor-not-allowed bg-bg-sunken text-text-secondary'\n : 'bg-foreground text-background hover:bg-foreground/90'\n )}\n >\n {service.status === 'unavailable' ? 'Currently Unavailable' : 'Book Now'}\n </button>\n </div>\n );\n}\n\nexport function LegalPage() {\n const { data: services } = useLegalServices();\n const [activeCategory, setActiveCategory] = useState<CategoryTab>('all');\n const [search, setSearch] = useState('');\n\n const filtered = useMemo(() => {\n return services.filter((s) => {\n const matchesCategory = activeCategory === 'all' || s.category === activeCategory;\n const matchesSearch =\n !search ||\n s.title.toLowerCase().includes(search.toLowerCase()) ||\n s.providerName.toLowerCase().includes(search.toLowerCase()) ||\n s.description.toLowerCase().includes(search.toLowerCase());\n return matchesCategory && matchesSearch;\n });\n }, [services, activeCategory, search]);\n\n return (\n <PageLayout\n title=\"Legal Services\"\n description=\"Professional legal solutions for property transactions and documentation\"\n purpose=\"Connect with verified property lawyers for the legal work behind every deal — title verification, rent agreements, registration, dispute advisory, and document review. Browse by category, compare ratings and fees, and book a consultation.\"\n actions={\n <span className=\"inline-flex items-center gap-1 text-xs text-emerald-600 dark:text-emerald-400\">\n <Shield className=\"h-3.5 w-3.5\" />\n Legally Compliant\n </span>\n }\n >\n {/* Category Tabs — primary control zone (one EmphasisPanel per page) */}\n <EmphasisPanel className=\"flex flex-wrap items-center gap-2 p-3\">\n {categoryTabs.map((tab) => (\n <button\n key={tab.value}\n onClick={() => setActiveCategory(tab.value)}\n className={cn(\n 'rounded-full px-4 py-1.5 text-sm font-medium transition-colors',\n activeCategory === tab.value\n ? 'bg-foreground text-background'\n : 'border border-border-subtle bg-bg-surface text-text-secondary hover:bg-bg-sunken hover:text-text-primary'\n )}\n >\n {tab.label}\n </button>\n ))}\n </EmphasisPanel>\n\n {/* Search */}\n <FilterBar searchValue={search} onSearchChange={setSearch} searchPlaceholder=\"Search legal services...\" />\n\n <NextSteps\n storageKey=\"housingvista-legal\"\n steps={[\n {\n id: 'verify-title',\n label: 'Verify a property title',\n description: 'The first legal check before any purchase — find a title-search expert.',\n onClick: () => setActiveCategory('title_search'),\n },\n {\n id: 'rent-agreement',\n label: 'Draft or review a rent agreement',\n description: 'Get a lawyer to prepare or vet your lease paperwork.',\n onClick: () => setActiveCategory('lease_review'),\n },\n {\n id: 'registration',\n label: 'Handle property registration',\n description: 'Find help to register a deal with the authorities.',\n onClick: () => setActiveCategory('registration'),\n },\n ]}\n />\n\n {/* Service Cards */}\n {filtered.length > 0 ? (\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {filtered.map((service) => (\n <LegalServiceCard key={service.id} service={service} />\n ))}\n </div>\n ) : (\n <EmptyState\n illustration=\"empty-search\"\n icon={<Scale className=\"h-12 w-12\" />}\n title=\"No legal services found\"\n description=\"Try adjusting your search or category filter.\"\n />\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -8,9 +8,9 @@ import { useMemo as a, useState as o } from "react";
8
8
  import { CheckCircle as s, Clock as c, MapPin as l, MessageCircle as u, Paintbrush as d, Phone as f, Shield as p, ShieldCheck as m, SprayCanIcon as h, Star as g, Trees as _, Wrench as v, Zap as y } from "lucide-react";
9
9
  import { useNavigate as b } from "react-router-dom";
10
10
  import { jsx as x, jsxs as S } from "react/jsx-runtime";
11
- import { EmphasisPanel as C } from "@burdenoff/fe-libs/ui";
11
+ import { EmphasisPanel as C, NextSteps as w } from "@burdenoff/fe-libs/ui";
12
12
  //#region src/housingvista/pages/marketplace/MarketplacePage.tsx
13
- var w = [
13
+ var T = [
14
14
  {
15
15
  value: "all",
16
16
  label: "All"
@@ -40,7 +40,7 @@ var w = [
40
40
  label: "Landscaping"
41
41
  }
42
42
  ];
43
- function T(e) {
43
+ function E(e) {
44
44
  switch (e) {
45
45
  case "repair": return /* @__PURE__ */ x(v, { className: "h-4 w-4" });
46
46
  case "maintenance": return /* @__PURE__ */ x(y, { className: "h-4 w-4" });
@@ -52,13 +52,13 @@ function T(e) {
52
52
  default: return /* @__PURE__ */ x(v, { className: "h-4 w-4" });
53
53
  }
54
54
  }
55
- function E({ rating: t }) {
55
+ function D({ rating: t }) {
56
56
  return /* @__PURE__ */ x("div", {
57
57
  className: "flex items-center gap-0.5",
58
58
  children: Array.from({ length: 5 }).map((n, r) => /* @__PURE__ */ x(g, { className: e("h-3.5 w-3.5", r < Math.floor(t) ? "fill-amber-400 text-amber-400" : r < t ? "fill-amber-400/50 text-amber-400" : "text-text-secondary/30") }, r))
59
59
  });
60
60
  }
61
- function D({ service: e }) {
61
+ function O({ service: e }) {
62
62
  let t = b();
63
63
  return /* @__PURE__ */ S("div", {
64
64
  className: "rounded-lg border border-border-subtle bg-bg-surface p-5 shadow-sm transition-shadow hover:shadow-md",
@@ -87,13 +87,13 @@ function D({ service: e }) {
87
87
  })]
88
88
  }), /* @__PURE__ */ S("span", {
89
89
  className: "inline-flex items-center gap-1 rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary capitalize",
90
- children: [T(e.category), e.category.replace("_", " ")]
90
+ children: [E(e.category), e.category.replace("_", " ")]
91
91
  })]
92
92
  }),
93
93
  /* @__PURE__ */ S("div", {
94
94
  className: "mb-3 flex items-center gap-2",
95
95
  children: [
96
- /* @__PURE__ */ x(E, { rating: e.rating }),
96
+ /* @__PURE__ */ x(D, { rating: e.rating }),
97
97
  /* @__PURE__ */ x("span", {
98
98
  className: "text-xs font-medium text-text-primary",
99
99
  children: e.rating
@@ -151,7 +151,7 @@ function D({ service: e }) {
151
151
  ]
152
152
  });
153
153
  }
154
- function O() {
154
+ function k() {
155
155
  let { data: s } = i(), [c, l] = o(""), [u, d] = o("all"), f = a(() => s.filter((e) => {
156
156
  let t = !c || e.name.toLowerCase().includes(c.toLowerCase()) || e.providerName.toLowerCase().includes(c.toLowerCase()) || e.description.toLowerCase().includes(c.toLowerCase()), n = u === "all" || e.category === u;
157
157
  return t && n;
@@ -167,7 +167,7 @@ function O() {
167
167
  children: [
168
168
  /* @__PURE__ */ x(C, {
169
169
  className: "flex flex-wrap items-center gap-2 p-3",
170
- children: w.map((t) => /* @__PURE__ */ x("button", {
170
+ children: T.map((t) => /* @__PURE__ */ x("button", {
171
171
  onClick: () => d(t.value),
172
172
  className: e("rounded-full px-4 py-1.5 text-sm font-medium transition-colors", u === t.value ? "bg-foreground text-background" : "border border-border-subtle bg-bg-surface text-text-secondary hover:bg-bg-sunken hover:text-text-primary"),
173
173
  children: t.label
@@ -178,6 +178,31 @@ function O() {
178
178
  onSearchChange: l,
179
179
  searchPlaceholder: "Search services, providers..."
180
180
  }),
181
+ /* @__PURE__ */ x(w, {
182
+ storageKey: "housingvista-marketplace",
183
+ steps: [
184
+ {
185
+ id: "book-repair",
186
+ label: "Fix something now",
187
+ description: "Find a plumber or repair pro for an urgent issue.",
188
+ onClick: () => d("repair")
189
+ },
190
+ {
191
+ id: "book-cleaning",
192
+ label: "Schedule a cleaning",
193
+ description: "Get a property move-in or turnover ready.",
194
+ onClick: () => d("cleaning")
195
+ },
196
+ {
197
+ id: "see-featured",
198
+ label: "Browse all providers",
199
+ description: "Clear filters to compare every vetted professional.",
200
+ onClick: () => {
201
+ d("all"), l("");
202
+ }
203
+ }
204
+ ]
205
+ }),
181
206
  /* @__PURE__ */ S("p", {
182
207
  className: "text-sm text-text-secondary",
183
208
  children: [
@@ -189,7 +214,7 @@ function O() {
189
214
  }),
190
215
  f.length > 0 ? /* @__PURE__ */ x("div", {
191
216
  className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-3",
192
- children: f.map((e) => /* @__PURE__ */ x(D, { service: e }, e.id))
217
+ children: f.map((e) => /* @__PURE__ */ x(O, { service: e }, e.id))
193
218
  }) : /* @__PURE__ */ x(n, {
194
219
  illustration: "empty-search",
195
220
  title: "No services found",
@@ -199,6 +224,6 @@ function O() {
199
224
  });
200
225
  }
201
226
  //#endregion
202
- export { O as MarketplacePage };
227
+ export { k as MarketplacePage };
203
228
 
204
229
  //# sourceMappingURL=MarketplacePage.js.map