@burdenoff/microfe-coolandlovely 2026.706.1 → 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 (89) hide show
  1. package/dist/coolandlovely/CoolAndLovelyRoot.js +62 -46
  2. package/dist/coolandlovely/CoolAndLovelyRoot.js.map +1 -1
  3. package/dist/coolandlovely/CoolAndLovelyRoutes.js +14 -6
  4. package/dist/coolandlovely/CoolAndLovelyRoutes.js.map +1 -1
  5. package/dist/coolandlovely/components/ActorName.js +29 -0
  6. package/dist/coolandlovely/components/ActorName.js.map +1 -0
  7. package/dist/coolandlovely/components/AddToLookbookButton.js +81 -0
  8. package/dist/coolandlovely/components/AddToLookbookButton.js.map +1 -0
  9. package/dist/coolandlovely/components/BrandCover.js +39 -0
  10. package/dist/coolandlovely/components/BrandCover.js.map +1 -0
  11. package/dist/coolandlovely/components/BrandCreatorAvatars.js +57 -0
  12. package/dist/coolandlovely/components/BrandCreatorAvatars.js.map +1 -0
  13. package/dist/coolandlovely/components/ColourSwatchRow.js +86 -0
  14. package/dist/coolandlovely/components/ColourSwatchRow.js.map +1 -0
  15. package/dist/coolandlovely/components/Comments.js +109 -0
  16. package/dist/coolandlovely/components/Comments.js.map +1 -0
  17. package/dist/coolandlovely/components/Field.js +22 -2
  18. package/dist/coolandlovely/components/Field.js.map +1 -1
  19. package/dist/coolandlovely/components/FileImage.js +17 -0
  20. package/dist/coolandlovely/components/FileImage.js.map +1 -0
  21. package/dist/coolandlovely/components/FollowButton.js +24 -0
  22. package/dist/coolandlovely/components/FollowButton.js.map +1 -0
  23. package/dist/coolandlovely/components/ImageUploadField.js +153 -0
  24. package/dist/coolandlovely/components/ImageUploadField.js.map +1 -0
  25. package/dist/coolandlovely/components/LookCard.js +77 -0
  26. package/dist/coolandlovely/components/LookCard.js.map +1 -0
  27. package/dist/coolandlovely/components/MetricsCard.js +1 -1
  28. package/dist/coolandlovely/components/MetricsCard.js.map +1 -1
  29. package/dist/coolandlovely/components/ShopItemCard.js +45 -0
  30. package/dist/coolandlovely/components/ShopItemCard.js.map +1 -0
  31. package/dist/coolandlovely/components/StepTracker.js +35 -0
  32. package/dist/coolandlovely/components/StepTracker.js.map +1 -0
  33. package/dist/coolandlovely/components/Thumbnail.js +25 -14
  34. package/dist/coolandlovely/components/Thumbnail.js.map +1 -1
  35. package/dist/coolandlovely/components/VisibilityChip.js +32 -0
  36. package/dist/coolandlovely/components/VisibilityChip.js.map +1 -0
  37. package/dist/coolandlovely/hooks/index.js +2 -0
  38. package/dist/coolandlovely/hooks/useComments.js +68 -0
  39. package/dist/coolandlovely/hooks/useComments.js.map +1 -0
  40. package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js +155 -60
  41. package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js.map +1 -1
  42. package/dist/coolandlovely/hooks/useFiles.js +111 -0
  43. package/dist/coolandlovely/hooks/useFiles.js.map +1 -0
  44. package/dist/coolandlovely/pages/HomePage.js +130 -133
  45. package/dist/coolandlovely/pages/HomePage.js.map +1 -1
  46. package/dist/coolandlovely/pages/brands/BrandDetailPage.js +261 -228
  47. package/dist/coolandlovely/pages/brands/BrandDetailPage.js.map +1 -1
  48. package/dist/coolandlovely/pages/brands/BrandFormPage.js +146 -104
  49. package/dist/coolandlovely/pages/brands/BrandFormPage.js.map +1 -1
  50. package/dist/coolandlovely/pages/brands/BrandsListPage.js +13 -11
  51. package/dist/coolandlovely/pages/brands/BrandsListPage.js.map +1 -1
  52. package/dist/coolandlovely/pages/collaborations/CollaborationDetailPage.js +117 -95
  53. package/dist/coolandlovely/pages/collaborations/CollaborationDetailPage.js.map +1 -1
  54. package/dist/coolandlovely/pages/collaborations/CollaborationFormPage.js +1 -1
  55. package/dist/coolandlovely/pages/collaborations/CollaborationsListPage.js +50 -43
  56. package/dist/coolandlovely/pages/collaborations/CollaborationsListPage.js.map +1 -1
  57. package/dist/coolandlovely/pages/collections/CollectionDetailPage.js +134 -107
  58. package/dist/coolandlovely/pages/collections/CollectionDetailPage.js.map +1 -1
  59. package/dist/coolandlovely/pages/collections/CollectionFormPage.js +117 -102
  60. package/dist/coolandlovely/pages/collections/CollectionFormPage.js.map +1 -1
  61. package/dist/coolandlovely/pages/collections/CollectionsListPage.js +59 -54
  62. package/dist/coolandlovely/pages/collections/CollectionsListPage.js.map +1 -1
  63. package/dist/coolandlovely/pages/discover/DiscoverPage.js +223 -0
  64. package/dist/coolandlovely/pages/discover/DiscoverPage.js.map +1 -0
  65. package/dist/coolandlovely/pages/items/StyleItemDetailPage.js +176 -144
  66. package/dist/coolandlovely/pages/items/StyleItemDetailPage.js.map +1 -1
  67. package/dist/coolandlovely/pages/items/StyleItemFormPage.js +144 -130
  68. package/dist/coolandlovely/pages/items/StyleItemFormPage.js.map +1 -1
  69. package/dist/coolandlovely/pages/items/StyleItemsListPage.js +73 -62
  70. package/dist/coolandlovely/pages/items/StyleItemsListPage.js.map +1 -1
  71. package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.js +215 -102
  72. package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.js.map +1 -1
  73. package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.js +115 -86
  74. package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.js.map +1 -1
  75. package/dist/coolandlovely/pages/looks/LookDetailPage.js +217 -155
  76. package/dist/coolandlovely/pages/looks/LookDetailPage.js.map +1 -1
  77. package/dist/coolandlovely/pages/looks/LookFormPage.js +147 -96
  78. package/dist/coolandlovely/pages/looks/LookFormPage.js.map +1 -1
  79. package/dist/coolandlovely/pages/looks/LooksListPage.js +60 -95
  80. package/dist/coolandlovely/pages/looks/LooksListPage.js.map +1 -1
  81. package/dist/coolandlovely/pages/profile/StyleProfilePage.js +376 -146
  82. package/dist/coolandlovely/pages/profile/StyleProfilePage.js.map +1 -1
  83. package/dist/coolandlovely/pages/trends/TrendsPage.js +249 -0
  84. package/dist/coolandlovely/pages/trends/TrendsPage.js.map +1 -0
  85. package/dist/coolandlovely/pages/wardrobe/WardrobeFormPage.js +136 -88
  86. package/dist/coolandlovely/pages/wardrobe/WardrobeFormPage.js.map +1 -1
  87. package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.js +75 -74
  88. package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.js.map +1 -1
  89. package/package.json +1 -1
