@burdenoff/microfe-coolandlovely 2026.706.2 → 2026.706.3

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 (75) hide show
  1. package/dist/coolandlovely/CoolAndLovelyRoot.js +62 -46
  2. package/dist/coolandlovely/CoolAndLovelyRoot.js.map +1 -1
  3. package/dist/coolandlovely/components/AddToLookbookButton.js +22 -22
  4. package/dist/coolandlovely/components/AddToLookbookButton.js.map +1 -1
  5. package/dist/coolandlovely/components/BrandCover.js +39 -0
  6. package/dist/coolandlovely/components/BrandCover.js.map +1 -0
  7. package/dist/coolandlovely/components/BrandCreatorAvatars.js +57 -0
  8. package/dist/coolandlovely/components/BrandCreatorAvatars.js.map +1 -0
  9. package/dist/coolandlovely/components/ColourSwatchRow.js +86 -0
  10. package/dist/coolandlovely/components/ColourSwatchRow.js.map +1 -0
  11. package/dist/coolandlovely/components/Comments.js +4 -4
  12. package/dist/coolandlovely/components/Comments.js.map +1 -1
  13. package/dist/coolandlovely/components/FileImage.js.map +1 -1
  14. package/dist/coolandlovely/components/ImageUploadField.js +139 -57
  15. package/dist/coolandlovely/components/ImageUploadField.js.map +1 -1
  16. package/dist/coolandlovely/components/LookCard.js +77 -0
  17. package/dist/coolandlovely/components/LookCard.js.map +1 -0
  18. package/dist/coolandlovely/components/MetricsCard.js +1 -1
  19. package/dist/coolandlovely/components/MetricsCard.js.map +1 -1
  20. package/dist/coolandlovely/components/ShopItemCard.js +45 -0
  21. package/dist/coolandlovely/components/ShopItemCard.js.map +1 -0
  22. package/dist/coolandlovely/components/StepTracker.js +35 -0
  23. package/dist/coolandlovely/components/StepTracker.js.map +1 -0
  24. package/dist/coolandlovely/components/Thumbnail.js +15 -11
  25. package/dist/coolandlovely/components/Thumbnail.js.map +1 -1
  26. package/dist/coolandlovely/components/VisibilityChip.js +32 -0
  27. package/dist/coolandlovely/components/VisibilityChip.js.map +1 -0
  28. package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js +94 -69
  29. package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js.map +1 -1
  30. package/dist/coolandlovely/hooks/useFiles.js +49 -32
  31. package/dist/coolandlovely/hooks/useFiles.js.map +1 -1
  32. package/dist/coolandlovely/pages/HomePage.js +112 -133
  33. package/dist/coolandlovely/pages/HomePage.js.map +1 -1
  34. package/dist/coolandlovely/pages/brands/BrandDetailPage.js +253 -242
  35. package/dist/coolandlovely/pages/brands/BrandDetailPage.js.map +1 -1
  36. package/dist/coolandlovely/pages/brands/BrandFormPage.js +116 -112
  37. package/dist/coolandlovely/pages/brands/BrandFormPage.js.map +1 -1
  38. package/dist/coolandlovely/pages/brands/BrandsListPage.js +13 -13
  39. package/dist/coolandlovely/pages/brands/BrandsListPage.js.map +1 -1
  40. package/dist/coolandlovely/pages/collaborations/CollaborationDetailPage.js +117 -95
  41. package/dist/coolandlovely/pages/collaborations/CollaborationDetailPage.js.map +1 -1
  42. package/dist/coolandlovely/pages/collaborations/CollaborationFormPage.js +1 -1
  43. package/dist/coolandlovely/pages/collaborations/CollaborationsListPage.js +50 -43
  44. package/dist/coolandlovely/pages/collaborations/CollaborationsListPage.js.map +1 -1
  45. package/dist/coolandlovely/pages/collections/CollectionDetailPage.js +131 -108
  46. package/dist/coolandlovely/pages/collections/CollectionDetailPage.js.map +1 -1
  47. package/dist/coolandlovely/pages/collections/CollectionFormPage.js +1 -1
  48. package/dist/coolandlovely/pages/collections/CollectionsListPage.js +59 -56
  49. package/dist/coolandlovely/pages/collections/CollectionsListPage.js.map +1 -1
  50. package/dist/coolandlovely/pages/discover/DiscoverPage.js +1 -1
  51. package/dist/coolandlovely/pages/discover/DiscoverPage.js.map +1 -1
  52. package/dist/coolandlovely/pages/items/StyleItemDetailPage.js +175 -147
  53. package/dist/coolandlovely/pages/items/StyleItemDetailPage.js.map +1 -1
  54. package/dist/coolandlovely/pages/items/StyleItemFormPage.js +1 -1
  55. package/dist/coolandlovely/pages/items/StyleItemsListPage.js +71 -62
  56. package/dist/coolandlovely/pages/items/StyleItemsListPage.js.map +1 -1
  57. package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.js +149 -127
  58. package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.js.map +1 -1
  59. package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.js +69 -53
  60. package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.js.map +1 -1
  61. package/dist/coolandlovely/pages/looks/LookDetailPage.js +135 -113
  62. package/dist/coolandlovely/pages/looks/LookDetailPage.js.map +1 -1
  63. package/dist/coolandlovely/pages/looks/LookFormPage.js +122 -110
  64. package/dist/coolandlovely/pages/looks/LookFormPage.js.map +1 -1
  65. package/dist/coolandlovely/pages/looks/LooksListPage.js +60 -97
  66. package/dist/coolandlovely/pages/looks/LooksListPage.js.map +1 -1
  67. package/dist/coolandlovely/pages/profile/StyleProfilePage.js +372 -210
  68. package/dist/coolandlovely/pages/profile/StyleProfilePage.js.map +1 -1
  69. package/dist/coolandlovely/pages/trends/TrendsPage.js +1 -1
  70. package/dist/coolandlovely/pages/trends/TrendsPage.js.map +1 -1
  71. package/dist/coolandlovely/pages/wardrobe/WardrobeFormPage.js +130 -94
  72. package/dist/coolandlovely/pages/wardrobe/WardrobeFormPage.js.map +1 -1
  73. package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.js +75 -76
  74. package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.js.map +1 -1
  75. package/package.json +1 -1
@@ -6,39 +6,43 @@ import { StatusBadge as i } from "../components/StatusBadge.js";
6
6
  import { ErrorView as a, LoadingView as o } from "../components/StateViews.js";
7
7
  import { Thumbnail as s } from "../components/Thumbnail.js";
8
8
  import { useBrands as c, useCollaborations as l, useLooks as u, useStyleItems as d, useWardrobeItems as f } from "../hooks/useCoolAndLovelyApi.js";
9
+ import { LookCard as p } from "../components/LookCard.js";
9
10
  import "../hooks/index.js";
