@burdenoff/microfe-housingvista 2026.624.2 → 2026.625.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 (59) hide show
  1. package/dist/housingvista/components/ChartCard.js +11 -9
  2. package/dist/housingvista/components/ChartCard.js.map +1 -1
  3. package/dist/housingvista/components/DataTable.js +63 -60
  4. package/dist/housingvista/components/DataTable.js.map +1 -1
  5. package/dist/housingvista/components/EmptyState.js +16 -9
  6. package/dist/housingvista/components/EmptyState.js.map +1 -1
  7. package/dist/housingvista/components/PageLayout.js +21 -14
  8. package/dist/housingvista/components/PageLayout.js.map +1 -1
  9. package/dist/housingvista/components/PropertyCard.js +2 -2
  10. package/dist/housingvista/components/PropertyCard.js.map +1 -1
  11. package/dist/housingvista/components/StatCard.js +20 -17
  12. package/dist/housingvista/components/StatCard.js.map +1 -1
  13. package/dist/housingvista/components/StatusBadge.js +1 -1
  14. package/dist/housingvista/components/StatusBadge.js.map +1 -1
  15. package/dist/housingvista/pages/HomePage.js +101 -58
  16. package/dist/housingvista/pages/HomePage.js.map +1 -1
  17. package/dist/housingvista/pages/amc/AMCManagementPage.js +59 -48
  18. package/dist/housingvista/pages/amc/AMCManagementPage.js.map +1 -1
  19. package/dist/housingvista/pages/analytics/AnalyticsPage.js +113 -90
  20. package/dist/housingvista/pages/analytics/AnalyticsPage.js.map +1 -1
  21. package/dist/housingvista/pages/assets/AssetManagementPage.js +66 -60
  22. package/dist/housingvista/pages/assets/AssetManagementPage.js.map +1 -1
  23. package/dist/housingvista/pages/chat/ChatPage.js +60 -58
  24. package/dist/housingvista/pages/chat/ChatPage.js.map +1 -1
  25. package/dist/housingvista/pages/finance/HomeLoansPage.js +23 -20
  26. package/dist/housingvista/pages/finance/HomeLoansPage.js.map +1 -1
  27. package/dist/housingvista/pages/investments/InvestmentDetailPage.js +114 -81
  28. package/dist/housingvista/pages/investments/InvestmentDetailPage.js.map +1 -1
  29. package/dist/housingvista/pages/investments/InvestmentsPage.js +65 -59
  30. package/dist/housingvista/pages/investments/InvestmentsPage.js.map +1 -1
  31. package/dist/housingvista/pages/legal/LegalPage.js +17 -14
  32. package/dist/housingvista/pages/legal/LegalPage.js.map +1 -1
  33. package/dist/housingvista/pages/market/AreaInsightsPage.js +13 -10
  34. package/dist/housingvista/pages/market/AreaInsightsPage.js.map +1 -1
  35. package/dist/housingvista/pages/market/MarketAnalyticsPage.js +155 -123
  36. package/dist/housingvista/pages/market/MarketAnalyticsPage.js.map +1 -1
  37. package/dist/housingvista/pages/marketplace/MarketplacePage.js +15 -12
  38. package/dist/housingvista/pages/marketplace/MarketplacePage.js.map +1 -1
  39. package/dist/housingvista/pages/notifications/NotificationsPage.js +24 -21
  40. package/dist/housingvista/pages/notifications/NotificationsPage.js.map +1 -1
  41. package/dist/housingvista/pages/properties/AddPropertyPage.js +73 -71
  42. package/dist/housingvista/pages/properties/AddPropertyPage.js.map +1 -1
  43. package/dist/housingvista/pages/properties/PropertiesPage.js +141 -135
  44. package/dist/housingvista/pages/properties/PropertiesPage.js.map +1 -1
  45. package/dist/housingvista/pages/properties/PropertyDetailPage.js +192 -154
  46. package/dist/housingvista/pages/properties/PropertyDetailPage.js.map +1 -1
  47. package/dist/housingvista/pages/rental/RentalManagementPage.js +185 -160
  48. package/dist/housingvista/pages/rental/RentalManagementPage.js.map +1 -1
  49. package/dist/housingvista/pages/settings/ProfilePage.js +51 -49
  50. package/dist/housingvista/pages/settings/ProfilePage.js.map +1 -1
  51. package/dist/housingvista/pages/settings/SettingsPage.js +56 -54
  52. package/dist/housingvista/pages/settings/SettingsPage.js.map +1 -1
  53. package/dist/housingvista/pages/transactions/TransactionDetailPage.js +183 -142
  54. package/dist/housingvista/pages/transactions/TransactionDetailPage.js.map +1 -1
  55. package/dist/housingvista/pages/transactions/TransactionsPage.js +90 -84
  56. package/dist/housingvista/pages/transactions/TransactionsPage.js.map +1 -1
  57. package/dist/housingvista/pages/verification/VerificationPage.js +49 -42
  58. package/dist/housingvista/pages/verification/VerificationPage.js.map +1 -1
  59. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"StatCard.js","names":[],"sources":["../../../src/housingvista/components/StatCard.tsx"],"sourcesContent":["import type { FC, ReactNode } from 'react';\nimport { TrendingUp, TrendingDown, Minus } from 'lucide-react';\nimport { cn } from '../utils/helpers';\nimport { formatNumber, formatCurrency } from '../utils/helpers';\n\ninterface StatCardProps {\n label: string;\n value: number | string;\n previousValue?: number;\n unit?: string;\n prefix?: string;\n icon?: ReactNode;\n trend?: 'up' | 'down' | 'stable';\n change?: number;\n className?: string;\n}\n\nexport const StatCard: FC<StatCardProps> = ({\n label,\n value,\n previousValue,\n unit,\n prefix,\n icon,\n trend,\n change,\n className,\n}) => {\n const numericValue = typeof value === 'number' ? value : 0;\n const computedChange =\n change ?? (previousValue ? Math.round(((numericValue - previousValue) / previousValue) * 100) : 0);\n const computedTrend = trend ?? (computedChange > 0 ? 'up' : computedChange < 0 ? 'down' : 'stable');\n\n const displayValue =\n typeof value === 'string'\n ? value\n : prefix === '$'\n ? formatCurrency(value)\n : `${formatNumber(value)}${unit ? ` ${unit}` : ''}`;\n\n return (\n <div className={cn('rounded-lg border border-border-subtle bg-bg-surface p-4 shadow-sm', className)}>\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm font-medium text-text-secondary\">{label}</span>\n {icon && <span className=\"text-text-secondary\">{icon}</span>}\n </div>\n <div className=\"mt-2 flex items-baseline gap-2\">\n <span className=\"text-2xl font-bold text-text-primary\">{displayValue}</span>\n </div>\n {computedChange !== 0 && (\n <div className=\"mt-2 flex items-center gap-1 text-xs\">\n {computedTrend === 'up' && <TrendingUp className=\"h-3 w-3 text-emerald-600 dark:text-emerald-400\" />}\n {computedTrend === 'down' && <TrendingDown className=\"h-3 w-3 text-red-600 dark:text-red-400\" />}\n {computedTrend === 'stable' && <Minus className=\"h-3 w-3 text-text-secondary\" />}\n <span\n className={cn(\n 'font-medium',\n computedTrend === 'up' && 'text-emerald-600 dark:text-emerald-400',\n computedTrend === 'down' && 'text-red-600 dark:text-red-400',\n computedTrend === 'stable' && 'text-text-secondary'\n )}\n >\n {computedChange > 0 ? '+' : ''}\n {computedChange}%\n </span>\n <span className=\"text-text-secondary\">vs last period</span>\n </div>\n )}\n </div>\n );\n};\n"],"mappings":";;;;AAiBA,IAAa,KAA+B,EAC1C,UACA,UACA,kBACA,SACA,WACA,SACA,UACA,WACA,mBACI;CAEJ,IAAM,IACJ,MAAW,IAAgB,KAAK,QAFb,OAAO,KAAU,WAAW,IAAQ,KAEA,KAAiB,IAAiB,IAAI,GAAG,IAC5F,IAAgB,MAAU,IAAiB,IAAI,OAAO,IAAiB,IAAI,SAAS,WAEpF,IACJ,OAAO,KAAU,WACb,IACA,MAAW,MACT,EAAe,EAAM,GACrB,GAAG,EAAa,EAAM,GAAG,IAAO,IAAI,MAAS;AAErD,QACE,kBAAC,OAAD;EAAK,WAAW,EAAG,sEAAsE,EAAU;YAAnG;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,QAAD;KAAM,WAAU;eAA2C;KAAa,CAAA,EACvE,KAAQ,kBAAC,QAAD;KAAM,WAAU;eAAuB;KAAY,CAAA,CACxD;;GACN,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,QAAD;KAAM,WAAU;eAAwC;KAAoB,CAAA;IACxE,CAAA;GACL,MAAmB,KAClB,kBAAC,OAAD;IAAK,WAAU;cAAf;KACG,MAAkB,QAAQ,kBAAC,GAAD,EAAY,WAAU,kDAAmD,CAAA;KACnG,MAAkB,UAAU,kBAAC,GAAD,EAAc,WAAU,0CAA2C,CAAA;KAC/F,MAAkB,YAAY,kBAAC,GAAD,EAAO,WAAU,+BAAgC,CAAA;KAChF,kBAAC,QAAD;MACE,WAAW,EACT,eACA,MAAkB,QAAQ,0CAC1B,MAAkB,UAAU,kCAC5B,MAAkB,YAAY,sBAC/B;gBANH;OAQG,IAAiB,IAAI,MAAM;OAC3B;OAAe;OACX;;KACP,kBAAC,QAAD;MAAM,WAAU;gBAAsB;MAAqB,CAAA;KACvD;;GAEJ"}