@@ -3,176 +3,196 @@ import { PageLayout as t } from "../../components/PageLayout.js";
3
3
  import { StatusBadge as n } from "../../components/StatusBadge.js";
4
4
  import { ErrorView as r, LoadingView as i } from "../../components/StateViews.js";
5
5
  import { Thumbnail as a } from "../../components/Thumbnail.js";
6
- import { useArchiveStyleItem as o, useStyleItem as s } from "../../hooks/useCoolAndLovelyApi.js";
6
+ import { useArchiveStyleItem as o, useLooksWithItems as s, useStyleItem as c } from "../../hooks/useCoolAndLovelyApi.js";
7
+ import { AddToLookbookButton as l } from "../../components/AddToLookbookButton.js";
8
+ import { formatDate as u, formatPrice as d, titleCase as f } from "../../utils/formatters.js";
9
+ import { LookCard as p } from "../../components/LookCard.js";
7
10
  import "../../hooks/index.js";
8
- import { formatDate as c, formatPrice as l, titleCase as u } from "../../utils/formatters.js";
9
- import { TagList as d } from "../../components/TagList.js";
10
- import { categoryIcon as f } from "../../utils/icons.js";
11
- import { Archive as p, ArrowLeft as m, Loader2 as h, Pencil as g, Shapes as _, Store as v } from "lucide-react";
12
- import { useParams as y } from "react-router-dom";
13
- import { jsx as b, jsxs as x } from "react/jsx-runtime";
14
- import { GlassCard as S } from "@burdenoff/fe-libs/ui";
11
+ import { TagList as m } from "../../components/TagList.js";
12
+ import { categoryIcon as h } from "../../utils/icons.js";
13
+ import { ColourSwatchRow as g } from "../../components/ColourSwatchRow.js";
14
+ import { Archive as _, ArrowLeft as v, ChevronRight as y, Loader2 as b, Pencil as x, Shapes as S } from "lucide-react";
15
+ import { useParams as C } from "react-router-dom";
16
+ import { jsx as w, jsxs as T } from "react/jsx-runtime";
17
+ import { GlassCard as E } from "@burdenoff/fe-libs/ui";
15
18
  //#region src/coolandlovely/pages/items/StyleItemDetailPage.tsx