10
- import { formatRelativeTime as p, titleCase as m } from "../utils/formatters.js";
11
- import { useMemo as h } from "react";
12
- import { ArrowRight as g, BookHeart as _, Compass as v, Handshake as y, Heart as b, Plus as x, Shapes as S, Shirt as C, Sparkles as w, Star as T, Store as E, TrendingUp as D, UserCircle as O } from "lucide-react";
13
- import { jsx as k, jsxs as A } from "react/jsx-runtime";
14
- import { EmphasisPanel as j, PagePurpose as M } from "@burdenoff/fe-libs/ui";
11
+ import { useMemo as m } from "react";
12
+ import { ArrowRight as h, BookHeart as g, Compass as _, Handshake as v, Heart as y, Plus as b, Shapes as x, Shirt as S, Sparkles as C, Star as w, Store as T, TrendingUp as E, UserCircle as D } from "lucide-react";
13
+ import { jsx as O, jsxs as k } from "react/jsx-runtime";
14
+ import { EmphasisPanel as A, PagePurpose as j } from "@burdenoff/fe-libs/ui";
15
15
  //#region src/coolandlovely/pages/HomePage.tsx
16
+ function M() {
17
+ let e = (/* @__PURE__ */ new Date()).getHours();
18
+ return e < 12 ? "Good morning" : e < 18 ? "Good afternoon" : "Good evening";
19
+ }
16
20
  var N = [
17
21
  {
18
22
  label: "New Brand",
19
23
  description: "Launch a storefront",
20
- icon: /* @__PURE__ */ k(E, { className: "h-5 w-5" }),
24
+ icon: /* @__PURE__ */ O(T, { className: "h-5 w-5" }),
21
25
  path: "/brands/new",
22
26
  color: "bg-accent-purple-subtle text-text-primary"
23
27
  },
24
28
  {
25
29
  label: "Add Style Item",
26
30
  description: "List a piece",
27
- icon: /* @__PURE__ */ k(C, { className: "h-5 w-5" }),
31
+ icon: /* @__PURE__ */ O(S, { className: "h-5 w-5" }),
28
32
  path: "/items/new",
29
33
  color: "bg-[var(--color-accent-soft)] text-text-primary"
30
34
  },
31
35
  {
32
36
  label: "Publish a Look",
33
37
  description: "Shop-the-look outfit",
34
- icon: /* @__PURE__ */ k(w, { className: "h-5 w-5" }),
38
+ icon: /* @__PURE__ */ O(C, { className: "h-5 w-5" }),
35
39
  path: "/looks/new",
36
40
  color: "bg-status-success-bg-subtle text-status-success-text"
37
41
  },
38
42
  {
39
43
  label: "My Wardrobe",
40
44
  description: "What you own",
41
- icon: /* @__PURE__ */ k(b, { className: "h-5 w-5" }),
45
+ icon: /* @__PURE__ */ O(y, { className: "h-5 w-5" }),
42
46
  path: "/wardrobe",
43
47
  color: "bg-status-warning-bg-subtle text-status-warning-text"
44
48
  }
@@ -46,77 +50,77 @@ var N = [
46
50
  {
47
51
  label: "Brands",
48
52
  description: "Storefronts with a publish lifecycle",
49
- icon: /* @__PURE__ */ k(E, { className: "h-6 w-6" }),
53
+ icon: /* @__PURE__ */ O(T, { className: "h-6 w-6" }),
50
54
  path: "/brands",
51
55
  color: "bg-accent-purple-subtle text-text-primary"
52
56
  },
53
57
  {
54
58
  label: "Collections",
55
59
  description: "Seasonal drops & curated edits",
56
- icon: /* @__PURE__ */ k(S, { className: "h-6 w-6" }),
60
+ icon: /* @__PURE__ */ O(x, { className: "h-6 w-6" }),
57
61
  path: "/collections",
58
62
  color: "bg-accent-blue-subtle text-accent-blue"
59
63
  },
60
64
  {
61
65
  label: "Style Items",
62
66
  description: "The shoppable catalogue",
63
- icon: /* @__PURE__ */ k(C, { className: "h-6 w-6" }),
67
+ icon: /* @__PURE__ */ O(S, { className: "h-6 w-6" }),
64
68
  path: "/items",
65
69
  color: "bg-[var(--color-accent-soft)] text-text-primary"
66
70
  },
67
71
  {
68
72
  label: "Looks",
69
73
  description: "Published shop-the-look outfits",
70
- icon: /* @__PURE__ */ k(w, { className: "h-6 w-6" }),
74
+ icon: /* @__PURE__ */ O(C, { className: "h-6 w-6" }),
71
75
  path: "/looks",
72
76
  color: "bg-status-success-bg-subtle text-status-success-text"
73
77
  },
74
78
  {
75
79
  label: "Collaborations",
76
80
  description: "Brand × creator partnerships",
77
- icon: /* @__PURE__ */ k(y, { className: "h-6 w-6" }),
81
+ icon: /* @__PURE__ */ O(v, { className: "h-6 w-6" }),
78
82
  path: "/collaborations",
79
83
  color: "bg-status-warning-bg-subtle text-status-warning-text"
80
84
  },
81
85
  {
82
86
  label: "Wardrobe",
83
87
  description: "Your digital closet & wear log",
84
- icon: /* @__PURE__ */ k(b, { className: "h-6 w-6" }),
88
+ icon: /* @__PURE__ */ O(y, { className: "h-6 w-6" }),
85
89
  path: "/wardrobe",
86
90
  color: "bg-status-error-bg-subtle text-status-error-text"
87
91
  },
88
92
  {
89
93
  label: "Lookbooks",
90
94
  description: "Themed boards of saved pieces",
91
- icon: /* @__PURE__ */ k(_, { className: "h-6 w-6" }),
95
+ icon: /* @__PURE__ */ O(g, { className: "h-6 w-6" }),
92
96
  path: "/lookbooks",
93
97
  color: "bg-accent-purple-subtle text-text-primary"
94
98
  },
95
99
  {
96
100
  label: "Style Profile",
97
101
  description: "Your taste, palette & sizing",
98
- icon: /* @__PURE__ */ k(O, { className: "h-6 w-6" }),
102
+ icon: /* @__PURE__ */ O(D, { className: "h-6 w-6" }),
99
103
  path: "/profile",
100
104
  color: "bg-accent-blue-subtle text-accent-blue"
101
105
  },
102
106
  {
103
107
  label: "Discover",
104
108
  description: "A feed tuned to your taste",
105
- icon: /* @__PURE__ */ k(v, { className: "h-6 w-6" }),
109
+ icon: /* @__PURE__ */ O(_, { className: "h-6 w-6" }),
106
110
  path: "/discover",
107
111
  color: "bg-[var(--color-accent-soft)] text-text-primary"
108
112
  },
109
113
  {
110
114
  label: "Trends",
111
115
  description: "Live signals from platform activity",
112
- icon: /* @__PURE__ */ k(D, { className: "h-6 w-6" }),
116
+ icon: /* @__PURE__ */ O(E, { className: "h-6 w-6" }),
113
117
  path: "/trends",
114
118
  color: "bg-status-success-bg-subtle text-status-success-text"
115
119
  }
116
120
  ];
117
121
  function F() {
118
- let { navigateTo: _, currentUser: v } = e(), S = c(), D = d(), O = u(), F = l(), I = f(), L = v?.firstName ?? v?.name ?? "there", R = S.isLoading || D.isLoading || O.isLoading || F.isLoading || I.isLoading, z = S.isError && D.isError && O.isError && F.isError, B = h(() => {
119
- let e = S.data?.items ?? [], t = D.data?.items ?? [], n = O.data?.items ?? [], r = F.data ?? [], i = I.data ?? [];
122
+ let { navigateTo: g, currentUser: _ } = e(), y = c(), x = d(), E = u(), D = l(), F = f(), I = _?.firstName ?? _?.name ?? "there", L = y.isLoading || x.isLoading || E.isLoading || D.isLoading || F.isLoading, R = y.isError && x.isError && E.isError && D.isError, z = m(() => {
123
+ let e = y.data?.items ?? [], t = x.data?.items ?? [], n = E.data?.items ?? [], r = D.data ?? [], i = F.data ?? [];
120
124
  return {
121
125
  totalBrands: e.length,
122
126
  publishedBrands: e.filter((e) => e.status === "PUBLISHED").length,
@@ -128,226 +132,201 @@ function F() {
128
132
  wardrobeItems: i.length
129
133
  };
130
134
  }, [
131
- S.data,
135
+ y.data,
136
+ x.data,
137
+ E.data,
132
138
  D.data,
133
- O.data,
134
- F.data,
135
- I.data
136
- ]), V = h(() => [...O.data?.items ?? []].slice(0, 6), [O.data]), H = h(() => [...S.data?.items ?? []].sort((e, t) => new Date(t.updatedAt).getTime() - new Date(e.updatedAt).getTime()).slice(0, 4), [S.data]);
137
- if (R) return /* @__PURE__ */ k(n, {
139
+ F.data
140
+ ]), B = m(() => [...E.data?.items ?? []].slice(0, 5), [E.data]), V = m(() => [...y.data?.items ?? []].sort((e, t) => new Date(t.updatedAt).getTime() - new Date(e.updatedAt).getTime()).slice(0, 4), [y.data]);
141
+ if (L) return /* @__PURE__ */ O(n, {
138
142
  title: "CoolAndLovely",
139
- children: /* @__PURE__ */ k(o, { label: "Loading your style command center…" })
143
+ children: /* @__PURE__ */ O(o, { label: "Loading your style command center…" })
140
144
  });
141
- if (z) return /* @__PURE__ */ k(n, {
145
+ if (R) return /* @__PURE__ */ O(n, {
142
146
  title: "CoolAndLovely",
143
- children: /* @__PURE__ */ k(a, {
147
+ children: /* @__PURE__ */ O(a, {
144
148
  title: "Could not load CoolAndLovely",
145
149
  message: "The fashion service did not respond. Please try again.",
146
150
  onRetry: () => {
147
- S.refetch(), D.refetch(), O.refetch(), F.refetch(), I.refetch();
151
+ y.refetch(), x.refetch(), E.refetch(), D.refetch(), F.refetch();
148
152
  }
149
153
  })
150
154
  });
151
- let U = [
155
+ let H = [
152
156
  {
153
- icon: /* @__PURE__ */ k(E, { className: "h-5 w-5" }),
154
- value: B.totalBrands.toString(),
157
+ icon: /* @__PURE__ */ O(T, { className: "h-5 w-5" }),
158
+ value: z.totalBrands.toString(),
155
159
  label: "Brands",
156
- sub: `${B.publishedBrands} published`
160
+ sub: `${z.publishedBrands} published`
157
161
  },
158
162
  {
159
- icon: /* @__PURE__ */ k(C, { className: "h-5 w-5" }),
160
- value: B.totalStyleItems.toString(),
163
+ icon: /* @__PURE__ */ O(S, { className: "h-5 w-5" }),
164
+ value: z.totalStyleItems.toString(),
161
165
  label: "Style Items",
162
- sub: `${B.activeStyleItems} active`
166
+ sub: `${z.activeStyleItems} active`
163
167
  },
164
168
  {
165
- icon: /* @__PURE__ */ k(w, { className: "h-5 w-5" }),
166
- value: B.totalLooks.toString(),
169
+ icon: /* @__PURE__ */ O(C, { className: "h-5 w-5" }),
170
+ value: z.totalLooks.toString(),
167
171
  label: "Looks",
168
- sub: `${B.featuredLooks} featured`
172
+ sub: `${z.featuredLooks} featured`
169
173
  },
170
174
  {
171
- icon: /* @__PURE__ */ k(y, { className: "h-5 w-5" }),
172
- value: B.activeCollaborations.toString(),
175
+ icon: /* @__PURE__ */ O(v, { className: "h-5 w-5" }),
176
+ value: z.activeCollaborations.toString(),
173
177
  label: "Active Collabs",
174
- sub: `${B.wardrobeItems} in wardrobe`
178
+ sub: `${z.wardrobeItems} in wardrobe`
175
179
  }
176
180
  ];
177
- return /* @__PURE__ */ A(n, {
178
- title: `Hello, ${L}`,
181
+ return /* @__PURE__ */ k(n, {
182
+ title: `${M()}, ${I}`,
179
183
  description: "Your fashion & lifestyle command center",
180
184
  hero: !0,
181
185
  children: [
182
- /* @__PURE__ */ k(M, {
186
+ /* @__PURE__ */ O(j, {
183
187
  className: "mb-6",
184
188
  children: "CoolAndLovely connects the three sides of style on one workspace-native model: brands launch storefronts and seasonal collections, you build a wardrobe and lookbooks, and creators publish shop-the-look outfits and run brand collaborations. Jump into any module below — all data is live from the CoolAndLovely service."
185
189
  }),
186
- /* @__PURE__ */ A(j, {
190
+ /* @__PURE__ */ k(A, {
187
191
  className: "mb-8",
188
- children: [/* @__PURE__ */ k("h2", {
192
+ children: [/* @__PURE__ */ O("h2", {
189
193
  className: "mb-4 text-lg font-semibold text-text-primary",
190
194
  children: "At a glance"
191
- }), /* @__PURE__ */ k("div", {
195
+ }), /* @__PURE__ */ O("div", {
192
196
  className: "grid grid-cols-2 gap-4 lg:grid-cols-4",
193
- children: U.map((e) => /* @__PURE__ */ k(r, {
197
+ children: H.map((e, t) => /* @__PURE__ */ O(r, {
194
198
  icon: e.icon,
195
199
  value: e.value,
196
200
  label: e.label,
197
201
  trendValue: e.sub,
198
- trend: "neutral"
202
+ trend: "neutral",
203
+ featured: t === 0
199
204
  }, e.label))
200
205
  })]
201
206
  }),
202
- /* @__PURE__ */ A("section", {
207
+ /* @__PURE__ */ k("section", {
203
208
  className: "mb-8",
204
- children: [/* @__PURE__ */ k("h2", {
209
+ children: [/* @__PURE__ */ O("h2", {
205
210
  className: "mb-4 text-lg font-semibold text-text-primary",
206
211
  children: "Quick actions"
207
- }), /* @__PURE__ */ k("div", {
212
+ }), /* @__PURE__ */ O("div", {
208
213
  className: "grid grid-cols-2 gap-4 lg:grid-cols-4",
209
- children: N.map((e) => /* @__PURE__ */ A("button", {
214
+ children: N.map((e) => /* @__PURE__ */ k("button", {
210
215
  type: "button",
211
- onClick: () => _(e.path),
216
+ onClick: () => g(e.path),
212
217
  className: t("flex items-start gap-3 rounded-lg border border-border-seam bg-bg-surface p-4 text-left shadow-sm transition-all", "hover:border-accent-foreground/20 hover:shadow-md"),
213
218
  children: [
214
- /* @__PURE__ */ k("div", {
219
+ /* @__PURE__ */ O("div", {
215
220
  className: t("flex h-10 w-10 shrink-0 items-center justify-center rounded-lg", e.color),
216
221
  children: e.icon
217
222
  }),
218
- /* @__PURE__ */ A("div", {
223
+ /* @__PURE__ */ k("div", {
219
224
  className: "min-w-0 flex-1",
220
- children: [/* @__PURE__ */ k("p", {
225
+ children: [/* @__PURE__ */ O("p", {
221
226
  className: "text-sm font-semibold text-text-primary",
222
227
  children: e.label
223
- }), /* @__PURE__ */ k("p", {
228
+ }), /* @__PURE__ */ O("p", {
224
229
  className: "mt-0.5 text-xs text-text-secondary",
225
230
  children: e.description
226
231
  })]
227
232
  }),
228
- /* @__PURE__ */ k(x, { className: "mt-1 h-4 w-4 shrink-0 text-text-secondary" })
233
+ /* @__PURE__ */ O(b, { className: "mt-1 h-4 w-4 shrink-0 text-text-secondary" })
229
234
  ]
230
235
  }, e.label))
231
236
  })]
232
237
  }),
233
- /* @__PURE__ */ A("section", {
238
+ /* @__PURE__ */ k("section", {
234
239
  className: "mb-8",
235
- children: [/* @__PURE__ */ k("h2", {
240
+ children: [/* @__PURE__ */ O("h2", {
236
241
  className: "mb-4 text-lg font-semibold text-text-primary",
237
242
  children: "Explore"
238
- }), /* @__PURE__ */ k("div", {
243
+ }), /* @__PURE__ */ O("div", {
239
244
  className: "grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4",
240
- children: P.map((e) => /* @__PURE__ */ A("button", {
245
+ children: P.map((e) => /* @__PURE__ */ k("button", {
241
246
  type: "button",
242
- onClick: () => _(e.path),
247
+ onClick: () => g(e.path),
243
248
  className: "flex flex-col gap-3 rounded-lg border border-border-seam bg-bg-surface p-5 text-left transition-all hover:border-accent-foreground/20 hover:shadow-md",
244
- children: [/* @__PURE__ */ k("div", {
249
+ children: [/* @__PURE__ */ O("div", {
245
250
  className: t("flex h-12 w-12 items-center justify-center rounded-full", e.color),
246
251
  children: e.icon
247
- }), /* @__PURE__ */ A("div", { children: [/* @__PURE__ */ k("p", {
252
+ }), /* @__PURE__ */ k("div", { children: [/* @__PURE__ */ O("p", {
248
253
  className: "text-sm font-semibold text-text-primary",
249
254
  children: e.label
250
- }), /* @__PURE__ */ k("p", {
255
+ }), /* @__PURE__ */ O("p", {
251
256
  className: "mt-0.5 text-xs text-text-secondary",
252
257
  children: e.description
253
258
  })] })]
254
259
  }, e.label))
255
260
  })]
256
261
  }),
257
- /* @__PURE__ */ A("section", {
262
+ /* @__PURE__ */ k("section", {
258
263
  className: "mb-8",
259
- children: [/* @__PURE__ */ A("div", {
264
+ children: [/* @__PURE__ */ k("div", {
260
265
  className: "mb-4 flex items-center justify-between",
261
- children: [/* @__PURE__ */ k("h2", {
266
+ children: [/* @__PURE__ */ O("h2", {
262
267
  className: "text-lg font-semibold text-text-primary",
263
268
  children: "Latest looks"
264
- }), /* @__PURE__ */ A("button", {
269
+ }), /* @__PURE__ */ k("button", {
265
270
  type: "button",
266
- onClick: () => _("/looks"),
271
+ onClick: () => g("/looks"),
267
272
  className: "flex items-center gap-1 text-sm font-medium text-primary hover:underline",
268
- children: ["View all ", /* @__PURE__ */ k(g, { className: "h-3.5 w-3.5" })]
273
+ children: ["View all ", /* @__PURE__ */ O(h, { className: "h-3.5 w-3.5" })]
269
274
  })]
270
- }), V.length === 0 ? /* @__PURE__ */ k("p", {
275
+ }), B.length === 0 ? /* @__PURE__ */ O("p", {
271
276
  className: "rounded-lg border border-border-seam bg-bg-surface p-6 text-sm text-text-secondary",
272
277
  children: "No looks published yet. Be the first to publish a shop-the-look outfit."
273
- }) : /* @__PURE__ */ k("div", {
274
- className: "grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-6",
275
- children: V.map((e) => /* @__PURE__ */ A("button", {
276
- type: "button",
277
- onClick: () => _(`/looks/${e.id}`),
278
- className: "group overflow-hidden rounded-lg border border-border-seam bg-bg-surface text-left transition-all hover:border-accent-foreground/20 hover:shadow-md",
279
- children: [/* @__PURE__ */ k(s, {
280
- icon: /* @__PURE__ */ k(w, { className: "h-7 w-7" }),
281
- seed: e.id,
282
- fileId: e.image?.id,
283
- alt: e.title,
284
- className: "h-28 w-full"
285
- }), /* @__PURE__ */ A("div", {
286
- className: "p-3",
287
- children: [/* @__PURE__ */ k("p", {
288
- className: "truncate text-sm font-medium text-text-primary",
289
- children: e.title
290
- }), /* @__PURE__ */ A("div", {
291
- className: "mt-1.5 flex items-center justify-between",
292
- children: [/* @__PURE__ */ k("span", {
293
- className: "text-xs text-text-secondary",
294
- children: m(e.occasion)
295
- }), /* @__PURE__ */ A("span", {
296
- className: "flex items-center gap-1 text-xs text-text-secondary",
297
- children: [
298
- /* @__PURE__ */ k(b, { className: "h-3 w-3" }),
299
- " ",
300
- e.likeCount
301
- ]
302
- })]
303
- })]
304
- })]
278
+ }) : /* @__PURE__ */ O("div", {
279
+ className: "grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-5",
280
+ children: B.map((e) => /* @__PURE__ */ O(p, {
281
+ id: e.id,
282
+ title: e.title,
283
+ occasion: e.occasion,
284
+ imageFileId: e.image?.id,
285
+ likeCount: e.likeCount,
286
+ onOpen: () => g(`/looks/${e.id}`),
287
+ showActions: !0
305
288
  }, e.id))
306
289
  })]
307
290
  }),
308
- H.length > 0 && /* @__PURE__ */ A("section", { children: [/* @__PURE__ */ A("div", {
291
+ V.length > 0 && /* @__PURE__ */ k("section", { children: [/* @__PURE__ */ k("div", {
309
292
  className: "mb-4 flex items-center justify-between",
310
- children: [/* @__PURE__ */ k("h2", {
293
+ children: [/* @__PURE__ */ O("h2", {
311
294
  className: "text-lg font-semibold text-text-primary",
312
295
  children: "Recently updated brands"
313
- }), /* @__PURE__ */ A("button", {
296
+ }), /* @__PURE__ */ k("button", {
314
297
  type: "button",
315
- onClick: () => _("/brands"),
298
+ onClick: () => g("/brands"),
316
299
  className: "flex items-center gap-1 text-sm font-medium text-primary hover:underline",
317
- children: ["View all ", /* @__PURE__ */ k(g, { className: "h-3.5 w-3.5" })]
300
+ children: ["View all ", /* @__PURE__ */ O(h, { className: "h-3.5 w-3.5" })]
318
301
  })]
319
- }), /* @__PURE__ */ k("div", {
320
- className: "divide-y divide-border-seam rounded-lg border border-border-seam bg-bg-surface",
321
- children: H.map((e) => /* @__PURE__ */ A("button", {
302
+ }), /* @__PURE__ */ O("div", {
303
+ className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
304
+ children: V.map((e) => /* @__PURE__ */ k("button", {
322
305
  type: "button",
323
- onClick: () => _(`/brands/${e.id}`),
324
- className: "flex w-full items-center gap-4 px-4 py-3 text-left transition-colors hover:bg-bg-sunken/50",
306
+ onClick: () => g(`/brands/${e.id}`),
307
+ className: "group flex items-center gap-3 rounded-xl border border-border-seam bg-bg-surface p-3 text-left shadow-sm transition-all hover:border-accent-foreground/20 hover:shadow-md",
325
308
  children: [
326
- /* @__PURE__ */ k(s, {
327
- icon: /* @__PURE__ */ k(E, { className: "h-5 w-5" }),
309
+ /* @__PURE__ */ O(s, {
310
+ icon: /* @__PURE__ */ O(T, { className: "h-5 w-5" }),
328
311
  seed: e.id,
329
312
  fileId: e.logo?.id ?? e.cover?.id,
330
313
  alt: e.name,
331
- className: "h-11 w-11 shrink-0"
314
+ className: "h-11 w-11 shrink-0 rounded-full ring-2 ring-bg-surface"
332
315
  }),
333
- /* @__PURE__ */ A("div", {
316
+ /* @__PURE__ */ k("div", {
334
317
  className: "min-w-0 flex-1",
335
- children: [/* @__PURE__ */ A("div", {
336
- className: "flex items-center gap-2",
337
- children: [/* @__PURE__ */ k("p", {
318
+ children: [/* @__PURE__ */ k("div", {
319
+ className: "flex items-center gap-1.5",
320
+ children: [/* @__PURE__ */ O("p", {
338
321
  className: "truncate text-sm font-medium text-text-primary",
339
322
  children: e.name
340
- }), e.isFeatured && /* @__PURE__ */ k(T, { className: "h-3.5 w-3.5 fill-status-warning-text text-status-warning-text" })]
341
- }), /* @__PURE__ */ A("p", {
323
+ }), e.isFeatured && /* @__PURE__ */ O(w, { className: "h-3.5 w-3.5 shrink-0 fill-status-warning-text text-status-warning-text" })]
324
+ }), /* @__PURE__ */ k("p", {
342
325
  className: "truncate text-xs text-text-secondary",
343
326
  children: ["@", e.handle]
344
327
  })]
345
328
  }),
346
- /* @__PURE__ */ k(i, { status: e.status }),
347
- /* @__PURE__ */ k("span", {
348
- className: "hidden shrink-0 text-xs text-text-secondary sm:inline",
349
- children: p(e.updatedAt)
350
- })
329
+ /* @__PURE__ */ O(i, { status: e.status })
351
330
  ]
352
331
  }, e.id))
353
332
  })] })
@@ -1 +1 @@
1
- {"version":3,"file":"HomePage.js","names":[],"sources":["../../../src/coolandlovely/pages/HomePage.tsx"],"sourcesContent":["/**\n * Overview / Home Page\n * @module coolandlovely/pages\n *\n * The CoolAndLovely command center landing page: a style-operating-system\n * dashboard rolling up live catalog (brands, items), social (looks,\n * collaborations) and the shopper's own wardrobe — all from real `coo*` ops.\n */\n\nimport { useMemo } from 'react';\nimport {\n Store,\n Shirt,\n Sparkles,\n Handshake,\n Shapes,\n Heart,\n ArrowRight,\n Star,\n Plus,\n BookHeart,\n UserCircle,\n Compass,\n TrendingUp,\n} from 'lucide-react';\nimport { EmphasisPanel, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { MetricsCard } from '../components/MetricsCard';\nimport { StatusBadge } from '../components/StatusBadge';\nimport { LoadingView, ErrorView } from '../components/StateViews';\nimport { Thumbnail } from '../components/Thumbnail';\nimport { useCoolAndLovely } from '../context/CoolAndLovelyContext';\nimport { useBrands, useStyleItems, useLooks, useCollaborations, useWardrobeItems } from '../hooks';\nimport { formatRelativeTime, titleCase } from '../utils/formatters';\nimport { cn } from '../utils/cn';\nimport type { DashboardStats } from '../types';\n\ninterface QuickAction {\n label: string;\n description: string;\n icon: React.ReactNode;\n path: string;\n color: string;\n}\n\nconst quickActions: QuickAction[] = [\n {\n label: 'New Brand',\n description: 'Launch a storefront',\n icon: <Store className=\"h-5 w-5\" />,\n path: '/brands/new',\n color: 'bg-accent-purple-subtle text-text-primary',\n },\n {\n label: 'Add Style Item',\n description: 'List a piece',\n icon: <Shirt className=\"h-5 w-5\" />,\n path: '/items/new',\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'Publish a Look',\n description: 'Shop-the-look outfit',\n icon: <Sparkles className=\"h-5 w-5\" />,\n path: '/looks/new',\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n {\n label: 'My Wardrobe',\n description: 'What you own',\n icon: <Heart className=\"h-5 w-5\" />,\n path: '/wardrobe',\n color: 'bg-status-warning-bg-subtle text-status-warning-text',\n },\n];\n\nconst modules = [\n {\n label: 'Brands',\n description: 'Storefronts with a publish lifecycle',\n icon: <Store className=\"h-6 w-6\" />,\n path: '/brands',\n color: 'bg-accent-purple-subtle text-text-primary',\n },\n {\n label: 'Collections',\n description: 'Seasonal drops & curated edits',\n icon: <Shapes className=\"h-6 w-6\" />,\n path: '/collections',\n color: 'bg-accent-blue-subtle text-accent-blue',\n },\n {\n label: 'Style Items',\n description: 'The shoppable catalogue',\n icon: <Shirt className=\"h-6 w-6\" />,\n path: '/items',\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'Looks',\n description: 'Published shop-the-look outfits',\n icon: <Sparkles className=\"h-6 w-6\" />,\n path: '/looks',\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n {\n label: 'Collaborations',\n description: 'Brand × creator partnerships',\n icon: <Handshake className=\"h-6 w-6\" />,\n path: '/collaborations',\n color: 'bg-status-warning-bg-subtle text-status-warning-text',\n },\n {\n label: 'Wardrobe',\n description: 'Your digital closet & wear log',\n icon: <Heart className=\"h-6 w-6\" />,\n path: '/wardrobe',\n color: 'bg-status-error-bg-subtle text-status-error-text',\n },\n {\n label: 'Lookbooks',\n description: 'Themed boards of saved pieces',\n icon: <BookHeart className=\"h-6 w-6\" />,\n path: '/lookbooks',\n color: 'bg-accent-purple-subtle text-text-primary',\n },\n {\n label: 'Style Profile',\n description: 'Your taste, palette & sizing',\n icon: <UserCircle className=\"h-6 w-6\" />,\n path: '/profile',\n color: 'bg-accent-blue-subtle text-accent-blue',\n },\n {\n label: 'Discover',\n description: 'A feed tuned to your taste',\n icon: <Compass className=\"h-6 w-6\" />,\n path: '/discover',\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'Trends',\n description: 'Live signals from platform activity',\n icon: <TrendingUp className=\"h-6 w-6\" />,\n path: '/trends',\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n];\n\nexport function HomePage() {\n const { navigateTo, currentUser } = useCoolAndLovely();\n\n const brands = useBrands();\n const items = useStyleItems();\n const looks = useLooks();\n const collaborations = useCollaborations();\n const wardrobe = useWardrobeItems();\n\n const firstName = currentUser?.firstName ?? currentUser?.name ?? 'there';\n\n const isLoading =\n brands.isLoading ||\n items.isLoading ||\n looks.isLoading ||\n collaborations.isLoading ||\n wardrobe.isLoading;\n\n const isError = brands.isError && items.isError && looks.isError && collaborations.isError;\n\n const stats = useMemo<DashboardStats>(() => {\n const brandItems = brands.data?.items ?? [];\n const styleItems = items.data?.items ?? [];\n const lookItems = looks.data?.items ?? [];\n const collabs = collaborations.data ?? [];\n const wardrobeItems = wardrobe.data ?? [];\n return {\n totalBrands: brandItems.length,\n publishedBrands: brandItems.filter((b) => b.status === 'PUBLISHED').length,\n totalStyleItems: styleItems.length,\n activeStyleItems: styleItems.filter((i) => i.status === 'ACTIVE').length,\n totalLooks: lookItems.length,\n featuredLooks: lookItems.filter((l) => l.isFeatured).length,\n activeCollaborations: collabs.filter(\n (c) => c.status === 'ACCEPTED' || c.status === 'IN_PROGRESS'\n ).length,\n wardrobeItems: wardrobeItems.length,\n };\n }, [brands.data, items.data, looks.data, collaborations.data, wardrobe.data]);\n\n const latestLooks = useMemo(() => [...(looks.data?.items ?? [])].slice(0, 6), [looks.data]);\n\n const recentBrands = useMemo(\n () =>\n [...(brands.data?.items ?? [])]\n .sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime())\n .slice(0, 4),\n [brands.data]\n );\n\n if (isLoading) {\n return (\n <PageLayout title=\"CoolAndLovely\">\n <LoadingView label=\"Loading your style command center…\" />\n </PageLayout>\n );\n }\n\n if (isError) {\n return (\n <PageLayout title=\"CoolAndLovely\">\n <ErrorView\n title=\"Could not load CoolAndLovely\"\n message=\"The fashion service did not respond. Please try again.\"\n onRetry={() => {\n void brands.refetch();\n void items.refetch();\n void looks.refetch();\n void collaborations.refetch();\n void wardrobe.refetch();\n }}\n />\n </PageLayout>\n );\n }\n\n const metrics = [\n {\n icon: <Store className=\"h-5 w-5\" />,\n value: stats.totalBrands.toString(),\n label: 'Brands',\n sub: `${stats.publishedBrands} published`,\n },\n {\n icon: <Shirt className=\"h-5 w-5\" />,\n value: stats.totalStyleItems.toString(),\n label: 'Style Items',\n sub: `${stats.activeStyleItems} active`,\n },\n {\n icon: <Sparkles className=\"h-5 w-5\" />,\n value: stats.totalLooks.toString(),\n label: 'Looks',\n sub: `${stats.featuredLooks} featured`,\n },\n {\n icon: <Handshake className=\"h-5 w-5\" />,\n value: stats.activeCollaborations.toString(),\n label: 'Active Collabs',\n sub: `${stats.wardrobeItems} in wardrobe`,\n },\n ];\n\n return (\n <PageLayout\n title={`Hello, ${firstName}`}\n description=\"Your fashion & lifestyle command center\"\n hero\n >\n <PagePurpose className=\"mb-6\">\n CoolAndLovely connects the three sides of style on one workspace-native model: brands launch\n storefronts and seasonal collections, you build a wardrobe and lookbooks, and creators\n publish shop-the-look outfits and run brand collaborations. Jump into any module below — all\n data is live from the CoolAndLovely service.\n </PagePurpose>\n\n {/* Headline metrics — the one emphasis zone for this page */}\n <EmphasisPanel className=\"mb-8\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">At a glance</h2>\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n {metrics.map((m) => (\n <MetricsCard\n key={m.label}\n icon={m.icon}\n value={m.value}\n label={m.label}\n trendValue={m.sub}\n trend=\"neutral\"\n />\n ))}\n </div>\n </EmphasisPanel>\n\n {/* Quick Actions */}\n <section className=\"mb-8\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Quick actions</h2>\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n {quickActions.map((action) => (\n <button\n key={action.label}\n type=\"button\"\n onClick={() => navigateTo(action.path)}\n className={cn(\n 'flex items-start gap-3 rounded-lg border border-border-seam bg-bg-surface p-4 text-left shadow-sm transition-all',\n 'hover:border-accent-foreground/20 hover:shadow-md'\n )}\n >\n <div\n className={cn(\n 'flex h-10 w-10 shrink-0 items-center justify-center rounded-lg',\n action.color\n )}\n >\n {action.icon}\n </div>\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-semibold text-text-primary\">{action.label}</p>\n <p className=\"mt-0.5 text-xs text-text-secondary\">{action.description}</p>\n </div>\n <Plus className=\"mt-1 h-4 w-4 shrink-0 text-text-secondary\" />\n </button>\n ))}\n </div>\n </section>\n\n {/* Modules */}\n <section className=\"mb-8\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Explore</h2>\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4\">\n {modules.map((mod) => (\n <button\n key={mod.label}\n type=\"button\"\n onClick={() => navigateTo(mod.path)}\n className=\"flex flex-col gap-3 rounded-lg border border-border-seam bg-bg-surface p-5 text-left transition-all hover:border-accent-foreground/20 hover:shadow-md\"\n >\n <div\n className={cn('flex h-12 w-12 items-center justify-center rounded-full', mod.color)}\n >\n {mod.icon}\n </div>\n <div>\n <p className=\"text-sm font-semibold text-text-primary\">{mod.label}</p>\n <p className=\"mt-0.5 text-xs text-text-secondary\">{mod.description}</p>\n </div>\n </button>\n ))}\n </div>\n </section>\n\n {/* Latest looks */}\n <section className=\"mb-8\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Latest looks</h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/looks')}\n className=\"flex items-center gap-1 text-sm font-medium text-primary hover:underline\"\n >\n View all <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n {latestLooks.length === 0 ? (\n <p className=\"rounded-lg border border-border-seam bg-bg-surface p-6 text-sm text-text-secondary\">\n No looks published yet. Be the first to publish a shop-the-look outfit.\n </p>\n ) : (\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-6\">\n {latestLooks.map((look) => (\n <button\n key={look.id}\n type=\"button\"\n onClick={() => navigateTo(`/looks/${look.id}`)}\n className=\"group overflow-hidden rounded-lg border border-border-seam bg-bg-surface text-left transition-all hover:border-accent-foreground/20 hover:shadow-md\"\n >\n <Thumbnail\n icon={<Sparkles className=\"h-7 w-7\" />}\n seed={look.id}\n fileId={look.image?.id}\n alt={look.title}\n className=\"h-28 w-full\"\n />\n <div className=\"p-3\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{look.title}</p>\n <div className=\"mt-1.5 flex items-center justify-between\">\n <span className=\"text-xs text-text-secondary\">{titleCase(look.occasion)}</span>\n <span className=\"flex items-center gap-1 text-xs text-text-secondary\">\n <Heart className=\"h-3 w-3\" /> {look.likeCount}\n </span>\n </div>\n </div>\n </button>\n ))}\n </div>\n )}\n </section>\n\n {/* Recent brands */}\n {recentBrands.length > 0 && (\n <section>\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Recently updated brands</h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/brands')}\n className=\"flex items-center gap-1 text-sm font-medium text-primary hover:underline\"\n >\n View all <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n <div className=\"divide-y divide-border-seam rounded-lg border border-border-seam bg-bg-surface\">\n {recentBrands.map((brand) => (\n <button\n key={brand.id}\n type=\"button\"\n onClick={() => navigateTo(`/brands/${brand.id}`)}\n className=\"flex w-full items-center gap-4 px-4 py-3 text-left transition-colors hover:bg-bg-sunken/50\"\n >\n <Thumbnail\n icon={<Store className=\"h-5 w-5\" />}\n seed={brand.id}\n fileId={brand.logo?.id ?? brand.cover?.id}\n alt={brand.name}\n className=\"h-11 w-11 shrink-0\"\n />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-2\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{brand.name}</p>\n {brand.isFeatured && (\n <Star className=\"h-3.5 w-3.5 fill-status-warning-text text-status-warning-text\" />\n )}\n </div>\n <p className=\"truncate text-xs text-text-secondary\">@{brand.handle}</p>\n </div>\n <StatusBadge status={brand.status} />\n <span className=\"hidden shrink-0 text-xs text-text-secondary sm:inline\">\n {formatRelativeTime(brand.updatedAt)}\n </span>\n </button>\n ))}\n </div>\n </section>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"HomePage.js","names":[],"sources":["../../../src/coolandlovely/pages/HomePage.tsx"],"sourcesContent":["/**\n * Overview / Home Page\n * @module coolandlovely/pages\n *\n * The CoolAndLovely command center landing page: a style-operating-system\n * dashboard rolling up live catalog (brands, items), social (looks,\n * collaborations) and the shopper's own wardrobe — all from real `coo*` ops.\n */\n\nimport { useMemo } from 'react';\nimport {\n Store,\n Shirt,\n Sparkles,\n Handshake,\n Shapes,\n Heart,\n ArrowRight,\n Star,\n Plus,\n BookHeart,\n UserCircle,\n Compass,\n TrendingUp,\n} from 'lucide-react';\nimport { EmphasisPanel, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { MetricsCard } from '../components/MetricsCard';\nimport { StatusBadge } from '../components/StatusBadge';\nimport { LoadingView, ErrorView } from '../components/StateViews';\nimport { Thumbnail } from '../components/Thumbnail';\nimport { LookCard } from '../components/LookCard';\nimport { useCoolAndLovely } from '../context/CoolAndLovelyContext';\nimport { useBrands, useStyleItems, useLooks, useCollaborations, useWardrobeItems } from '../hooks';\nimport { cn } from '../utils/cn';\nimport type { DashboardStats } from '../types';\n\n/** Time-of-day greeting for the dashboard title (local clock, honest — no data). */\nfunction greeting(): string {\n const hour = new Date().getHours();\n if (hour < 12) return 'Good morning';\n if (hour < 18) return 'Good afternoon';\n return 'Good evening';\n}\n\ninterface QuickAction {\n label: string;\n description: string;\n icon: React.ReactNode;\n path: string;\n color: string;\n}\n\nconst quickActions: QuickAction[] = [\n {\n label: 'New Brand',\n description: 'Launch a storefront',\n icon: <Store className=\"h-5 w-5\" />,\n path: '/brands/new',\n color: 'bg-accent-purple-subtle text-text-primary',\n },\n {\n label: 'Add Style Item',\n description: 'List a piece',\n icon: <Shirt className=\"h-5 w-5\" />,\n path: '/items/new',\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'Publish a Look',\n description: 'Shop-the-look outfit',\n icon: <Sparkles className=\"h-5 w-5\" />,\n path: '/looks/new',\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n {\n label: 'My Wardrobe',\n description: 'What you own',\n icon: <Heart className=\"h-5 w-5\" />,\n path: '/wardrobe',\n color: 'bg-status-warning-bg-subtle text-status-warning-text',\n },\n];\n\nconst modules = [\n {\n label: 'Brands',\n description: 'Storefronts with a publish lifecycle',\n icon: <Store className=\"h-6 w-6\" />,\n path: '/brands',\n color: 'bg-accent-purple-subtle text-text-primary',\n },\n {\n label: 'Collections',\n description: 'Seasonal drops & curated edits',\n icon: <Shapes className=\"h-6 w-6\" />,\n path: '/collections',\n color: 'bg-accent-blue-subtle text-accent-blue',\n },\n {\n label: 'Style Items',\n description: 'The shoppable catalogue',\n icon: <Shirt className=\"h-6 w-6\" />,\n path: '/items',\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'Looks',\n description: 'Published shop-the-look outfits',\n icon: <Sparkles className=\"h-6 w-6\" />,\n path: '/looks',\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n {\n label: 'Collaborations',\n description: 'Brand × creator partnerships',\n icon: <Handshake className=\"h-6 w-6\" />,\n path: '/collaborations',\n color: 'bg-status-warning-bg-subtle text-status-warning-text',\n },\n {\n label: 'Wardrobe',\n description: 'Your digital closet & wear log',\n icon: <Heart className=\"h-6 w-6\" />,\n path: '/wardrobe',\n color: 'bg-status-error-bg-subtle text-status-error-text',\n },\n {\n label: 'Lookbooks',\n description: 'Themed boards of saved pieces',\n icon: <BookHeart className=\"h-6 w-6\" />,\n path: '/lookbooks',\n color: 'bg-accent-purple-subtle text-text-primary',\n },\n {\n label: 'Style Profile',\n description: 'Your taste, palette & sizing',\n icon: <UserCircle className=\"h-6 w-6\" />,\n path: '/profile',\n color: 'bg-accent-blue-subtle text-accent-blue',\n },\n {\n label: 'Discover',\n description: 'A feed tuned to your taste',\n icon: <Compass className=\"h-6 w-6\" />,\n path: '/discover',\n color: 'bg-[var(--color-accent-soft)] text-text-primary',\n },\n {\n label: 'Trends',\n description: 'Live signals from platform activity',\n icon: <TrendingUp className=\"h-6 w-6\" />,\n path: '/trends',\n color: 'bg-status-success-bg-subtle text-status-success-text',\n },\n];\n\nexport function HomePage() {\n const { navigateTo, currentUser } = useCoolAndLovely();\n\n const brands = useBrands();\n const items = useStyleItems();\n const looks = useLooks();\n const collaborations = useCollaborations();\n const wardrobe = useWardrobeItems();\n\n const firstName = currentUser?.firstName ?? currentUser?.name ?? 'there';\n\n const isLoading =\n brands.isLoading ||\n items.isLoading ||\n looks.isLoading ||\n collaborations.isLoading ||\n wardrobe.isLoading;\n\n const isError = brands.isError && items.isError && looks.isError && collaborations.isError;\n\n const stats = useMemo<DashboardStats>(() => {\n const brandItems = brands.data?.items ?? [];\n const styleItems = items.data?.items ?? [];\n const lookItems = looks.data?.items ?? [];\n const collabs = collaborations.data ?? [];\n const wardrobeItems = wardrobe.data ?? [];\n return {\n totalBrands: brandItems.length,\n publishedBrands: brandItems.filter((b) => b.status === 'PUBLISHED').length,\n totalStyleItems: styleItems.length,\n activeStyleItems: styleItems.filter((i) => i.status === 'ACTIVE').length,\n totalLooks: lookItems.length,\n featuredLooks: lookItems.filter((l) => l.isFeatured).length,\n activeCollaborations: collabs.filter(\n (c) => c.status === 'ACCEPTED' || c.status === 'IN_PROGRESS'\n ).length,\n wardrobeItems: wardrobeItems.length,\n };\n }, [brands.data, items.data, looks.data, collaborations.data, wardrobe.data]);\n\n const latestLooks = useMemo(() => [...(looks.data?.items ?? [])].slice(0, 5), [looks.data]);\n\n const recentBrands = useMemo(\n () =>\n [...(brands.data?.items ?? [])]\n .sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime())\n .slice(0, 4),\n [brands.data]\n );\n\n if (isLoading) {\n return (\n <PageLayout title=\"CoolAndLovely\">\n <LoadingView label=\"Loading your style command center…\" />\n </PageLayout>\n );\n }\n\n if (isError) {\n return (\n <PageLayout title=\"CoolAndLovely\">\n <ErrorView\n title=\"Could not load CoolAndLovely\"\n message=\"The fashion service did not respond. Please try again.\"\n onRetry={() => {\n void brands.refetch();\n void items.refetch();\n void looks.refetch();\n void collaborations.refetch();\n void wardrobe.refetch();\n }}\n />\n </PageLayout>\n );\n }\n\n const metrics = [\n {\n icon: <Store className=\"h-5 w-5\" />,\n value: stats.totalBrands.toString(),\n label: 'Brands',\n sub: `${stats.publishedBrands} published`,\n },\n {\n icon: <Shirt className=\"h-5 w-5\" />,\n value: stats.totalStyleItems.toString(),\n label: 'Style Items',\n sub: `${stats.activeStyleItems} active`,\n },\n {\n icon: <Sparkles className=\"h-5 w-5\" />,\n value: stats.totalLooks.toString(),\n label: 'Looks',\n sub: `${stats.featuredLooks} featured`,\n },\n {\n icon: <Handshake className=\"h-5 w-5\" />,\n value: stats.activeCollaborations.toString(),\n label: 'Active Collabs',\n sub: `${stats.wardrobeItems} in wardrobe`,\n },\n ];\n\n return (\n <PageLayout\n title={`${greeting()}, ${firstName}`}\n description=\"Your fashion & lifestyle command center\"\n hero\n >\n <PagePurpose className=\"mb-6\">\n CoolAndLovely connects the three sides of style on one workspace-native model: brands launch\n storefronts and seasonal collections, you build a wardrobe and lookbooks, and creators\n publish shop-the-look outfits and run brand collaborations. Jump into any module below — all\n data is live from the CoolAndLovely service.\n </PagePurpose>\n\n {/* Headline metrics — the one emphasis zone for this page */}\n <EmphasisPanel className=\"mb-8\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">At a glance</h2>\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n {metrics.map((m, index) => (\n <MetricsCard\n key={m.label}\n icon={m.icon}\n value={m.value}\n label={m.label}\n trendValue={m.sub}\n trend=\"neutral\"\n featured={index === 0}\n />\n ))}\n </div>\n </EmphasisPanel>\n\n {/* Quick Actions */}\n <section className=\"mb-8\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Quick actions</h2>\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n {quickActions.map((action) => (\n <button\n key={action.label}\n type=\"button\"\n onClick={() => navigateTo(action.path)}\n className={cn(\n 'flex items-start gap-3 rounded-lg border border-border-seam bg-bg-surface p-4 text-left shadow-sm transition-all',\n 'hover:border-accent-foreground/20 hover:shadow-md'\n )}\n >\n <div\n className={cn(\n 'flex h-10 w-10 shrink-0 items-center justify-center rounded-lg',\n action.color\n )}\n >\n {action.icon}\n </div>\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-semibold text-text-primary\">{action.label}</p>\n <p className=\"mt-0.5 text-xs text-text-secondary\">{action.description}</p>\n </div>\n <Plus className=\"mt-1 h-4 w-4 shrink-0 text-text-secondary\" />\n </button>\n ))}\n </div>\n </section>\n\n {/* Modules */}\n <section className=\"mb-8\">\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">Explore</h2>\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4\">\n {modules.map((mod) => (\n <button\n key={mod.label}\n type=\"button\"\n onClick={() => navigateTo(mod.path)}\n className=\"flex flex-col gap-3 rounded-lg border border-border-seam bg-bg-surface p-5 text-left transition-all hover:border-accent-foreground/20 hover:shadow-md\"\n >\n <div\n className={cn('flex h-12 w-12 items-center justify-center rounded-full', mod.color)}\n >\n {mod.icon}\n </div>\n <div>\n <p className=\"text-sm font-semibold text-text-primary\">{mod.label}</p>\n <p className=\"mt-0.5 text-xs text-text-secondary\">{mod.description}</p>\n </div>\n </button>\n ))}\n </div>\n </section>\n\n {/* Latest looks */}\n <section className=\"mb-8\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Latest looks</h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/looks')}\n className=\"flex items-center gap-1 text-sm font-medium text-primary hover:underline\"\n >\n View all <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n {latestLooks.length === 0 ? (\n <p className=\"rounded-lg border border-border-seam bg-bg-surface p-6 text-sm text-text-secondary\">\n No looks published yet. Be the first to publish a shop-the-look outfit.\n </p>\n ) : (\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-5\">\n {latestLooks.map((look) => (\n <LookCard\n key={look.id}\n id={look.id}\n title={look.title}\n occasion={look.occasion}\n imageFileId={look.image?.id}\n likeCount={look.likeCount}\n onOpen={() => navigateTo(`/looks/${look.id}`)}\n showActions\n />\n ))}\n </div>\n )}\n </section>\n\n {/* Recent brands */}\n {recentBrands.length > 0 && (\n <section>\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Recently updated brands</h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/brands')}\n className=\"flex items-center gap-1 text-sm font-medium text-primary hover:underline\"\n >\n View all <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n {recentBrands.map((brand) => (\n <button\n key={brand.id}\n type=\"button\"\n onClick={() => navigateTo(`/brands/${brand.id}`)}\n className=\"group flex items-center gap-3 rounded-xl border border-border-seam bg-bg-surface p-3 text-left shadow-sm transition-all hover:border-accent-foreground/20 hover:shadow-md\"\n >\n <Thumbnail\n icon={<Store className=\"h-5 w-5\" />}\n seed={brand.id}\n fileId={brand.logo?.id ?? brand.cover?.id}\n alt={brand.name}\n className=\"h-11 w-11 shrink-0 rounded-full ring-2 ring-bg-surface\"\n />\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex items-center gap-1.5\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{brand.name}</p>\n {brand.isFeatured && (\n <Star className=\"h-3.5 w-3.5 shrink-0 fill-status-warning-text text-status-warning-text\" />\n )}\n </div>\n <p className=\"truncate text-xs text-text-secondary\">@{brand.handle}</p>\n </div>\n <StatusBadge status={brand.status} />\n </button>\n ))}\n </div>\n </section>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}