1
+ {"version":3,"file":"StatCard.js","names":[],"sources":["../../../src/housingvista/components/StatCard.tsx"],"sourcesContent":["import type { FC, ReactNode } from 'react';\nimport { TrendingUp, TrendingDown, Minus } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { cn } from '../utils/helpers';\nimport { formatNumber, formatCurrency } from '../utils/helpers';\n\ninterface StatCardProps {\n label: string;\n value: number | string;\n previousValue?: number;\n unit?: string;\n prefix?: string;\n icon?: ReactNode;\n trend?: 'up' | 'down' | 'stable';\n change?: number;\n className?: string;\n /** Render the featured hero metric with a glass treatment + accent glow. */\n featured?: boolean;\n}\n\nexport const StatCard: FC<StatCardProps> = ({\n label,\n value,\n previousValue,\n unit,\n prefix,\n icon,\n trend,\n change,\n className,\n featured = false,\n}) => {\n const numericValue = typeof value === 'number' ? value : 0;\n const computedChange =\n change ?? (previousValue ? Math.round(((numericValue - previousValue) / previousValue) * 100) : 0);\n const computedTrend = trend ?? (computedChange > 0 ? 'up' : computedChange < 0 ? 'down' : 'stable');\n\n const displayValue =\n typeof value === 'string'\n ? value\n : prefix === '$'\n ? formatCurrency(value)\n : `${formatNumber(value)}${unit ? ` ${unit}` : ''}`;\n\n return (\n <GlassCard\n treatment={featured ? 'glass' : 'metric'}\n glow={featured}\n className={cn('border-border-seam p-4', className)}\n >\n <div className=\"flex items-center justify-between\">\n <span className=\"text-sm font-medium text-text-secondary\">{label}</span>\n {icon && <span className=\"text-text-secondary\">{icon}</span>}\n </div>\n <div className=\"mt-2 flex items-baseline gap-2\">\n <span className=\"text-2xl font-bold tabular-nums text-text-primary\">{displayValue}</span>\n </div>\n {computedChange !== 0 && (\n <div className=\"mt-2 flex items-center gap-1 text-xs\">\n {computedTrend === 'up' && <TrendingUp className=\"h-3 w-3 text-emerald-600 dark:text-emerald-400\" />}\n {computedTrend === 'down' && <TrendingDown className=\"h-3 w-3 text-red-600 dark:text-red-400\" />}\n {computedTrend === 'stable' && <Minus className=\"h-3 w-3 text-text-secondary\" />}\n <span\n className={cn(\n 'font-medium tabular-nums',\n computedTrend === 'up' && 'text-emerald-600 dark:text-emerald-400',\n computedTrend === 'down' && 'text-red-600 dark:text-red-400',\n computedTrend === 'stable' && 'text-text-secondary'\n )}\n >\n {computedChange > 0 ? '+' : ''}\n {computedChange}%\n </span>\n <span className=\"text-text-secondary\">vs last period</span>\n </div>\n )}\n </GlassCard>\n );\n};\n"],"mappings":";;;;;AAoBA,IAAa,KAA+B,EAC1C,UACA,UACA,kBACA,SACA,WACA,SACA,UACA,WACA,cACA,cAAW,SACP;CAEJ,IAAM,IACJ,MAAW,IAAgB,KAAK,QAFb,OAAO,KAAU,WAAW,IAAQ,KAEA,KAAiB,IAAiB,IAAI,GAAG,IAC5F,IAAgB,MAAU,IAAiB,IAAI,OAAO,IAAiB,IAAI,SAAS,WAEpF,IACJ,OAAO,KAAU,WACb,IACA,MAAW,MACT,EAAe,EAAM,GACrB,GAAG,EAAa,EAAM,GAAG,IAAO,IAAI,MAAS;AAErD,QACE,kBAAC,GAAD;EACE,WAAW,IAAW,UAAU;EAChC,MAAM;EACN,WAAW,EAAG,0BAA0B,EAAU;YAHpD;GAKE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,QAAD;KAAM,WAAU;eAA2C;KAAa,CAAA,EACvE,KAAQ,kBAAC,QAAD;KAAM,WAAU;eAAuB;KAAY,CAAA,CACxD;;GACN,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,QAAD;KAAM,WAAU;eAAqD;KAAoB,CAAA;IACrF,CAAA;GACL,MAAmB,KAClB,kBAAC,OAAD;IAAK,WAAU;cAAf;KACG,MAAkB,QAAQ,kBAAC,GAAD,EAAY,WAAU,kDAAmD,CAAA;KACnG,MAAkB,UAAU,kBAAC,GAAD,EAAc,WAAU,0CAA2C,CAAA;KAC/F,MAAkB,YAAY,kBAAC,GAAD,EAAO,WAAU,+BAAgC,CAAA;KAChF,kBAAC,QAAD;MACE,WAAW,EACT,4BACA,MAAkB,QAAQ,0CAC1B,MAAkB,UAAU,kCAC5B,MAAkB,YAAY,sBAC/B;gBANH;OAQG,IAAiB,IAAI,MAAM;OAC3B;OAAe;OACX;;KACP,kBAAC,QAAD;MAAM,WAAU;gBAAsB;MAAqB,CAAA;KACvD;;GAEE"}
@@ -17,7 +17,7 @@ var r = {
17
17
  muted: "bg-muted-foreground"
18
18
  }, a = ({ label: a, variant: o = "default", dot: s = !1, className: c }) => /* @__PURE__ */ n("span", {
19
19
  className: e("inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium", r[o], c),
20
- children: [s && /* @__PURE__ */ t("span", { className: e("h-1.5 w-1.5 rounded-full", i[o]) }), a]
20
+ children: [s && /* @__PURE__ */ t("span", { className: e("h-1.5 w-1.5 rounded-full", i[o], o === "success" && "motion-safe:animate-vc-glow-pulse") }), a]
21
21
  });
22
22
  //#endregion
23
23
  export { a as StatusBadge };