16
- function C() {
17
- let { itemId: C } = y(), { navigateTo: w } = e(), T = s(C), E = o();
18
- if (T.isLoading) return /* @__PURE__ */ b(t, {
19
+ function D() {
20
+ let { itemId: D } = C(), { navigateTo: O } = e(), k = c(D), A = s({ pagination: {
21
+ limit: 100,
22
+ offset: 0
23
+ } }), j = o();
24
+ if (k.isLoading) return /* @__PURE__ */ w(t, {
19
25
  title: "Style item",
20
- children: /* @__PURE__ */ b(i, { label: "Loading item…" })
26
+ children: /* @__PURE__ */ w(i, { label: "Loading item…" })
21
27
  });
22
- if (T.isError || !T.data) return /* @__PURE__ */ b(t, {
28
+ if (k.isError || !k.data) return /* @__PURE__ */ w(t, {
23
29
  title: "Style item",
24
- children: /* @__PURE__ */ b(r, {
30
+ children: /* @__PURE__ */ w(r, {
25
31
  title: "Item not found",
26
- onRetry: () => void T.refetch()
32
+ onRetry: () => void k.refetch()
27
33
  })
28
34
  });
29
- let D = T.data, O = D.status === "RETIRED";
30
- return /* @__PURE__ */ b(t, {
31
- title: D.name,
32
- description: D.brand?.name ?? void 0,
33
- actions: /* @__PURE__ */ x("div", {
34
- className: "flex items-center gap-2",
35
+ let M = k.data, N = M.status === "RETIRED", P = (A.data?.items ?? []).filter((e) => e.items?.some((e) => e.styleItemId === M.id)).slice(0, 4);
36
+ return /* @__PURE__ */ T(t, {
37
+ title: M.name,
38
+ description: M.brand?.name ?? void 0,
39
+ actions: /* @__PURE__ */ T("div", {
40
+ className: "flex flex-wrap items-center gap-2",
35
41
  children: [
36
- /* @__PURE__ */ x("button", {
42
+ /* @__PURE__ */ T("button", {
37
43
  type: "button",
38
- onClick: () => w("/items"),
44
+ onClick: () => O("/items"),
39
45
  className: "inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
40
- children: [/* @__PURE__ */ b(m, { className: "h-4 w-4" }), " Back"]
46
+ children: [/* @__PURE__ */ w(v, { className: "h-4 w-4" }), " Back"]
41
47
  }),
42
- /* @__PURE__ */ x("button", {
48
+ /* @__PURE__ */ w(l, { styleItemId: M.id }),
49
+ /* @__PURE__ */ T("button", {
43
50
  type: "button",
44
- onClick: () => w(`/items/${D.id}/edit`),
51
+ onClick: () => O(`/items/${M.id}/edit`),
45
52
  className: "inline-flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg/90",
46
- children: [/* @__PURE__ */ b(g, { className: "h-4 w-4" }), " Edit"]
53
+ children: [/* @__PURE__ */ w(x, { className: "h-4 w-4" }), " Edit"]
47
54
  }),
48
- !O && /* @__PURE__ */ x("button", {
55
+ !N && /* @__PURE__ */ T("button", {
49
56
  type: "button",
50
- disabled: E.isPending,
51
- onClick: () => E.mutate(D.id, { onSuccess: () => w("/items") }),
57
+ disabled: j.isPending,
58
+ onClick: () => j.mutate(M.id, { onSuccess: () => O("/items") }),
52
59
  className: "inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-status-error-text transition-colors hover:bg-status-error-bg-subtle disabled:opacity-50",
53
- children: [E.isPending ? /* @__PURE__ */ b(h, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ b(p, { className: "h-4 w-4" }), "Archive"]
60
+ children: [j.isPending ? /* @__PURE__ */ w(b, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ w(_, { className: "h-4 w-4" }), "Archive"]
54
61
  })
55
62
  ]
56
63
  }),
57
- children: /* @__PURE__ */ x("div", {
64
+ children: [/* @__PURE__ */ T("div", {
58
65
  className: "grid grid-cols-1 gap-6 lg:grid-cols-3",
59
- children: [/* @__PURE__ */ b("div", {
66
+ children: [/* @__PURE__ */ w("div", {
60
67
  className: "lg:col-span-2",
61
- children: /* @__PURE__ */ x(S, {
68
+ children: /* @__PURE__ */ T(E, {
62
69
  treatment: "glass",
63
- className: "overflow-hidden p-0",
64
- children: [/* @__PURE__ */ b(a, {
65
- icon: f(D.category, 40),
66
- seed: D.id,
67
- className: "h-52 w-full"
68
- }), /* @__PURE__ */ x("div", {
70
+ className: "group overflow-hidden p-0",
71
+ children: [/* @__PURE__ */ w(a, {
72
+ icon: h(M.category, 48),
73
+ seed: M.id,
74
+ fileId: M.image?.id,
75
+ alt: M.name,
76
+ className: "aspect-[4/5] w-full"
77
+ }), M.description && /* @__PURE__ */ w("div", {
69
78
  className: "p-6",
70
- children: [
71
- /* @__PURE__ */ x("div", {
72
- className: "flex items-center gap-2",
73
- children: [/* @__PURE__ */ b("h2", {
74
- className: "text-xl font-semibold text-text-primary",
75
- children: D.name
76
- }), /* @__PURE__ */ b(n, {
77
- status: D.status,
78
- className: "ml-auto"
79
- })]
80
- }),
81
- /* @__PURE__ */ b("p", {
82
- className: "mt-1 text-2xl font-bold text-text-primary tabular-nums",
83
- children: l(D.price, D.currency)
84
- }),
85
- D.description && /* @__PURE__ */ b("p", {
86
- className: "mt-3 text-sm text-text-secondary",
87
- children: D.description
88
- }),
89
- /* @__PURE__ */ x("div", {
90
- className: "mt-5 grid grid-cols-1 gap-4 sm:grid-cols-2",
91
- children: [
92
- D.colours.length > 0 && /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("p", {
93
- className: "mb-1.5 text-xs font-medium uppercase tracking-wide text-text-secondary",
94
- children: "Colours"
95
- }), /* @__PURE__ */ b(d, {
96
- tags: D.colours,
97
- max: 10
98
- })] }),
99
- D.sizes.length > 0 && /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("p", {
100
- className: "mb-1.5 text-xs font-medium uppercase tracking-wide text-text-secondary",
101
- children: "Sizes"
102
- }), /* @__PURE__ */ b(d, {
103
- tags: D.sizes,
104
- max: 10
105
- })] }),
106
- D.materials.length > 0 && /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("p", {
107
- className: "mb-1.5 text-xs font-medium uppercase tracking-wide text-text-secondary",
108
- children: "Materials"
109
- }), /* @__PURE__ */ b(d, {
110
- tags: D.materials,
111
- max: 10
112
- })] }),
113
- D.tags.length > 0 && /* @__PURE__ */ x("div", { children: [/* @__PURE__ */ b("p", {
114
- className: "mb-1.5 text-xs font-medium uppercase tracking-wide text-text-secondary",
115
- children: "Tags"
116
- }), /* @__PURE__ */ b(d, {
117
- tags: D.tags,
118
- max: 10,
119
- tone: "accent"
120
- })] })
121
- ]
122
- })
123
- ]
79
+ children: /* @__PURE__ */ w("p", {
80
+ className: "text-sm leading-relaxed text-text-secondary",
81
+ children: M.description
82
+ })
124
83
  })]
125
84
  })
126
- }), /* @__PURE__ */ x("div", {
85
+ }), /* @__PURE__ */ T("div", {
127
86
  className: "space-y-4",
128
87
  children: [
129
- /* @__PURE__ */ x(S, {
88
+ /* @__PURE__ */ T(E, {
89
+ treatment: "glass",
90
+ className: "space-y-5 p-6",
91
+ children: [
92
+ /* @__PURE__ */ T("div", { children: [
93
+ /* @__PURE__ */ w("h2", {
94
+ className: "text-2xl font-semibold leading-tight text-text-primary",
95
+ children: M.name
96
+ }),
97
+ M.brand && /* @__PURE__ */ T("button", {
98
+ type: "button",
99
+ onClick: () => O(`/brands/${M.brand?.id}`),
100
+ className: "mt-1 inline-flex items-center gap-0.5 text-sm font-medium text-action-primary-bg hover:underline",
101
+ children: [M.brand.name, /* @__PURE__ */ w(y, { className: "h-3.5 w-3.5" })]
102
+ }),
103
+ /* @__PURE__ */ T("div", {
104
+ className: "mt-3 flex flex-wrap items-center justify-between gap-2",
105
+ children: [/* @__PURE__ */ T("p", {
106
+ className: "text-3xl font-bold text-text-primary tabular-nums",
107
+ children: [d(M.price, M.currency), /* @__PURE__ */ w("span", {
108
+ className: "ml-2 text-base font-medium text-text-secondary",
109
+ children: M.currency
110
+ })]
111
+ }), /* @__PURE__ */ w(n, { status: M.status })]
112
+ })
113
+ ] }),
114
+ /* @__PURE__ */ w("div", { className: "border-t border-border-seam" }),
115
+ M.colours.length > 0 && /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("p", {
116
+ className: "mb-2 text-xs font-medium uppercase tracking-wide text-text-secondary",
117
+ children: "Colours"
118
+ }), /* @__PURE__ */ w(g, {
119
+ colours: M.colours,
120
+ max: 12
121
+ })] }),
122
+ M.sizes.length > 0 && /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("p", {
123
+ className: "mb-2 text-xs font-medium uppercase tracking-wide text-text-secondary",
124
+ children: "Size"
125
+ }), /* @__PURE__ */ w("div", {
126
+ className: "flex flex-wrap gap-2",
127
+ children: M.sizes.map((e) => /* @__PURE__ */ w("span", {
128
+ className: "inline-flex min-w-9 items-center justify-center rounded-full border border-border-seam px-3 py-1 text-sm font-medium text-text-primary",
129
+ children: e
130
+ }, e))
131
+ })] }),
132
+ M.materials.length > 0 && /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("p", {
133
+ className: "mb-1 text-xs font-medium uppercase tracking-wide text-text-secondary",
134
+ children: "Materials"
135
+ }), /* @__PURE__ */ w("p", {
136
+ className: "text-sm text-text-primary",
137
+ children: M.materials.join(", ")
138
+ })] }),
139
+ M.tags.length > 0 && /* @__PURE__ */ T("div", { children: [/* @__PURE__ */ w("p", {
140
+ className: "mb-2 text-xs font-medium uppercase tracking-wide text-text-secondary",
141
+ children: "Tags"
142
+ }), /* @__PURE__ */ w(m, {
143
+ tags: M.tags,
144
+ max: 12,
145
+ tone: "accent"
146
+ })] })
147
+ ]
148
+ }),
149
+ /* @__PURE__ */ T(E, {
130
150
  treatment: "plain",
131
151
  className: "p-5",
132
- children: [/* @__PURE__ */ b("h3", {
152
+ children: [/* @__PURE__ */ w("h3", {
133
153
  className: "mb-3 text-sm font-semibold text-text-primary",
134
154
  children: "Details"
135
- }), /* @__PURE__ */ x("dl", {
155
+ }), /* @__PURE__ */ T("dl", {
136
156
  className: "space-y-2 text-sm",
137
157
  children: [
138
- /* @__PURE__ */ x("div", {
158
+ /* @__PURE__ */ T("div", {
139
159
  className: "flex justify-between gap-2",
140
- children: [/* @__PURE__ */ b("dt", {
160
+ children: [/* @__PURE__ */ w("dt", {
141
161
  className: "text-text-secondary",
142
162
  children: "Category"
143
- }), /* @__PURE__ */ b("dd", {
163
+ }), /* @__PURE__ */ w("dd", {
144
164
  className: "text-text-primary",
145
- children: u(D.category)
165
+ children: f(M.category)
146
166
  })]
147
167
  }),
148
- /* @__PURE__ */ x("div", {
168
+ /* @__PURE__ */ T("div", {
149
169
  className: "flex justify-between gap-2",
150
- children: [/* @__PURE__ */ b("dt", {
170
+ children: [/* @__PURE__ */ w("dt", {
151
171
  className: "text-text-secondary",
152
172
  children: "SKU"
153
- }), /* @__PURE__ */ b("dd", {
173
+ }), /* @__PURE__ */ w("dd", {
154
174
  className: "text-text-primary",
155
- children: D.sku ?? "—"
175
+ children: M.sku ?? "—"
156
176
  })]
157
177
  }),
158
- /* @__PURE__ */ x("div", {
178
+ /* @__PURE__ */ T("div", {
159
179
  className: "flex justify-between gap-2",
160
- children: [/* @__PURE__ */ b("dt", {
180
+ children: [/* @__PURE__ */ w("dt", {
161
181
  className: "text-text-secondary",
162
182
  children: "Currency"
163
- }), /* @__PURE__ */ b("dd", {
183
+ }), /* @__PURE__ */ w("dd", {
164
184
  className: "text-text-primary",
165
- children: D.currency
185
+ children: M.currency
166
186
  })]
167
187
  }),
168
- /* @__PURE__ */ x("div", {
188
+ /* @__PURE__ */ T("div", {
169
189
  className: "flex justify-between gap-2",
170
- children: [/* @__PURE__ */ b("dt", {
190
+ children: [/* @__PURE__ */ w("dt", {
171
191
  className: "text-text-secondary",
172
192
  children: "Created"
173
- }), /* @__PURE__ */ b("dd", {
193
+ }), /* @__PURE__ */ w("dd", {
174
194
  className: "text-text-primary",
175
- children: c(D.createdAt, {
195
+ children: u(M.createdAt, {
176
196
  hour: void 0,
177
197
  minute: void 0
178
198
  })
@@ -181,39 +201,20 @@ function C() {
181
201
  ]
182
202
  })]
183
203
  }),
184
- D.brand && /* @__PURE__ */ x("button", {
185
- type: "button",
186
- onClick: () => w(`/brands/${D.brand?.id}`),
187
- className: "flex w-full items-center gap-3 rounded-lg border border-border-seam bg-bg-surface p-4 text-left transition-colors hover:bg-bg-sunken/50",
188
- children: [/* @__PURE__ */ b(a, {
189
- icon: /* @__PURE__ */ b(v, { className: "h-5 w-5" }),
190
- seed: D.brand.id,
191
- className: "h-10 w-10 shrink-0"
192
- }), /* @__PURE__ */ x("div", {
193
- className: "min-w-0",
194
- children: [/* @__PURE__ */ b("p", {
195
- className: "truncate text-sm font-medium text-text-primary",
196
- children: D.brand.name
197
- }), /* @__PURE__ */ b("p", {
198
- className: "truncate text-xs text-text-secondary",
199
- children: "View brand"
200
- })]
201
- })]
202
- }),
203
- D.collection && /* @__PURE__ */ x("button", {
204
+ M.collection && /* @__PURE__ */ T("button", {
204
205
  type: "button",
205
- onClick: () => w(`/collections/${D.collection?.id}`),
206
+ onClick: () => O(`/collections/${M.collection?.id}`),
206
207
  className: "flex w-full items-center gap-3 rounded-lg border border-border-seam bg-bg-surface p-4 text-left transition-colors hover:bg-bg-sunken/50",
207
- children: [/* @__PURE__ */ b(a, {
208
- icon: /* @__PURE__ */ b(_, { className: "h-5 w-5" }),
209
- seed: D.collection.id,
208
+ children: [/* @__PURE__ */ w(a, {
209
+ icon: /* @__PURE__ */ w(S, { className: "h-5 w-5" }),
210
+ seed: M.collection.id,
210
211
  className: "h-10 w-10 shrink-0"
211
- }), /* @__PURE__ */ x("div", {
212
+ }), /* @__PURE__ */ T("div", {
212
213
  className: "min-w-0",
213
- children: [/* @__PURE__ */ b("p", {
214
+ children: [/* @__PURE__ */ w("p", {
214
215
  className: "truncate text-sm font-medium text-text-primary",
215
- children: D.collection.name
216
- }), /* @__PURE__ */ b("p", {
216
+ children: M.collection.name
217
+ }), /* @__PURE__ */ w("p", {
217
218
  className: "truncate text-xs text-text-secondary",
218
219
  children: "View collection"
219
220
  })]
@@ -221,10 +222,41 @@ function C() {
221
222
  })
222
223
  ]
223
224
  })]
224
- })
225
+ }), /* @__PURE__ */ T("section", {
226
+ className: "mt-8",
227
+ children: [/* @__PURE__ */ T("div", {
228
+ className: "mb-3 flex items-center justify-between gap-3",
229
+ children: [/* @__PURE__ */ w("h3", {
230
+ className: "text-lg font-semibold text-text-primary",
231
+ children: "Appears in looks"
232
+ }), P.length > 0 && /* @__PURE__ */ T("button", {
233
+ type: "button",
234
+ onClick: () => O("/looks"),
235
+ className: "inline-flex items-center gap-1 text-sm font-medium text-action-primary-bg hover:underline",
236
+ children: ["View all ", /* @__PURE__ */ w(y, { className: "h-3.5 w-3.5" })]
237
+ })]
238
+ }), A.isLoading ? /* @__PURE__ */ T("div", {
239
+ className: "flex items-center gap-2 rounded-lg border border-border-seam bg-bg-surface p-4 text-sm text-text-secondary",
240
+ children: [/* @__PURE__ */ w(b, { className: "h-4 w-4 animate-spin" }), " Loading referenced looks…"]
241
+ }) : P.length === 0 ? /* @__PURE__ */ w("p", {
242
+ className: "rounded-lg border border-border-seam bg-bg-surface p-4 text-sm text-text-secondary",
243
+ children: "This piece has not been tagged in any looks yet."
244
+ }) : /* @__PURE__ */ w("div", {
245
+ className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
246
+ children: P.map((e) => /* @__PURE__ */ w(p, {
247
+ id: e.id,
248
+ title: e.title,
249
+ occasion: e.occasion,
250
+ imageFileId: e.image?.id,
251
+ likeCount: e.likeCount,
252
+ onOpen: () => O(`/looks/${e.id}`),
253
+ showActions: !0
254
+ }, e.id))
255
+ })]
256
+ })]
225
257
  });
226
258
  }
227
259
  //#endregion
228
- export { C as StyleItemDetailPage };
260
+ export { D as StyleItemDetailPage };
229
261
 
230
262
  //# sourceMappingURL=StyleItemDetailPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"StyleItemDetailPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/items/StyleItemDetailPage.tsx"],"sourcesContent":["/**\n * Style Item Detail Page\n * @module coolandlovely/pages/items\n *\n * Renders a single catalogue piece (`cooStyleItem`) with edit + archive\n * (`cooArchiveStyleItem`) actions.\n */\n\nimport { useParams } from 'react-router-dom';\nimport { ArrowLeft, Pencil, Archive, Loader2, Store, Shapes } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { Thumbnail } from '../../components/Thumbnail';\nimport { TagList } from '../../components/TagList';\nimport { useCoolAndLovely } from '../../context/CoolAndLovelyContext';\nimport { useStyleItem, useArchiveStyleItem } from '../../hooks';\nimport { categoryIcon } from '../../utils/icons';\nimport { formatPrice, formatDate, titleCase } from '../../utils/formatters';\n\nexport function StyleItemDetailPage() {\n const { itemId } = useParams<{ itemId: string }>();\n const { navigateTo } = useCoolAndLovely();\n const query = useStyleItem(itemId);\n const archive = useArchiveStyleItem();\n\n if (query.isLoading) {\n return (\n <PageLayout title=\"Style item\">\n <LoadingView label=\"Loading item…\" />\n </PageLayout>\n );\n }\n\n if (query.isError || !query.data) {\n return (\n <PageLayout title=\"Style item\">\n <ErrorView title=\"Item not found\" onRetry={() => void query.refetch()} />\n </PageLayout>\n );\n }\n\n const item = query.data;\n const isArchived = item.status === 'RETIRED';\n\n return (\n <PageLayout\n title={item.name}\n description={item.brand?.name ?? undefined}\n actions={\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/items')}\n className=\"inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n <ArrowLeft className=\"h-4 w-4\" /> Back\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/items/${item.id}/edit`)}\n className=\"inline-flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg/90\"\n >\n <Pencil className=\"h-4 w-4\" /> Edit\n </button>\n {!isArchived && (\n <button\n type=\"button\"\n disabled={archive.isPending}\n onClick={() => archive.mutate(item.id, { onSuccess: () => navigateTo('/items') })}\n className=\"inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-status-error-text transition-colors hover:bg-status-error-bg-subtle disabled:opacity-50\"\n >\n {archive.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Archive className=\"h-4 w-4\" />\n )}\n Archive\n </button>\n )}\n </div>\n }\n >\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-3\">\n <div className=\"lg:col-span-2\">\n <GlassCard treatment=\"glass\" className=\"overflow-hidden p-0\">\n <Thumbnail\n icon={categoryIcon(item.category, 40)}\n seed={item.id}\n className=\"h-52 w-full\"\n />\n <div className=\"p-6\">\n <div className=\"flex items-center gap-2\">\n <h2 className=\"text-xl font-semibold text-text-primary\">{item.name}</h2>\n <StatusBadge status={item.status} className=\"ml-auto\" />\n </div>\n <p className=\"mt-1 text-2xl font-bold text-text-primary tabular-nums\">\n {formatPrice(item.price, item.currency)}\n </p>\n {item.description && (\n <p className=\"mt-3 text-sm text-text-secondary\">{item.description}</p>\n )}\n\n <div className=\"mt-5 grid grid-cols-1 gap-4 sm:grid-cols-2\">\n {item.colours.length > 0 && (\n <div>\n <p className=\"mb-1.5 text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Colours\n </p>\n <TagList tags={item.colours} max={10} />\n </div>\n )}\n {item.sizes.length > 0 && (\n <div>\n <p className=\"mb-1.5 text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Sizes\n </p>\n <TagList tags={item.sizes} max={10} />\n </div>\n )}\n {item.materials.length > 0 && (\n <div>\n <p className=\"mb-1.5 text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Materials\n </p>\n <TagList tags={item.materials} max={10} />\n </div>\n )}\n {item.tags.length > 0 && (\n <div>\n <p className=\"mb-1.5 text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Tags\n </p>\n <TagList tags={item.tags} max={10} tone=\"accent\" />\n </div>\n )}\n </div>\n </div>\n </GlassCard>\n </div>\n\n <div className=\"space-y-4\">\n <GlassCard treatment=\"plain\" className=\"p-5\">\n <h3 className=\"mb-3 text-sm font-semibold text-text-primary\">Details</h3>\n <dl className=\"space-y-2 text-sm\">\n <div className=\"flex justify-between gap-2\">\n <dt className=\"text-text-secondary\">Category</dt>\n <dd className=\"text-text-primary\">{titleCase(item.category)}</dd>\n </div>\n <div className=\"flex justify-between gap-2\">\n <dt className=\"text-text-secondary\">SKU</dt>\n <dd className=\"text-text-primary\">{item.sku ?? '—'}</dd>\n </div>\n <div className=\"flex justify-between gap-2\">\n <dt className=\"text-text-secondary\">Currency</dt>\n <dd className=\"text-text-primary\">{item.currency}</dd>\n </div>\n <div className=\"flex justify-between gap-2\">\n <dt className=\"text-text-secondary\">Created</dt>\n <dd className=\"text-text-primary\">\n {formatDate(item.createdAt, { hour: undefined, minute: undefined })}\n </dd>\n </div>\n </dl>\n </GlassCard>\n\n {item.brand && (\n <button\n type=\"button\"\n onClick={() => navigateTo(`/brands/${item.brand?.id}`)}\n className=\"flex w-full items-center gap-3 rounded-lg border border-border-seam bg-bg-surface p-4 text-left transition-colors hover:bg-bg-sunken/50\"\n >\n <Thumbnail\n icon={<Store className=\"h-5 w-5\" />}\n seed={item.brand.id}\n className=\"h-10 w-10 shrink-0\"\n />\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{item.brand.name}</p>\n <p className=\"truncate text-xs text-text-secondary\">View brand</p>\n </div>\n </button>\n )}\n\n {item.collection && (\n <button\n type=\"button\"\n onClick={() => navigateTo(`/collections/${item.collection?.id}`)}\n className=\"flex w-full items-center gap-3 rounded-lg border border-border-seam bg-bg-surface p-4 text-left transition-colors hover:bg-bg-sunken/50\"\n >\n <Thumbnail\n icon={<Shapes className=\"h-5 w-5\" />}\n seed={item.collection.id}\n className=\"h-10 w-10 shrink-0\"\n />\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {item.collection.name}\n </p>\n <p className=\"truncate text-xs text-text-secondary\">View collection</p>\n </div>\n </button>\n )}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"StyleItemDetailPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/items/StyleItemDetailPage.tsx"],"sourcesContent":["/**\n * Style Item Detail Page\n * @module coolandlovely/pages/items\n *\n * Renders a single catalogue piece (`cooStyleItem`) with edit + archive\n * (`cooArchiveStyleItem`) actions.\n */\n\nimport { useParams } from 'react-router-dom';\nimport { ArrowLeft, Pencil, Archive, Loader2, ChevronRight, Shapes } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { Thumbnail } from '../../components/Thumbnail';\nimport { LookCard } from '../../components/LookCard';\nimport { TagList } from '../../components/TagList';\nimport { ColourSwatchRow } from '../../components/ColourSwatchRow';\nimport { AddToLookbookButton } from '../../components/AddToLookbookButton';\nimport { useCoolAndLovely } from '../../context/CoolAndLovelyContext';\nimport { useStyleItem, useArchiveStyleItem, useLooksWithItems } from '../../hooks';\nimport { categoryIcon } from '../../utils/icons';\nimport { formatPrice, formatDate, titleCase } from '../../utils/formatters';\n\nexport function StyleItemDetailPage() {\n const { itemId } = useParams<{ itemId: string }>();\n const { navigateTo } = useCoolAndLovely();\n const query = useStyleItem(itemId);\n const looksQuery = useLooksWithItems({ pagination: { limit: 100, offset: 0 } });\n const archive = useArchiveStyleItem();\n\n if (query.isLoading) {\n return (\n <PageLayout title=\"Style item\">\n <LoadingView label=\"Loading item…\" />\n </PageLayout>\n );\n }\n\n if (query.isError || !query.data) {\n return (\n <PageLayout title=\"Style item\">\n <ErrorView title=\"Item not found\" onRetry={() => void query.refetch()} />\n </PageLayout>\n );\n }\n\n const item = query.data;\n const isArchived = item.status === 'RETIRED';\n const appearsInLooks = (looksQuery.data?.items ?? [])\n .filter((look) => look.items?.some((lookItem) => lookItem.styleItemId === item.id))\n .slice(0, 4);\n\n return (\n <PageLayout\n title={item.name}\n description={item.brand?.name ?? undefined}\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/items')}\n className=\"inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n <ArrowLeft className=\"h-4 w-4\" /> Back\n </button>\n <AddToLookbookButton styleItemId={item.id} />\n <button\n type=\"button\"\n onClick={() => navigateTo(`/items/${item.id}/edit`)}\n className=\"inline-flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg/90\"\n >\n <Pencil className=\"h-4 w-4\" /> Edit\n </button>\n {!isArchived && (\n <button\n type=\"button\"\n disabled={archive.isPending}\n onClick={() => archive.mutate(item.id, { onSuccess: () => navigateTo('/items') })}\n className=\"inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-status-error-text transition-colors hover:bg-status-error-bg-subtle disabled:opacity-50\"\n >\n {archive.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Archive className=\"h-4 w-4\" />\n )}\n Archive\n </button>\n )}\n </div>\n }\n >\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Product image */}\n <div className=\"lg:col-span-2\">\n <GlassCard treatment=\"glass\" className=\"group overflow-hidden p-0\">\n <Thumbnail\n icon={categoryIcon(item.category, 48)}\n seed={item.id}\n fileId={item.image?.id}\n alt={item.name}\n className=\"aspect-[4/5] w-full\"\n />\n {item.description && (\n <div className=\"p-6\">\n <p className=\"text-sm leading-relaxed text-text-secondary\">{item.description}</p>\n </div>\n )}\n </GlassCard>\n </div>\n\n {/* Product panel */}\n <div className=\"space-y-4\">\n <GlassCard treatment=\"glass\" className=\"space-y-5 p-6\">\n <div>\n <h2 className=\"text-2xl font-semibold leading-tight text-text-primary\">\n {item.name}\n </h2>\n {item.brand && (\n <button\n type=\"button\"\n onClick={() => navigateTo(`/brands/${item.brand?.id}`)}\n className=\"mt-1 inline-flex items-center gap-0.5 text-sm font-medium text-action-primary-bg hover:underline\"\n >\n {item.brand.name}\n <ChevronRight className=\"h-3.5 w-3.5\" />\n </button>\n )}\n <div className=\"mt-3 flex flex-wrap items-center justify-between gap-2\">\n <p className=\"text-3xl font-bold text-text-primary tabular-nums\">\n {formatPrice(item.price, item.currency)}\n <span className=\"ml-2 text-base font-medium text-text-secondary\">\n {item.currency}\n </span>\n </p>\n <StatusBadge status={item.status} />\n </div>\n </div>\n\n <div className=\"border-t border-border-seam\" />\n\n {item.colours.length > 0 && (\n <div>\n <p className=\"mb-2 text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Colours\n </p>\n <ColourSwatchRow colours={item.colours} max={12} />\n </div>\n )}\n\n {item.sizes.length > 0 && (\n <div>\n <p className=\"mb-2 text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Size\n </p>\n <div className=\"flex flex-wrap gap-2\">\n {item.sizes.map((size) => (\n <span\n key={size}\n className=\"inline-flex min-w-9 items-center justify-center rounded-full border border-border-seam px-3 py-1 text-sm font-medium text-text-primary\"\n >\n {size}\n </span>\n ))}\n </div>\n </div>\n )}\n\n {item.materials.length > 0 && (\n <div>\n <p className=\"mb-1 text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Materials\n </p>\n <p className=\"text-sm text-text-primary\">{item.materials.join(', ')}</p>\n </div>\n )}\n\n {item.tags.length > 0 && (\n <div>\n <p className=\"mb-2 text-xs font-medium uppercase tracking-wide text-text-secondary\">\n Tags\n </p>\n <TagList tags={item.tags} max={12} tone=\"accent\" />\n </div>\n )}\n </GlassCard>\n\n <GlassCard treatment=\"plain\" className=\"p-5\">\n <h3 className=\"mb-3 text-sm font-semibold text-text-primary\">Details</h3>\n <dl className=\"space-y-2 text-sm\">\n <div className=\"flex justify-between gap-2\">\n <dt className=\"text-text-secondary\">Category</dt>\n <dd className=\"text-text-primary\">{titleCase(item.category)}</dd>\n </div>\n <div className=\"flex justify-between gap-2\">\n <dt className=\"text-text-secondary\">SKU</dt>\n <dd className=\"text-text-primary\">{item.sku ?? '—'}</dd>\n </div>\n <div className=\"flex justify-between gap-2\">\n <dt className=\"text-text-secondary\">Currency</dt>\n <dd className=\"text-text-primary\">{item.currency}</dd>\n </div>\n <div className=\"flex justify-between gap-2\">\n <dt className=\"text-text-secondary\">Created</dt>\n <dd className=\"text-text-primary\">\n {formatDate(item.createdAt, { hour: undefined, minute: undefined })}\n </dd>\n </div>\n </dl>\n </GlassCard>\n\n {item.collection && (\n <button\n type=\"button\"\n onClick={() => navigateTo(`/collections/${item.collection?.id}`)}\n className=\"flex w-full items-center gap-3 rounded-lg border border-border-seam bg-bg-surface p-4 text-left transition-colors hover:bg-bg-sunken/50\"\n >\n <Thumbnail\n icon={<Shapes className=\"h-5 w-5\" />}\n seed={item.collection.id}\n className=\"h-10 w-10 shrink-0\"\n />\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {item.collection.name}\n </p>\n <p className=\"truncate text-xs text-text-secondary\">View collection</p>\n </div>\n </button>\n )}\n </div>\n </div>\n\n <section className=\"mt-8\">\n <div className=\"mb-3 flex items-center justify-between gap-3\">\n <h3 className=\"text-lg font-semibold text-text-primary\">Appears in looks</h3>\n {appearsInLooks.length > 0 && (\n <button\n type=\"button\"\n onClick={() => navigateTo('/looks')}\n className=\"inline-flex items-center gap-1 text-sm font-medium text-action-primary-bg hover:underline\"\n >\n View all <ChevronRight className=\"h-3.5 w-3.5\" />\n </button>\n )}\n </div>\n {looksQuery.isLoading ? (\n <div className=\"flex items-center gap-2 rounded-lg border border-border-seam bg-bg-surface p-4 text-sm text-text-secondary\">\n <Loader2 className=\"h-4 w-4 animate-spin\" /> Loading referenced looks…\n </div>\n ) : appearsInLooks.length === 0 ? (\n <p className=\"rounded-lg border border-border-seam bg-bg-surface p-4 text-sm text-text-secondary\">\n This piece has not been tagged in any looks yet.\n </p>\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n {appearsInLooks.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 </PageLayout>\n );\n}\n"],"mappings":"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"}