@@ -1 +1 @@
1
- {"version":3,"file":"StatusBadge.js","names":[],"sources":["../../../src/housingvista/components/StatusBadge.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { cn } from '../utils/helpers';\n\ntype BadgeVariant = 'success' | 'warning' | 'error' | 'info' | 'default' | 'muted';\n\ninterface StatusBadgeProps {\n label: string;\n variant?: BadgeVariant;\n dot?: boolean;\n className?: string;\n}\n\nconst variantStyles: Record<BadgeVariant, string> = {\n success: 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-400',\n warning: 'bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-400',\n error: 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400',\n info: 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400',\n default: 'bg-action-primary-bg/10 text-primary',\n muted: 'bg-bg-sunken text-text-secondary',\n};\n\nconst dotStyles: Record<BadgeVariant, string> = {\n success: 'bg-emerald-500',\n warning: 'bg-amber-500',\n error: 'bg-red-500',\n info: 'bg-blue-500',\n default: 'bg-action-primary-bg',\n muted: 'bg-muted-foreground',\n};\n\nexport const StatusBadge: FC<StatusBadgeProps> = ({ label, variant = 'default', dot = false, className }) => {\n return (\n <span\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium',\n variantStyles[variant],\n className\n )}\n >\n {dot && <span className={cn('h-1.5 w-1.5 rounded-full', dotStyles[variant])} />}\n {label}\n </span>\n );\n};\n"],"mappings":";;;AAYA,IAAM,IAA8C;CAClD,SAAS;CACT,SAAS;CACT,OAAO;CACP,MAAM;CACN,SAAS;CACT,OAAO;CACR,EAEK,IAA0C;CAC9C,SAAS;CACT,SAAS;CACT,OAAO;CACP,MAAM;CACN,SAAS;CACT,OAAO;CACR,EAEY,KAAqC,EAAE,UAAO,aAAU,WAAW,SAAM,IAAO,mBAEzF,kBAAC,QAAD;CACE,WAAW,EACT,mFACA,EAAc,IACd,EACD;WALH,CAOG,KAAO,kBAAC,QAAD,EAAM,WAAW,EAAG,4BAA4B,EAAU,GAAS,EAAI,CAAA,EAC9E,EACI"}
1
+ {"version":3,"file":"StatusBadge.js","names":[],"sources":["../../../src/housingvista/components/StatusBadge.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { cn } from '../utils/helpers';\n\ntype BadgeVariant = 'success' | 'warning' | 'error' | 'info' | 'default' | 'muted';\n\ninterface StatusBadgeProps {\n label: string;\n variant?: BadgeVariant;\n dot?: boolean;\n className?: string;\n}\n\nconst variantStyles: Record<BadgeVariant, string> = {\n success: 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-400',\n warning: 'bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-400',\n error: 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400',\n info: 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400',\n default: 'bg-action-primary-bg/10 text-primary',\n muted: 'bg-bg-sunken text-text-secondary',\n};\n\nconst dotStyles: Record<BadgeVariant, string> = {\n success: 'bg-emerald-500',\n warning: 'bg-amber-500',\n error: 'bg-red-500',\n info: 'bg-blue-500',\n default: 'bg-action-primary-bg',\n muted: 'bg-muted-foreground',\n};\n\nexport const StatusBadge: FC<StatusBadgeProps> = ({ label, variant = 'default', dot = false, className }) => {\n return (\n <span\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium',\n variantStyles[variant],\n className\n )}\n >\n {dot && (\n <span\n className={cn(\n 'h-1.5 w-1.5 rounded-full',\n dotStyles[variant],\n variant === 'success' && 'motion-safe:animate-vc-glow-pulse'\n )}\n />\n )}\n {label}\n </span>\n );\n};\n"],"mappings":";;;AAYA,IAAM,IAA8C;CAClD,SAAS;CACT,SAAS;CACT,OAAO;CACP,MAAM;CACN,SAAS;CACT,OAAO;CACR,EAEK,IAA0C;CAC9C,SAAS;CACT,SAAS;CACT,OAAO;CACP,MAAM;CACN,SAAS;CACT,OAAO;CACR,EAEY,KAAqC,EAAE,UAAO,aAAU,WAAW,SAAM,IAAO,mBAEzF,kBAAC,QAAD;CACE,WAAW,EACT,mFACA,EAAc,IACd,EACD;WALH,CAOG,KACC,kBAAC,QAAD,EACE,WAAW,EACT,4BACA,EAAU,IACV,MAAY,aAAa,oCAC1B,EACD,CAAA,EAEH,EACI"}
@@ -8,8 +8,9 @@ import { ArrowRight as l, BarChart3 as u, Building as d, DollarSign as f, Eye as
8
8
  import { useNavigate as v } from "react-router-dom";
9
9
  import { jsx as y, jsxs as b } from "react/jsx-runtime";
10
10
  import { useI18n as x } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
11
+ import { AuroraBackground as S, Button as C, EmphasisPanel as w, GlassCard as T, GradientText as E, IllustratedEmptyState as D, NextSteps as O, PagePurpose as k } from "@burdenoff/fe-libs/ui";
11
12
  //#region src/housingvista/pages/HomePage.tsx
12
- var S = {
13
+ var A = {
13
14
  property_listed: h,
14
15
  transaction_update: m,
15
16
  payment_received: f,
@@ -18,7 +19,7 @@ var S = {
18
19
  document_uploaded: m,
19
20
  offer_received: _,
20
21
  lease_signed: m
21
- }, C = {
22
+ }, j = {
22
23
  property_listed: "text-purple-600 dark:text-purple-400",
23
24
  transaction_update: "text-blue-600 dark:text-blue-400",
24
25
  payment_received: "text-emerald-600 dark:text-emerald-400",
@@ -27,83 +28,111 @@ var S = {
27
28
  document_uploaded: "text-indigo-600 dark:text-indigo-400",
28
29
  offer_received: "text-emerald-600 dark:text-emerald-400",
29
30
  lease_signed: "text-teal-600 dark:text-teal-400"
30
- }, w = () => {
31
- let h = v(), { t: w } = x(), { data: T } = a(), { data: E } = s(), { data: D } = o(), O = (e, t) => {
32
- let n = w(e);
31
+ }, M = () => {
32
+ let h = v(), { t: M } = x(), { data: N } = a(), { data: P } = s(), { data: F } = o(), I = (e, t) => {
33
+ let n = M(e);
33
34
  return n === e ? t : n;
34
- }, k = [
35
+ }, L = [
35
36
  {
36
- title: O("housingvista.home.quickActions.addProperty.title", "Add Property"),
37
- description: O("housingvista.home.quickActions.addProperty.description", "List a new property"),
37
+ title: I("housingvista.home.quickActions.addProperty.title", "Add Property"),
38
+ description: I("housingvista.home.quickActions.addProperty.description", "List a new property"),
38
39
  icon: g,
39
40
  path: "properties/new"
40
41
  },
41
42
  {
42
- title: O("housingvista.home.quickActions.viewAnalytics.title", "View Analytics"),
43
- description: O("housingvista.home.quickActions.viewAnalytics.description", "Check performance metrics"),
43
+ title: I("housingvista.home.quickActions.viewAnalytics.title", "View Analytics"),
44
+ description: I("housingvista.home.quickActions.viewAnalytics.description", "Check performance metrics"),
44
45
  icon: u,
45
46
  path: "analytics"
46
47
  },
47
48
  {
48
- title: O("housingvista.home.quickActions.manageTransactions.title", "Manage Transactions"),
49
- description: O("housingvista.home.quickActions.manageTransactions.description", "Handle ongoing deals"),
49
+ title: I("housingvista.home.quickActions.manageTransactions.title", "Manage Transactions"),
50
+ description: I("housingvista.home.quickActions.manageTransactions.description", "Handle ongoing deals"),
50
51
  icon: m,
51
52
  path: "transactions"
52
53
  },
53
54
  {
54
- title: O("housingvista.home.quickActions.browseProperties.title", "Browse Properties"),
55
- description: O("housingvista.home.quickActions.browseProperties.description", "Explore listings"),
55
+ title: I("housingvista.home.quickActions.browseProperties.title", "Browse Properties"),
56
+ description: I("housingvista.home.quickActions.browseProperties.description", "Explore listings"),
56
57
  icon: d,
57
58
  path: "properties"
58
59
  }
59
- ], A = c(() => D.slice(0, 6), [D]);
60
+ ], R = c(() => F.slice(0, 6), [F]);
60
61
  return /* @__PURE__ */ b("div", {
61
62
  className: "space-y-6 p-6",
62
63
  children: [
63
64
  /* @__PURE__ */ b("div", {
64
- className: "flex flex-col lg:flex-row lg:items-center lg:justify-between gap-4 rounded-xl border border-border-subtle bg-bg-surface p-6 shadow-sm",
65
- children: [/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("h1", {
66
- className: "text-3xl font-bold text-text-primary",
67
- children: O("housingvista.home.header.title", "Welcome back!")
68
- }), /* @__PURE__ */ y("p", {
69
- className: "mt-1 text-text-secondary",
70
- children: O("housingvista.home.header.description", "Here's what's happening with your real estate portfolio today.")
71
- })] }), /* @__PURE__ */ y("div", {
72
- className: "flex items-center gap-3",
73
- children: /* @__PURE__ */ b("button", {
65
+ className: "relative overflow-hidden rounded-card border border-border-seam bg-gloss-card p-6 shadow-pop",
66
+ children: [/* @__PURE__ */ y(S, { intensity: "subtle" }), /* @__PURE__ */ b("div", {
67
+ className: "relative flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between",
68
+ children: [/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("h1", {
69
+ className: "text-3xl font-bold text-text-primary",
70
+ children: /* @__PURE__ */ y(E, { children: I("housingvista.home.header.title", "Welcome back!") })
71
+ }), /* @__PURE__ */ y("p", {
72
+ className: "mt-1 text-text-secondary",
73
+ children: I("housingvista.home.header.description", "Here's what's happening with your real estate portfolio today.")
74
+ })] }), /* @__PURE__ */ b(C, {
74
75
  onClick: () => h("properties/new"),
75
- 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",
76
- children: [/* @__PURE__ */ y(g, { className: "h-4 w-4" }), O("housingvista.home.header.quickAdd", "Quick Add")]
77
- })
76
+ className: "gap-2 self-start lg:self-auto",
77
+ children: [/* @__PURE__ */ y(g, { className: "h-4 w-4" }), I("housingvista.home.header.quickAdd", "Quick Add")]
78
+ })]
78
79
  })]
79
80
  }),
81
+ /* @__PURE__ */ y(k, {
82
+ className: "max-w-3xl",
83
+ children: I("housingvista.home.purpose", "Your real-estate command center. See your portfolio at a glance, jump to the things you do most, and pick up where you left off — from listing a property to tracking deals and analytics.")
84
+ }),
85
+ /* @__PURE__ */ y(O, {
86
+ storageKey: "housingvista-home",
87
+ steps: [
88
+ {
89
+ id: "add-property",
90
+ label: I("housingvista.home.nextSteps.addProperty", "List your first property"),
91
+ description: I("housingvista.home.nextSteps.addPropertyDesc", "Create a market-ready listing in a few guided steps."),
92
+ onClick: () => h("properties/new")
93
+ },
94
+ {
95
+ id: "browse",
96
+ label: I("housingvista.home.nextSteps.browse", "Browse properties"),
97
+ description: I("housingvista.home.nextSteps.browseDesc", "Explore listings and open one for full details."),
98
+ onClick: () => h("properties")
99
+ },
100
+ {
101
+ id: "analytics",
102
+ label: I("housingvista.home.nextSteps.analytics", "Review your analytics"),
103
+ description: I("housingvista.home.nextSteps.analyticsDesc", "Check portfolio performance and market insights."),
104
+ onClick: () => h("analytics")
105
+ }
106
+ ]
107
+ }),
80
108
  /* @__PURE__ */ b("div", {
81
109
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
82
110
  children: [
83
111
  /* @__PURE__ */ y(r, {
84
- label: O("housingvista.home.stats.totalProperties", "Total Properties"),
85
- value: T.totalProperties,
112
+ label: I("housingvista.home.stats.totalProperties", "Total Properties"),
113
+ value: N.totalProperties,
86
114
  icon: /* @__PURE__ */ y(d, { className: "h-5 w-5" }),
87
115
  trend: "up",
88
- change: 12
116
+ change: 12,
117
+ featured: !0
89
118
  }),
90
119
  /* @__PURE__ */ y(r, {
91
- label: O("housingvista.home.stats.activeListings", "Active Listings"),
92
- value: T.activeTransactions,
120
+ label: I("housingvista.home.stats.activeListings", "Active Listings"),
121
+ value: N.activeTransactions,
93
122
  icon: /* @__PURE__ */ y(_, { className: "h-5 w-5" }),
94
123
  trend: "up",
95
124
  change: 8
96
125
  }),
97
126
  /* @__PURE__ */ y(r, {
98
- label: O("housingvista.home.stats.totalViews", "Total Views"),
127
+ label: I("housingvista.home.stats.totalViews", "Total Views"),
99
128
  value: t(12540),
100
129
  icon: /* @__PURE__ */ y(p, { className: "h-5 w-5" }),
101
130
  trend: "down",
102
131
  change: -2
103
132
  }),
104
133
  /* @__PURE__ */ y(r, {
105
- label: O("housingvista.home.stats.monthlyRevenue", "Monthly Revenue"),
106
- value: T.monthlyRevenue,
134
+ label: I("housingvista.home.stats.monthlyRevenue", "Monthly Revenue"),
135
+ value: N.monthlyRevenue,
107
136
  prefix: "$",
108
137
  icon: /* @__PURE__ */ y(f, { className: "h-5 w-5" }),
109
138
  trend: "up",
@@ -115,21 +144,22 @@ var S = {
115
144
  className: "grid grid-cols-1 gap-6 lg:grid-cols-3",
116
145
  children: [/* @__PURE__ */ y("div", {
117
146
  className: "lg:col-span-1",
118
- children: /* @__PURE__ */ b("div", {
119
- className: "rounded-lg border border-border-subtle bg-bg-surface shadow-sm",
147
+ children: /* @__PURE__ */ b(T, {
148
+ treatment: "plain",
149
+ className: "border-border-seam",
120
150
  children: [/* @__PURE__ */ y("div", {
121
- className: "border-b border-border-subtle px-5 py-4",
151
+ className: "border-b border-border-seam px-5 py-4",
122
152
  children: /* @__PURE__ */ y("h2", {
123
153
  className: "text-base font-semibold text-text-primary",
124
- children: O("housingvista.home.quickActions.title", "Quick Actions")
154
+ children: I("housingvista.home.quickActions.title", "Quick Actions")
125
155
  })
126
156
  }), /* @__PURE__ */ y("div", {
127
157
  className: "space-y-2 p-4",
128
- children: k.map((e) => {
158
+ children: L.map((e) => {
129
159
  let t = e.icon;
130
160
  return /* @__PURE__ */ b("button", {
131
161
  onClick: () => h(e.path),
132
- className: "flex w-full items-center gap-3 rounded-lg border border-border-subtle p-3 text-left transition-colors hover:bg-bg-sunken/50",
162
+ className: "flex min-h-[44px] w-full items-center gap-3 rounded-lg border border-border-seam p-3 text-left transition-colors hover:bg-bg-sunken/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]",
133
163
  children: [/* @__PURE__ */ y("div", {
134
164
  className: "rounded-lg bg-action-primary-bg/10 p-2",
135
165
  children: /* @__PURE__ */ y(t, { className: "h-5 w-5 text-text-primary" })
@@ -149,21 +179,21 @@ var S = {
149
179
  })
150
180
  }), /* @__PURE__ */ y("div", {
151
181
  className: "lg:col-span-2",
152
- children: /* @__PURE__ */ b("div", {
153
- className: "rounded-lg border border-border-subtle bg-bg-surface shadow-sm",
182
+ children: /* @__PURE__ */ b(w, {
183
+ className: "p-0",
154
184
  children: [/* @__PURE__ */ y("div", {
155
- className: "border-b border-border-subtle px-5 py-4",
185
+ className: "border-b border-border-seam px-5 py-4",
156
186
  children: /* @__PURE__ */ y("h2", {
157
187
  className: "text-base font-semibold text-text-primary",
158
- children: O("housingvista.home.recentActivity.title", "Recent Activity")
188
+ children: I("housingvista.home.recentActivity.title", "Recent Activity")
159
189
  })
160
190
  }), /* @__PURE__ */ y("div", {
161
191
  className: "space-y-2 p-4",
162
- children: E.slice(0, 6).map((t) => /* @__PURE__ */ b("div", {
163
- className: "flex items-start gap-4 rounded-lg border border-border-subtle p-4 transition-colors hover:bg-bg-sunken/50",
192
+ children: P.slice(0, 6).map((t) => /* @__PURE__ */ b("div", {
193
+ className: "flex items-start gap-4 rounded-lg border border-border-seam bg-bg-surface/60 p-4 transition-colors hover:bg-bg-sunken/50",
164
194
  children: [/* @__PURE__ */ y("div", {
165
195
  className: "rounded-lg bg-bg-sunken p-2",
166
- children: /* @__PURE__ */ y(S[t.type] ?? p, { className: e("h-5 w-5", C[t.type] ?? "text-text-secondary") })
196
+ children: /* @__PURE__ */ y(A[t.type] ?? p, { className: e("h-5 w-5", j[t.type] ?? "text-text-secondary") })
167
197
  }), /* @__PURE__ */ b("div", {
168
198
  className: "flex-1 min-w-0",
169
199
  children: [
@@ -186,21 +216,34 @@ var S = {
186
216
  })
187
217
  })]
188
218
  }),
189
- /* @__PURE__ */ b("div", {
190
- className: "rounded-lg border border-border-subtle bg-bg-surface shadow-sm",
219
+ /* @__PURE__ */ b(T, {
220
+ treatment: "plain",
221
+ className: "border-border-seam",
191
222
  children: [/* @__PURE__ */ b("div", {
192
- className: "flex items-center justify-between border-b border-border-subtle px-5 py-4",
223
+ className: "flex items-center justify-between border-b border-border-seam px-5 py-4",
193
224
  children: [/* @__PURE__ */ y("h2", {
194
225
  className: "text-base font-semibold text-text-primary",
195
- children: O("housingvista.home.recentProperties.title", "Recent Properties")
226
+ children: I("housingvista.home.recentProperties.title", "Recent Properties")
196
227
  }), /* @__PURE__ */ b("button", {
197
228
  onClick: () => h("properties"),
198
- className: "inline-flex items-center gap-1 text-sm font-medium text-text-secondary transition-colors hover:text-text-primary",
199
- children: [O("housingvista.home.recentProperties.viewAll", "View All"), /* @__PURE__ */ y(l, { className: "h-4 w-4" })]
229
+ className: "inline-flex min-h-[44px] items-center gap-1 text-sm font-medium text-text-secondary transition-colors hover:text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] rounded-md px-1",
230
+ children: [I("housingvista.home.recentProperties.viewAll", "View All"), /* @__PURE__ */ y(l, { className: "h-4 w-4" })]
200
231
  })]
201
- }), /* @__PURE__ */ y("div", {
232
+ }), R.length === 0 ? /* @__PURE__ */ y("div", {
233
+ className: "p-4",
234
+ children: /* @__PURE__ */ y(D, {
235
+ illustration: "empty-data",
236
+ title: I("housingvista.home.recentProperties.empty.title", "No properties yet"),
237
+ description: I("housingvista.home.recentProperties.empty.description", "List your first property to see it appear here."),
238
+ action: /* @__PURE__ */ b(C, {
239
+ onClick: () => h("properties/new"),
240
+ className: "gap-2",
241
+ children: [/* @__PURE__ */ y(g, { className: "h-4 w-4" }), I("housingvista.home.header.quickAdd", "Quick Add")]
242
+ })
243
+ })
244
+ }) : /* @__PURE__ */ y("div", {
202
245
  className: "grid grid-cols-1 gap-4 p-4 sm:grid-cols-2 lg:grid-cols-3",
203
- children: A.map((e) => /* @__PURE__ */ y(i, {
246
+ children: R.map((e) => /* @__PURE__ */ y(i, {
204
247
  id: e.id,
205
248
  title: e.title,
206
249
  price: e.price.amount,
@@ -221,6 +264,6 @@ var S = {
221
264
  });
222
265
  };
223
266
  //#endregion
224
- export { w as HomePage };
267
+ export { M as HomePage };
225
268
 
226
269
  //# sourceMappingURL=HomePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"HomePage.js","names":[],"sources":["../../../src/housingvista/pages/HomePage.tsx"],"sourcesContent":["/**\n * HousingVista Dashboard / Home Page\n * Migrated from legacy housingvista-frontend dashboard.tsx\n * @module housingvista\n */\n\nimport { useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Building, TrendingUp, Eye, DollarSign, Plus, BarChart3, FileText, Home, ArrowRight } from 'lucide-react';\nimport { StatCard, PropertyCard } from '../components';\nimport { useDashboardStats, useRecentActivities, useProperties } from '../hooks';\nimport { cn, formatNumber, getRelativeTime } from '../utils/helpers';\nimport type { RecentActivity } from '../types';\n\n// ---- Activity icon mapping ----\nconst activityIconMap: Record<RecentActivity['type'], typeof Eye> = {\n property_listed: Home,\n transaction_update: FileText,\n payment_received: DollarSign,\n maintenance_request: Building,\n viewing_scheduled: Eye,\n document_uploaded: FileText,\n offer_received: TrendingUp,\n lease_signed: FileText,\n};\n\nconst activityColorMap: Record<RecentActivity['type'], string> = {\n property_listed: 'text-purple-600 dark:text-purple-400',\n transaction_update: 'text-blue-600 dark:text-blue-400',\n payment_received: 'text-emerald-600 dark:text-emerald-400',\n maintenance_request: 'text-amber-600 dark:text-amber-400',\n viewing_scheduled: 'text-sky-600 dark:text-sky-400',\n document_uploaded: 'text-indigo-600 dark:text-indigo-400',\n offer_received: 'text-emerald-600 dark:text-emerald-400',\n lease_signed: 'text-teal-600 dark:text-teal-400',\n};\n\nexport const HomePage = () => {\n const navigate = useNavigate();\n const { t } = useI18n();\n const { data: stats } = useDashboardStats();\n const { data: activities } = useRecentActivities();\n const { data: properties } = useProperties();\n\n const tr = (key: string, fallback: string) => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n\n const quickActions = [\n {\n title: tr('housingvista.home.quickActions.addProperty.title', 'Add Property'),\n description: tr('housingvista.home.quickActions.addProperty.description', 'List a new property'),\n icon: Plus,\n path: 'properties/new',\n },\n {\n title: tr('housingvista.home.quickActions.viewAnalytics.title', 'View Analytics'),\n description: tr('housingvista.home.quickActions.viewAnalytics.description', 'Check performance metrics'),\n icon: BarChart3,\n path: 'analytics',\n },\n {\n title: tr('housingvista.home.quickActions.manageTransactions.title', 'Manage Transactions'),\n description: tr('housingvista.home.quickActions.manageTransactions.description', 'Handle ongoing deals'),\n icon: FileText,\n path: 'transactions',\n },\n {\n title: tr('housingvista.home.quickActions.browseProperties.title', 'Browse Properties'),\n description: tr('housingvista.home.quickActions.browseProperties.description', 'Explore listings'),\n icon: Building,\n path: 'properties',\n },\n ];\n\n const recentProperties = useMemo(() => properties.slice(0, 6), [properties]);\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Welcome Header */}\n <div className=\"flex flex-col lg:flex-row lg:items-center lg:justify-between gap-4 rounded-xl border border-border-subtle bg-bg-surface p-6 shadow-sm\">\n <div>\n <h1 className=\"text-3xl font-bold text-text-primary\">\n {tr('housingvista.home.header.title', 'Welcome back!')}\n </h1>\n <p className=\"mt-1 text-text-secondary\">\n {tr(\n 'housingvista.home.header.description',\n \"Here's what's happening with your real estate portfolio today.\"\n )}\n </p>\n </div>\n <div className=\"flex items-center gap-3\">\n <button\n onClick={() => navigate('properties/new')}\n 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 >\n <Plus className=\"h-4 w-4\" />\n {tr('housingvista.home.header.quickAdd', 'Quick Add')}\n </button>\n </div>\n </div>\n\n {/* Stats Grid */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n label={tr('housingvista.home.stats.totalProperties', 'Total Properties')}\n value={stats.totalProperties}\n icon={<Building className=\"h-5 w-5\" />}\n trend=\"up\"\n change={12}\n />\n <StatCard\n label={tr('housingvista.home.stats.activeListings', 'Active Listings')}\n value={stats.activeTransactions}\n icon={<TrendingUp className=\"h-5 w-5\" />}\n trend=\"up\"\n change={8}\n />\n <StatCard\n label={tr('housingvista.home.stats.totalViews', 'Total Views')}\n value={formatNumber(12540)}\n icon={<Eye className=\"h-5 w-5\" />}\n trend=\"down\"\n change={-2}\n />\n <StatCard\n label={tr('housingvista.home.stats.monthlyRevenue', 'Monthly Revenue')}\n value={stats.monthlyRevenue}\n prefix=\"$\"\n icon={<DollarSign className=\"h-5 w-5\" />}\n trend=\"up\"\n change={15}\n />\n </div>\n\n {/* Quick Actions + Recent Activity */}\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Quick Actions */}\n <div className=\"lg:col-span-1\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface shadow-sm\">\n <div className=\"border-b border-border-subtle px-5 py-4\">\n <h2 className=\"text-base font-semibold text-text-primary\">\n {tr('housingvista.home.quickActions.title', 'Quick Actions')}\n </h2>\n </div>\n <div className=\"space-y-2 p-4\">\n {quickActions.map((action) => {\n const Icon = action.icon;\n return (\n <button\n key={action.title}\n onClick={() => navigate(action.path)}\n className=\"flex w-full items-center gap-3 rounded-lg border border-border-subtle p-3 text-left transition-colors hover:bg-bg-sunken/50\"\n >\n <div className=\"rounded-lg bg-action-primary-bg/10 p-2\">\n <Icon className=\"h-5 w-5 text-text-primary\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium text-text-primary\">{action.title}</div>\n <div className=\"text-xs text-text-secondary\">{action.description}</div>\n </div>\n </button>\n );\n })}\n </div>\n </div>\n </div>\n\n {/* Recent Activity */}\n <div className=\"lg:col-span-2\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface shadow-sm\">\n <div className=\"border-b border-border-subtle px-5 py-4\">\n <h2 className=\"text-base font-semibold text-text-primary\">\n {tr('housingvista.home.recentActivity.title', 'Recent Activity')}\n </h2>\n </div>\n <div className=\"space-y-2 p-4\">\n {activities.slice(0, 6).map((activity) => {\n const Icon = activityIconMap[activity.type] ?? Eye;\n const colorClass = activityColorMap[activity.type] ?? 'text-text-secondary';\n return (\n <div\n key={activity.id}\n className=\"flex items-start gap-4 rounded-lg border border-border-subtle p-4 transition-colors hover:bg-bg-sunken/50\"\n >\n <div className=\"rounded-lg bg-bg-sunken p-2\">\n <Icon className={cn('h-5 w-5', colorClass)} />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-text-primary\">{activity.title}</p>\n <p className=\"text-xs text-text-secondary mt-0.5\">{activity.description}</p>\n <p className=\"text-xs text-text-secondary mt-1\">\n {getRelativeTime(activity.timestamp)}\n {activity.actorName && ` · ${activity.actorName}`}\n </p>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n </div>\n </div>\n\n {/* Recent Properties */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface shadow-sm\">\n <div className=\"flex items-center justify-between border-b border-border-subtle px-5 py-4\">\n <h2 className=\"text-base font-semibold text-text-primary\">\n {tr('housingvista.home.recentProperties.title', 'Recent Properties')}\n </h2>\n <button\n onClick={() => navigate('properties')}\n className=\"inline-flex items-center gap-1 text-sm font-medium text-text-secondary transition-colors hover:text-text-primary\"\n >\n {tr('housingvista.home.recentProperties.viewAll', 'View All')}\n <ArrowRight className=\"h-4 w-4\" />\n </button>\n </div>\n <div className=\"grid grid-cols-1 gap-4 p-4 sm:grid-cols-2 lg:grid-cols-3\">\n {recentProperties.map((property) => (\n <PropertyCard\n key={property.id}\n id={property.id}\n title={property.title}\n price={property.price.amount}\n priceType={property.price.type === 'rent' ? 'rent' : 'sale'}\n pricePeriod={property.price.period}\n location={`${property.location.neighborhood}, ${property.location.city}`}\n bedrooms={property.specifications.bedrooms}\n bathrooms={property.specifications.bathrooms}\n area={property.specifications.totalArea}\n imageUrl={property.images[0]?.url}\n status={property.status.replace('_', ' ')}\n type={property.category}\n onClick={() => navigate(`properties/${property.id}`)}\n />\n ))}\n </div>\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"HomePage.js","names":[],"sources":["../../../src/housingvista/pages/HomePage.tsx"],"sourcesContent":["/**\n * HousingVista Dashboard / Home Page\n * Migrated from legacy housingvista-frontend dashboard.tsx\n * @module housingvista\n */\n\nimport { useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport {\n AuroraBackground,\n GradientText,\n Button,\n GlassCard,\n EmphasisPanel,\n IllustratedEmptyState,\n PagePurpose,\n NextSteps,\n} from '@burdenoff/fe-libs/ui';\nimport { Building, TrendingUp, Eye, DollarSign, Plus, BarChart3, FileText, Home, ArrowRight } from 'lucide-react';\nimport { StatCard, PropertyCard } from '../components';\nimport { useDashboardStats, useRecentActivities, useProperties } from '../hooks';\nimport { cn, formatNumber, getRelativeTime } from '../utils/helpers';\nimport type { RecentActivity } from '../types';\n\n// ---- Activity icon mapping ----\nconst activityIconMap: Record<RecentActivity['type'], typeof Eye> = {\n property_listed: Home,\n transaction_update: FileText,\n payment_received: DollarSign,\n maintenance_request: Building,\n viewing_scheduled: Eye,\n document_uploaded: FileText,\n offer_received: TrendingUp,\n lease_signed: FileText,\n};\n\nconst activityColorMap: Record<RecentActivity['type'], string> = {\n property_listed: 'text-purple-600 dark:text-purple-400',\n transaction_update: 'text-blue-600 dark:text-blue-400',\n payment_received: 'text-emerald-600 dark:text-emerald-400',\n maintenance_request: 'text-amber-600 dark:text-amber-400',\n viewing_scheduled: 'text-sky-600 dark:text-sky-400',\n document_uploaded: 'text-indigo-600 dark:text-indigo-400',\n offer_received: 'text-emerald-600 dark:text-emerald-400',\n lease_signed: 'text-teal-600 dark:text-teal-400',\n};\n\nexport const HomePage = () => {\n const navigate = useNavigate();\n const { t } = useI18n();\n const { data: stats } = useDashboardStats();\n const { data: activities } = useRecentActivities();\n const { data: properties } = useProperties();\n\n const tr = (key: string, fallback: string) => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n\n const quickActions = [\n {\n title: tr('housingvista.home.quickActions.addProperty.title', 'Add Property'),\n description: tr('housingvista.home.quickActions.addProperty.description', 'List a new property'),\n icon: Plus,\n path: 'properties/new',\n },\n {\n title: tr('housingvista.home.quickActions.viewAnalytics.title', 'View Analytics'),\n description: tr('housingvista.home.quickActions.viewAnalytics.description', 'Check performance metrics'),\n icon: BarChart3,\n path: 'analytics',\n },\n {\n title: tr('housingvista.home.quickActions.manageTransactions.title', 'Manage Transactions'),\n description: tr('housingvista.home.quickActions.manageTransactions.description', 'Handle ongoing deals'),\n icon: FileText,\n path: 'transactions',\n },\n {\n title: tr('housingvista.home.quickActions.browseProperties.title', 'Browse Properties'),\n description: tr('housingvista.home.quickActions.browseProperties.description', 'Explore listings'),\n icon: Building,\n path: 'properties',\n },\n ];\n\n const recentProperties = useMemo(() => properties.slice(0, 6), [properties]);\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Welcome Header — Boff UI 2.0 aurora hero (one per MFE) */}\n <div className=\"relative overflow-hidden rounded-card border border-border-seam bg-gloss-card p-6 shadow-pop\">\n <AuroraBackground intensity=\"subtle\" />\n <div className=\"relative flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between\">\n <div>\n <h1 className=\"text-3xl font-bold text-text-primary\">\n <GradientText>{tr('housingvista.home.header.title', 'Welcome back!')}</GradientText>\n </h1>\n <p className=\"mt-1 text-text-secondary\">\n {tr(\n 'housingvista.home.header.description',\n \"Here's what's happening with your real estate portfolio today.\"\n )}\n </p>\n </div>\n <Button onClick={() => navigate('properties/new')} className=\"gap-2 self-start lg:self-auto\">\n <Plus className=\"h-4 w-4\" />\n {tr('housingvista.home.header.quickAdd', 'Quick Add')}\n </Button>\n </div>\n </div>\n\n <PagePurpose className=\"max-w-3xl\">\n {tr(\n 'housingvista.home.purpose',\n 'Your real-estate command center. See your portfolio at a glance, jump to the things you do most, and pick up where you left off — from listing a property to tracking deals and analytics.'\n )}\n </PagePurpose>\n\n <NextSteps\n storageKey=\"housingvista-home\"\n steps={[\n {\n id: 'add-property',\n label: tr('housingvista.home.nextSteps.addProperty', 'List your first property'),\n description: tr(\n 'housingvista.home.nextSteps.addPropertyDesc',\n 'Create a market-ready listing in a few guided steps.'\n ),\n onClick: () => navigate('properties/new'),\n },\n {\n id: 'browse',\n label: tr('housingvista.home.nextSteps.browse', 'Browse properties'),\n description: tr('housingvista.home.nextSteps.browseDesc', 'Explore listings and open one for full details.'),\n onClick: () => navigate('properties'),\n },\n {\n id: 'analytics',\n label: tr('housingvista.home.nextSteps.analytics', 'Review your analytics'),\n description: tr(\n 'housingvista.home.nextSteps.analyticsDesc',\n 'Check portfolio performance and market insights.'\n ),\n onClick: () => navigate('analytics'),\n },\n ]}\n />\n\n {/* Stats Grid */}\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n label={tr('housingvista.home.stats.totalProperties', 'Total Properties')}\n value={stats.totalProperties}\n icon={<Building className=\"h-5 w-5\" />}\n trend=\"up\"\n change={12}\n featured\n />\n <StatCard\n label={tr('housingvista.home.stats.activeListings', 'Active Listings')}\n value={stats.activeTransactions}\n icon={<TrendingUp className=\"h-5 w-5\" />}\n trend=\"up\"\n change={8}\n />\n <StatCard\n label={tr('housingvista.home.stats.totalViews', 'Total Views')}\n value={formatNumber(12540)}\n icon={<Eye className=\"h-5 w-5\" />}\n trend=\"down\"\n change={-2}\n />\n <StatCard\n label={tr('housingvista.home.stats.monthlyRevenue', 'Monthly Revenue')}\n value={stats.monthlyRevenue}\n prefix=\"$\"\n icon={<DollarSign className=\"h-5 w-5\" />}\n trend=\"up\"\n change={15}\n />\n </div>\n\n {/* Quick Actions + Recent Activity */}\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Quick Actions */}\n <div className=\"lg:col-span-1\">\n <GlassCard treatment=\"plain\" className=\"border-border-seam\">\n <div className=\"border-b border-border-seam px-5 py-4\">\n <h2 className=\"text-base font-semibold text-text-primary\">\n {tr('housingvista.home.quickActions.title', 'Quick Actions')}\n </h2>\n </div>\n <div className=\"space-y-2 p-4\">\n {quickActions.map((action) => {\n const Icon = action.icon;\n return (\n <button\n key={action.title}\n onClick={() => navigate(action.path)}\n className=\"flex min-h-[44px] w-full items-center gap-3 rounded-lg border border-border-seam p-3 text-left transition-colors hover:bg-bg-sunken/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)]\"\n >\n <div className=\"rounded-lg bg-action-primary-bg/10 p-2\">\n <Icon className=\"h-5 w-5 text-text-primary\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"text-sm font-medium text-text-primary\">{action.title}</div>\n <div className=\"text-xs text-text-secondary\">{action.description}</div>\n </div>\n </button>\n );\n })}\n </div>\n </GlassCard>\n </div>\n\n {/* Recent Activity — primary insight zone (one EmphasisPanel per page) */}\n <div className=\"lg:col-span-2\">\n <EmphasisPanel className=\"p-0\">\n <div className=\"border-b border-border-seam px-5 py-4\">\n <h2 className=\"text-base font-semibold text-text-primary\">\n {tr('housingvista.home.recentActivity.title', 'Recent Activity')}\n </h2>\n </div>\n <div className=\"space-y-2 p-4\">\n {activities.slice(0, 6).map((activity) => {\n const Icon = activityIconMap[activity.type] ?? Eye;\n const colorClass = activityColorMap[activity.type] ?? 'text-text-secondary';\n return (\n <div\n key={activity.id}\n className=\"flex items-start gap-4 rounded-lg border border-border-seam bg-bg-surface/60 p-4 transition-colors hover:bg-bg-sunken/50\"\n >\n <div className=\"rounded-lg bg-bg-sunken p-2\">\n <Icon className={cn('h-5 w-5', colorClass)} />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium text-text-primary\">{activity.title}</p>\n <p className=\"text-xs text-text-secondary mt-0.5\">{activity.description}</p>\n <p className=\"text-xs text-text-secondary mt-1\">\n {getRelativeTime(activity.timestamp)}\n {activity.actorName && ` · ${activity.actorName}`}\n </p>\n </div>\n </div>\n );\n })}\n </div>\n </EmphasisPanel>\n </div>\n </div>\n\n {/* Recent Properties */}\n <GlassCard treatment=\"plain\" className=\"border-border-seam\">\n <div className=\"flex items-center justify-between border-b border-border-seam px-5 py-4\">\n <h2 className=\"text-base font-semibold text-text-primary\">\n {tr('housingvista.home.recentProperties.title', 'Recent Properties')}\n </h2>\n <button\n onClick={() => navigate('properties')}\n className=\"inline-flex min-h-[44px] items-center gap-1 text-sm font-medium text-text-secondary transition-colors hover:text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] rounded-md px-1\"\n >\n {tr('housingvista.home.recentProperties.viewAll', 'View All')}\n <ArrowRight className=\"h-4 w-4\" />\n </button>\n </div>\n {recentProperties.length === 0 ? (\n <div className=\"p-4\">\n <IllustratedEmptyState\n illustration=\"empty-data\"\n title={tr('housingvista.home.recentProperties.empty.title', 'No properties yet')}\n description={tr(\n 'housingvista.home.recentProperties.empty.description',\n 'List your first property to see it appear here.'\n )}\n action={\n <Button onClick={() => navigate('properties/new')} className=\"gap-2\">\n <Plus className=\"h-4 w-4\" />\n {tr('housingvista.home.header.quickAdd', 'Quick Add')}\n </Button>\n }\n />\n </div>\n ) : (\n <div className=\"grid grid-cols-1 gap-4 p-4 sm:grid-cols-2 lg:grid-cols-3\">\n {recentProperties.map((property) => (\n <PropertyCard\n key={property.id}\n id={property.id}\n title={property.title}\n price={property.price.amount}\n priceType={property.price.type === 'rent' ? 'rent' : 'sale'}\n pricePeriod={property.price.period}\n location={`${property.location.neighborhood}, ${property.location.city}`}\n bedrooms={property.specifications.bedrooms}\n bathrooms={property.specifications.bathrooms}\n area={property.specifications.totalArea}\n imageUrl={property.images[0]?.url}\n status={property.status.replace('_', ' ')}\n type={property.category}\n onClick={() => navigate(`properties/${property.id}`)}\n />\n ))}\n </div>\n )}\n </GlassCard>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -10,8 +10,9 @@ import { useAMCContracts as l } from "../../hooks/index.js";
10
10
  import { useMemo as u, useState as d } from "react";
11
11
  import { AlertTriangle as f, Calendar as p, Clock as m, DollarSign as h, Download as g, Plus as _, RotateCcw as v, Shield as y, Wrench as b } from "lucide-react";
12
12
  import { jsx as x, jsxs as S } from "react/jsx-runtime";
13
+ import { EmphasisPanel as C } from "@burdenoff/fe-libs/ui";
13
14
  //#region src/housingvista/pages/amc/AMCManagementPage.tsx
14
- function C(e) {
15
+ function w(e) {
15
16
  switch (e) {
16
17
  case "active": return "success";
17
18
  case "expiring_soon": return "warning";
@@ -20,24 +21,25 @@ function C(e) {
20
21
  default: return "muted";
21
22
  }
22
23
  }
23
- function w() {
24
- let { data: w } = l(), [T, E] = d(""), D = u(() => {
25
- if (!T) return w;
26
- let e = T.toLowerCase();
27
- return w.filter((t) => t.propertyTitle.toLowerCase().includes(e) || t.providerName.toLowerCase().includes(e) || t.packageName.toLowerCase().includes(e));
28
- }, [w, T]), O = u(() => ({
29
- activeContracts: w.filter((e) => e.status === "active" || e.status === "expiring_soon").length,
30
- pendingRenewals: w.filter((e) => e.status === "expiring_soon").length,
31
- totalMonthlySpent: w.filter((e) => e.status === "active" || e.status === "expiring_soon").reduce((e, t) => e + t.monthlyCost, 0),
32
- upcomingServices: w.filter((e) => {
24
+ function T() {
25
+ let { data: T } = l(), [E, D] = d(""), O = u(() => {
26
+ if (!E) return T;
27
+ let e = E.toLowerCase();
28
+ return T.filter((t) => t.propertyTitle.toLowerCase().includes(e) || t.providerName.toLowerCase().includes(e) || t.packageName.toLowerCase().includes(e));
29
+ }, [T, E]), k = u(() => ({
30
+ activeContracts: T.filter((e) => e.status === "active" || e.status === "expiring_soon").length,
31
+ pendingRenewals: T.filter((e) => e.status === "expiring_soon").length,
32
+ totalMonthlySpent: T.filter((e) => e.status === "active" || e.status === "expiring_soon").reduce((e, t) => e + t.monthlyCost, 0),
33
+ upcomingServices: T.filter((e) => {
33
34
  if (!e.nextServiceDate) return !1;
34
35
  let t = new Date(e.nextServiceDate), n = /* @__PURE__ */ new Date(), r = (t.getTime() - n.getTime()) / (1e3 * 60 * 60 * 24);
35
36
  return r >= 0 && r <= 30;
36
37
  }).length
37
- }), [w]);
38
+ }), [T]), A = u(() => T.filter((e) => e.nextServiceDate && (e.status === "active" || e.status === "expiring_soon")).sort((e, t) => new Date(e.nextServiceDate).getTime() - new Date(t.nextServiceDate).getTime()), [T]);
38
39
  return /* @__PURE__ */ S(r, {
39
40
  title: "AMC Management",
40
41
  description: "Manage Annual Maintenance Contracts and service packages",
42
+ purpose: "Keep your properties maintained without surprises. Track every Annual Maintenance Contract, see what each covers and costs, get ahead of renewals, and know which services are due in the next 30 days so nothing slips.",
41
43
  actions: /* @__PURE__ */ S("div", {
42
44
  className: "flex items-center gap-2",
43
45
  children: [/* @__PURE__ */ S("button", {
@@ -49,42 +51,50 @@ function w() {
49
51
  })]
50
52
  }),
51
53
  children: [
52
- /* @__PURE__ */ S("div", {
53
- className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
54
- children: [
55
- /* @__PURE__ */ x(i, {
56
- label: "Active Contracts",
57
- value: O.activeContracts,
58
- icon: /* @__PURE__ */ x(y, { className: "h-4 w-4" })
59
- }),
60
- /* @__PURE__ */ x(i, {
61
- label: "Pending Renewals",
62
- value: O.pendingRenewals,
63
- icon: /* @__PURE__ */ x(v, { className: "h-4 w-4" }),
64
- trend: O.pendingRenewals > 0 ? "up" : "stable",
65
- change: O.pendingRenewals > 0 ? O.pendingRenewals : 0
66
- }),
67
- /* @__PURE__ */ x(i, {
68
- label: "Total Monthly Spent",
69
- value: O.totalMonthlySpent,
70
- prefix: "$",
71
- icon: /* @__PURE__ */ x(h, { className: "h-4 w-4" })
72
- }),
73
- /* @__PURE__ */ x(i, {
74
- label: "Upcoming Services",
75
- value: O.upcomingServices,
76
- icon: /* @__PURE__ */ x(p, { className: "h-4 w-4" })
77
- })
78
- ]
54
+ /* @__PURE__ */ x(C, {
55
+ className: "p-4",
56
+ children: /* @__PURE__ */ S("div", {
57
+ className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
58
+ children: [
59
+ /* @__PURE__ */ x(i, {
60
+ label: "Active Contracts",
61
+ value: k.activeContracts,
62
+ icon: /* @__PURE__ */ x(y, { className: "h-4 w-4" })
63
+ }),
64
+ /* @__PURE__ */ x(i, {
65
+ label: "Pending Renewals",
66
+ value: k.pendingRenewals,
67
+ icon: /* @__PURE__ */ x(v, { className: "h-4 w-4" }),
68
+ trend: k.pendingRenewals > 0 ? "up" : "stable",
69
+ change: k.pendingRenewals > 0 ? k.pendingRenewals : 0
70
+ }),
71
+ /* @__PURE__ */ x(i, {
72
+ label: "Total Monthly Spent",
73
+ value: k.totalMonthlySpent,
74
+ prefix: "$",
75
+ icon: /* @__PURE__ */ x(h, { className: "h-4 w-4" })
76
+ }),
77
+ /* @__PURE__ */ x(i, {
78
+ label: "Upcoming Services",
79
+ value: k.upcomingServices,
80
+ icon: /* @__PURE__ */ x(p, { className: "h-4 w-4" })
81
+ })
82
+ ]
83
+ })
79
84
  }),
80
85
  /* @__PURE__ */ S("div", {
81
86
  className: "rounded-lg border border-border-subtle bg-bg-surface p-5 shadow-sm",
82
87
  children: [/* @__PURE__ */ x("h3", {
83
88
  className: "mb-4 text-lg font-semibold text-text-primary",
84
89
  children: "Upcoming Service Schedule"
85
- }), /* @__PURE__ */ x("div", {
90
+ }), A.length === 0 ? /* @__PURE__ */ x(s, {
91
+ illustration: "empty-generic",
92
+ title: "No services scheduled",
93
+ description: "Once your active contracts have upcoming service dates, they'll be listed here in order of priority.",
94
+ className: "border-0 bg-transparent p-6"
95
+ }) : /* @__PURE__ */ x("div", {
86
96
  className: "space-y-3",
87
- children: w.filter((e) => e.nextServiceDate && (e.status === "active" || e.status === "expiring_soon")).sort((e, t) => new Date(e.nextServiceDate).getTime() - new Date(t.nextServiceDate).getTime()).map((t) => {
97
+ children: A.map((t) => {
88
98
  let r = new Date(t.nextServiceDate), i = /* @__PURE__ */ new Date(), a = Math.ceil((r.getTime() - i.getTime()) / (1e3 * 60 * 60 * 24)), s = a <= 7, c = a < 0;
89
99
  return /* @__PURE__ */ S("div", {
90
100
  className: "flex flex-col gap-3 rounded-lg bg-bg-sunken/50 p-4 sm:flex-row sm:items-center sm:justify-between",
@@ -134,7 +144,7 @@ function w() {
134
144
  })]
135
145
  }), /* @__PURE__ */ x(o, {
136
146
  label: t.status.replace("_", " "),
137
- variant: C(t.status)
147
+ variant: w(t.status)
138
148
  })]
139
149
  })]
140
150
  }, t.id);
@@ -147,13 +157,13 @@ function w() {
147
157
  children: "All Contracts"
148
158
  }),
149
159
  /* @__PURE__ */ x(c, {
150
- searchValue: T,
151
- onSearchChange: E,
160
+ searchValue: E,
161
+ onSearchChange: D,
152
162
  searchPlaceholder: "Search contracts, providers, properties..."
153
163
  }),
154
164
  /* @__PURE__ */ x("div", {
155
165
  className: "mt-4",
156
- children: D.length > 0 ? /* @__PURE__ */ x(a, {
166
+ children: O.length > 0 ? /* @__PURE__ */ x(a, {
157
167
  columns: [
158
168
  {
159
169
  key: "packageName",
@@ -220,15 +230,16 @@ function w() {
220
230
  header: "Status",
221
231
  render: (e) => /* @__PURE__ */ x(o, {
222
232
  label: e.status.replace("_", " "),
223
- variant: C(e.status),
233
+ variant: w(e.status),
224
234
  dot: !0
225
235
  })
226
236
  }
227
237
  ],
228
- data: D,
238
+ data: O,
229
239
  keyField: "id",
230
240
  pageSize: 10
231
241
  }) : /* @__PURE__ */ x(s, {
242
+ illustration: "empty-search",
232
243
  icon: /* @__PURE__ */ x(y, { className: "h-12 w-12" }),
233
244
  title: "No contracts found",
234
245
  description: "Try adjusting your search criteria or create a new contract.",
@@ -243,6 +254,6 @@ function w() {
243
254
  });
244
255
  }
245
256
  //#endregion
246
- export { w as AMCManagementPage };
257
+ export { T as AMCManagementPage };
247
258
 
248
259
  //# sourceMappingURL=AMCManagementPage.js.map