@burdenoff/microfe-coolandlovely 2026.706.1 → 2026.706.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/coolandlovely/CoolAndLovelyRoutes.js +14 -6
  2. package/dist/coolandlovely/CoolAndLovelyRoutes.js.map +1 -1
  3. package/dist/coolandlovely/components/ActorName.js +29 -0
  4. package/dist/coolandlovely/components/ActorName.js.map +1 -0
  5. package/dist/coolandlovely/components/AddToLookbookButton.js +81 -0
  6. package/dist/coolandlovely/components/AddToLookbookButton.js.map +1 -0
  7. package/dist/coolandlovely/components/Comments.js +109 -0
  8. package/dist/coolandlovely/components/Comments.js.map +1 -0
  9. package/dist/coolandlovely/components/Field.js +22 -2
  10. package/dist/coolandlovely/components/Field.js.map +1 -1
  11. package/dist/coolandlovely/components/FileImage.js +17 -0
  12. package/dist/coolandlovely/components/FileImage.js.map +1 -0
  13. package/dist/coolandlovely/components/FollowButton.js +24 -0
  14. package/dist/coolandlovely/components/FollowButton.js.map +1 -0
  15. package/dist/coolandlovely/components/ImageUploadField.js +71 -0
  16. package/dist/coolandlovely/components/ImageUploadField.js.map +1 -0
  17. package/dist/coolandlovely/components/Thumbnail.js +20 -13
  18. package/dist/coolandlovely/components/Thumbnail.js.map +1 -1
  19. package/dist/coolandlovely/hooks/index.js +2 -0
  20. package/dist/coolandlovely/hooks/useComments.js +68 -0
  21. package/dist/coolandlovely/hooks/useComments.js.map +1 -0
  22. package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js +74 -4
  23. package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js.map +1 -1
  24. package/dist/coolandlovely/hooks/useFiles.js +94 -0
  25. package/dist/coolandlovely/hooks/useFiles.js.map +1 -0
  26. package/dist/coolandlovely/pages/HomePage.js +105 -87
  27. package/dist/coolandlovely/pages/HomePage.js.map +1 -1
  28. package/dist/coolandlovely/pages/brands/BrandDetailPage.js +144 -122
  29. package/dist/coolandlovely/pages/brands/BrandDetailPage.js.map +1 -1
  30. package/dist/coolandlovely/pages/brands/BrandFormPage.js +128 -90
  31. package/dist/coolandlovely/pages/brands/BrandFormPage.js.map +1 -1
  32. package/dist/coolandlovely/pages/brands/BrandsListPage.js +2 -0
  33. package/dist/coolandlovely/pages/brands/BrandsListPage.js.map +1 -1
  34. package/dist/coolandlovely/pages/collections/CollectionDetailPage.js +5 -1
  35. package/dist/coolandlovely/pages/collections/CollectionDetailPage.js.map +1 -1
  36. package/dist/coolandlovely/pages/collections/CollectionFormPage.js +117 -102
  37. package/dist/coolandlovely/pages/collections/CollectionFormPage.js.map +1 -1
  38. package/dist/coolandlovely/pages/collections/CollectionsListPage.js +2 -0
  39. package/dist/coolandlovely/pages/collections/CollectionsListPage.js.map +1 -1
  40. package/dist/coolandlovely/pages/discover/DiscoverPage.js +223 -0
  41. package/dist/coolandlovely/pages/discover/DiscoverPage.js.map +1 -0
  42. package/dist/coolandlovely/pages/items/StyleItemDetailPage.js +99 -95
  43. package/dist/coolandlovely/pages/items/StyleItemDetailPage.js.map +1 -1
  44. package/dist/coolandlovely/pages/items/StyleItemFormPage.js +144 -130
  45. package/dist/coolandlovely/pages/items/StyleItemFormPage.js.map +1 -1
  46. package/dist/coolandlovely/pages/items/StyleItemsListPage.js +2 -0
  47. package/dist/coolandlovely/pages/items/StyleItemsListPage.js.map +1 -1
  48. package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.js +190 -99
  49. package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.js.map +1 -1
  50. package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.js +81 -68
  51. package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.js.map +1 -1
  52. package/dist/coolandlovely/pages/looks/LookDetailPage.js +195 -155
  53. package/dist/coolandlovely/pages/looks/LookDetailPage.js.map +1 -1
  54. package/dist/coolandlovely/pages/looks/LookFormPage.js +127 -88
  55. package/dist/coolandlovely/pages/looks/LookFormPage.js.map +1 -1
  56. package/dist/coolandlovely/pages/looks/LooksListPage.js +2 -0
  57. package/dist/coolandlovely/pages/looks/LooksListPage.js.map +1 -1
  58. package/dist/coolandlovely/pages/profile/StyleProfilePage.js +169 -101
  59. package/dist/coolandlovely/pages/profile/StyleProfilePage.js.map +1 -1
  60. package/dist/coolandlovely/pages/trends/TrendsPage.js +249 -0
  61. package/dist/coolandlovely/pages/trends/TrendsPage.js.map +1 -0
  62. package/dist/coolandlovely/pages/wardrobe/WardrobeFormPage.js +88 -76
  63. package/dist/coolandlovely/pages/wardrobe/WardrobeFormPage.js.map +1 -1
  64. package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.js +2 -0
  65. package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.js.map +1 -1
  66. package/package.json +1 -1
@@ -1,202 +1,242 @@
1
1
  import { useCoolAndLovely as e } from "../../context/CoolAndLovelyContext.js";
2
- import { PageLayout as t } from "../../components/PageLayout.js";
3
- import { StatusBadge as n } from "../../components/StatusBadge.js";
4
- import { ErrorView as r, LoadingView as i } from "../../components/StateViews.js";
5
- import { Thumbnail as a } from "../../components/Thumbnail.js";
6
- import { useDeleteLook as o, useLikeLook as s, useLook as c, usePublishLook as l } from "../../hooks/useCoolAndLovelyApi.js";
2
+ import { cn as t } from "../../utils/cn.js";
3
+ import { PageLayout as n } from "../../components/PageLayout.js";
4
+ import { StatusBadge as r } from "../../components/StatusBadge.js";
5
+ import { ErrorView as i, LoadingView as a } from "../../components/StateViews.js";
6
+ import { Thumbnail as o } from "../../components/Thumbnail.js";
7
+ import { useDeleteLook as s, useLikeLook as c, useLook as l, usePublishLook as u, useUpdateLook as d } from "../../hooks/useCoolAndLovelyApi.js";
7
8
  import "../../hooks/index.js";
8
- import { formatDate as u, formatPrice as d, titleCase as f } from "../../utils/formatters.js";
9
- import { TagList as p } from "../../components/TagList.js";
10
- import { ArrowLeft as m, Bookmark as h, Heart as g, Loader2 as _, Rocket as v, Sparkles as y, Star as b, Trash2 as x } from "lucide-react";
11
- import { useParams as S } from "react-router-dom";
12
- import { jsx as C, jsxs as w } from "react/jsx-runtime";
13
- import { GlassCard as T } from "@burdenoff/fe-libs/ui";
9
+ import { formatDate as f, formatPrice as p, titleCase as m } from "../../utils/formatters.js";
10
+ import { TagList as h } from "../../components/TagList.js";
11
+ import { ActorName as g } from "../../components/ActorName.js";
12
+ import { Comments as _ } from "../../components/Comments.js";
13
+ import { AddToLookbookButton as v } from "../../components/AddToLookbookButton.js";
14
+ import { FollowButton as y } from "../../components/FollowButton.js";
15
+ import { ArrowLeft as b, Bookmark as x, Heart as S, Loader2 as C, Rocket as w, Sparkles as T, Star as E, Trash2 as D } from "lucide-react";
16
+ import { useParams as O } from "react-router-dom";
17
+ import { jsx as k, jsxs as A } from "react/jsx-runtime";
18
+ import { GlassCard as j } from "@burdenoff/fe-libs/ui";
14
19
  //#region src/coolandlovely/pages/looks/LookDetailPage.tsx
15
- function E() {
16
- let { lookId: E } = S(), { navigateTo: D } = e(), O = c(E), k = s(), A = l(), j = o();
17
- if (O.isLoading) return /* @__PURE__ */ C(t, {
20
+ function M() {
21
+ let { lookId: M } = O(), { navigateTo: N, currentUser: P } = e(), F = l(M), I = c(), L = u(), R = s(), z = d();
22
+ if (F.isLoading) return /* @__PURE__ */ k(n, {
18
23
  title: "Look",
19
- children: /* @__PURE__ */ C(i, { label: "Loading look…" })
24
+ children: /* @__PURE__ */ k(a, { label: "Loading look…" })
20
25
  });
21
- if (O.isError || !O.data) return /* @__PURE__ */ C(t, {
26
+ if (F.isError || !F.data) return /* @__PURE__ */ k(n, {
22
27
  title: "Look",
23
- children: /* @__PURE__ */ C(r, {
28
+ children: /* @__PURE__ */ k(i, {
24
29
  title: "Look not found",
25
- onRetry: () => void O.refetch()
30
+ onRetry: () => void F.refetch()
26
31
  })
27
32
  });
28
- let M = O.data, N = M.items ?? [], P = M.publishedAt !== null;
29
- return /* @__PURE__ */ C(t, {
30
- title: M.title,
31
- description: f(M.occasion),
32
- actions: /* @__PURE__ */ w("div", {
33
- className: "flex items-center gap-2",
33
+ let B = F.data, V = B.items ?? [], H = B.publishedAt !== null, U = !!(P?.id && P.id === B.authorId);
34
+ return /* @__PURE__ */ k(n, {
35
+ title: B.title,
36
+ description: m(B.occasion),
37
+ actions: /* @__PURE__ */ A("div", {
38
+ className: "flex flex-wrap items-center gap-2",
34
39
  children: [
35
- /* @__PURE__ */ w("button", {
40
+ /* @__PURE__ */ A("button", {
36
41
  type: "button",
37
- onClick: () => D("/looks"),
42
+ onClick: () => N("/looks"),
38
43
  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",
39
- children: [/* @__PURE__ */ C(m, { className: "h-4 w-4" }), " Back"]
44
+ children: [/* @__PURE__ */ k(b, { className: "h-4 w-4" }), " Back"]
40
45
  }),
41
- !P && /* @__PURE__ */ w("button", {
46
+ /* @__PURE__ */ k(v, { lookId: B.id }),
47
+ /* @__PURE__ */ A("button", {
42
48
  type: "button",
43
- disabled: A.isPending,
44
- onClick: () => A.mutate(M.id),
49
+ disabled: z.isPending,
50
+ onClick: () => z.mutate({
51
+ id: B.id,
52
+ input: { isFeatured: !B.isFeatured }
53
+ }),
54
+ "aria-pressed": B.isFeatured,
55
+ className: t("inline-flex items-center gap-1.5 rounded-lg border px-3 py-2 text-sm font-medium transition-colors disabled:opacity-50", B.isFeatured ? "border-status-warning-text/40 bg-status-warning-bg-subtle text-status-warning-text" : "border-border-seam text-text-primary hover:bg-bg-sunken"),
56
+ children: [z.isPending ? /* @__PURE__ */ k(C, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ k(E, { className: t("h-4 w-4", B.isFeatured && "fill-status-warning-text") }), B.isFeatured ? "Featured" : "Feature"]
57
+ }),
58
+ !H && /* @__PURE__ */ A("button", {
59
+ type: "button",
60
+ disabled: L.isPending,
61
+ onClick: () => L.mutate(B.id),
45
62
  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 disabled:opacity-50",
46
- children: [A.isPending ? /* @__PURE__ */ C(_, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ C(v, { className: "h-4 w-4" }), "Publish"]
63
+ children: [L.isPending ? /* @__PURE__ */ k(C, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ k(w, { className: "h-4 w-4" }), "Publish"]
47
64
  }),
48
- /* @__PURE__ */ w("button", {
65
+ /* @__PURE__ */ A("button", {
49
66
  type: "button",
50
- disabled: j.isPending,
51
- onClick: () => j.mutate(M.id, { onSuccess: () => D("/looks") }),
67
+ disabled: R.isPending,
68
+ onClick: () => R.mutate(B.id, { onSuccess: () => N("/looks") }),
52
69
  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: [j.isPending ? /* @__PURE__ */ C(_, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ C(x, { className: "h-4 w-4" }), "Delete"]
70
+ children: [R.isPending ? /* @__PURE__ */ k(C, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ k(D, { className: "h-4 w-4" }), "Delete"]
54
71
  })
55
72
  ]
56
73
  }),
57
- children: /* @__PURE__ */ w("div", {
74
+ children: /* @__PURE__ */ A("div", {
58
75
  className: "grid grid-cols-1 gap-6 lg:grid-cols-3",
59
- children: [/* @__PURE__ */ w("div", {
76
+ children: [/* @__PURE__ */ A("div", {
60
77
  className: "lg:col-span-2",
61
- children: [/* @__PURE__ */ w(T, {
62
- treatment: "glass",
63
- className: "overflow-hidden p-0",
64
- children: [/* @__PURE__ */ C(a, {
65
- icon: /* @__PURE__ */ C(y, { className: "h-14 w-14" }),
66
- seed: M.id,
67
- className: "h-60 w-full"
68
- }), /* @__PURE__ */ w("div", {
69
- className: "p-6",
70
- children: [
71
- /* @__PURE__ */ w("div", {
72
- className: "flex items-center gap-2",
73
- children: [
74
- /* @__PURE__ */ C("h2", {
75
- className: "text-xl font-semibold text-text-primary",
76
- children: M.title
77
- }),
78
- M.isFeatured && /* @__PURE__ */ C(b, { className: "h-4 w-4 fill-status-warning-text text-status-warning-text" }),
79
- /* @__PURE__ */ C(n, {
80
- status: P ? "published" : "draft",
81
- className: "ml-auto"
82
- })
83
- ]
84
- }),
85
- M.caption && /* @__PURE__ */ C("p", {
86
- className: "mt-3 text-sm text-text-secondary",
87
- children: M.caption
88
- }),
89
- M.tags.length > 0 && /* @__PURE__ */ C(p, {
90
- tags: M.tags,
91
- className: "mt-4",
92
- tone: "accent"
93
- }),
94
- /* @__PURE__ */ w("div", {
95
- className: "mt-5 flex items-center gap-3",
96
- children: [/* @__PURE__ */ w("button", {
97
- type: "button",
98
- disabled: k.isPending,
99
- onClick: () => k.mutate(M.id),
100
- 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-status-error-bg-subtle disabled:opacity-50",
101
- children: [
102
- k.isPending ? /* @__PURE__ */ C(_, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ C(g, { className: "h-4 w-4" }),
103
- "Like · ",
104
- M.likeCount
105
- ]
106
- }), /* @__PURE__ */ w("span", {
107
- className: "inline-flex items-center gap-1.5 text-sm text-text-secondary",
78
+ children: [
79
+ /* @__PURE__ */ A(j, {
80
+ treatment: "glass",
81
+ className: "overflow-hidden p-0",
82
+ children: [/* @__PURE__ */ k(o, {
83
+ icon: /* @__PURE__ */ k(T, { className: "h-14 w-14" }),
84
+ seed: B.id,
85
+ fileId: B.image?.id,
86
+ alt: B.title,
87
+ className: "h-60 w-full"
88
+ }), /* @__PURE__ */ A("div", {
89
+ className: "p-6",
90
+ children: [
91
+ /* @__PURE__ */ A("div", {
92
+ className: "flex items-center gap-2",
108
93
  children: [
109
- /* @__PURE__ */ C(h, { className: "h-4 w-4" }),
110
- " ",
111
- M.saveCount,
112
- " saves"
94
+ /* @__PURE__ */ k("h2", {
95
+ className: "text-xl font-semibold text-text-primary",
96
+ children: B.title
97
+ }),
98
+ B.isFeatured && /* @__PURE__ */ k(E, { className: "h-4 w-4 fill-status-warning-text text-status-warning-text" }),
99
+ /* @__PURE__ */ k(r, {
100
+ status: H ? "published" : "draft",
101
+ className: "ml-auto"
102
+ })
113
103
  ]
114
- })]
115
- })
116
- ]
117
- })]
118
- }), /* @__PURE__ */ w("section", {
119
- className: "mt-6",
120
- children: [/* @__PURE__ */ w("h3", {
121
- className: "mb-3 text-lg font-semibold text-text-primary",
122
- children: [
123
- "Shop the look (",
124
- N.length,
125
- ")"
126
- ]
127
- }), N.length === 0 ? /* @__PURE__ */ C("p", {
128
- className: "rounded-lg border border-border-seam bg-bg-surface p-4 text-sm text-text-secondary",
129
- children: "No items tagged in this look yet."
130
- }) : /* @__PURE__ */ C("div", {
131
- className: "divide-y divide-border-seam rounded-lg border border-border-seam bg-bg-surface",
132
- children: [...N].sort((e, t) => e.position - t.position).map((e) => /* @__PURE__ */ w("button", {
133
- type: "button",
134
- onClick: () => e.styleItem && D(`/items/${e.styleItem.id}`),
135
- className: "flex w-full items-center gap-4 px-4 py-3 text-left transition-colors hover:bg-bg-sunken/50",
136
- children: [
137
- /* @__PURE__ */ C(a, {
138
- icon: /* @__PURE__ */ C(y, { className: "h-5 w-5" }),
139
- seed: e.id,
140
- className: "h-11 w-11 shrink-0"
141
104
  }),
142
- /* @__PURE__ */ w("div", {
143
- className: "min-w-0 flex-1",
144
- children: [/* @__PURE__ */ C("p", {
145
- className: "truncate text-sm font-medium text-text-primary",
146
- children: e.styleItem?.name ?? "Catalogue piece"
147
- }), e.styling && /* @__PURE__ */ C("p", {
148
- className: "truncate text-xs text-text-secondary",
149
- children: e.styling
105
+ B.caption && /* @__PURE__ */ k("p", {
106
+ className: "mt-3 text-sm text-text-secondary",
107
+ children: B.caption
108
+ }),
109
+ B.tags.length > 0 && /* @__PURE__ */ k(h, {
110
+ tags: B.tags,
111
+ className: "mt-4",
112
+ tone: "accent"
113
+ }),
114
+ /* @__PURE__ */ A("div", {
115
+ className: "mt-4 flex flex-wrap items-center gap-2 text-sm text-text-secondary",
116
+ children: [/* @__PURE__ */ A("span", { children: [
117
+ "By",
118
+ " ",
119
+ /* @__PURE__ */ k(g, {
120
+ id: B.authorId,
121
+ className: "font-medium text-text-primary"
122
+ })
123
+ ] }), !U && /* @__PURE__ */ k(y, {
124
+ followeeId: B.authorId,
125
+ size: "sm"
150
126
  })]
151
127
  }),
152
- e.styleItem && /* @__PURE__ */ C("span", {
153
- className: "shrink-0 text-sm font-semibold text-text-primary",
154
- children: d(e.styleItem.price, e.styleItem.currency)
128
+ /* @__PURE__ */ A("div", {
129
+ className: "mt-5 flex items-center gap-3",
130
+ children: [/* @__PURE__ */ A("button", {
131
+ type: "button",
132
+ disabled: I.isPending,
133
+ onClick: () => I.mutate(B.id),
134
+ 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-status-error-bg-subtle disabled:opacity-50",
135
+ children: [
136
+ I.isPending ? /* @__PURE__ */ k(C, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ k(S, { className: "h-4 w-4" }),
137
+ "Like · ",
138
+ B.likeCount
139
+ ]
140
+ }), /* @__PURE__ */ A("span", {
141
+ className: "inline-flex items-center gap-1.5 text-sm text-text-secondary",
142
+ children: [
143
+ /* @__PURE__ */ k(x, { className: "h-4 w-4" }),
144
+ " ",
145
+ B.saveCount,
146
+ " saves"
147
+ ]
148
+ })]
155
149
  })
156
150
  ]
157
- }, e.id))
158
- })]
159
- })]
160
- }), /* @__PURE__ */ w("div", {
151
+ })]
152
+ }),
153
+ /* @__PURE__ */ A("section", {
154
+ className: "mt-6",
155
+ children: [/* @__PURE__ */ A("h3", {
156
+ className: "mb-3 text-lg font-semibold text-text-primary",
157
+ children: [
158
+ "Shop the look (",
159
+ V.length,
160
+ ")"
161
+ ]
162
+ }), V.length === 0 ? /* @__PURE__ */ k("p", {
163
+ className: "rounded-lg border border-border-seam bg-bg-surface p-4 text-sm text-text-secondary",
164
+ children: "No items tagged in this look yet."
165
+ }) : /* @__PURE__ */ k("div", {
166
+ className: "divide-y divide-border-seam rounded-lg border border-border-seam bg-bg-surface",
167
+ children: [...V].sort((e, t) => e.position - t.position).map((e) => /* @__PURE__ */ A("button", {
168
+ type: "button",
169
+ onClick: () => e.styleItem && N(`/items/${e.styleItem.id}`),
170
+ className: "flex w-full items-center gap-4 px-4 py-3 text-left transition-colors hover:bg-bg-sunken/50",
171
+ children: [
172
+ /* @__PURE__ */ k(o, {
173
+ icon: /* @__PURE__ */ k(T, { className: "h-5 w-5" }),
174
+ seed: e.id,
175
+ className: "h-11 w-11 shrink-0"
176
+ }),
177
+ /* @__PURE__ */ A("div", {
178
+ className: "min-w-0 flex-1",
179
+ children: [/* @__PURE__ */ k("p", {
180
+ className: "truncate text-sm font-medium text-text-primary",
181
+ children: e.styleItem?.name ?? "Catalogue piece"
182
+ }), e.styling && /* @__PURE__ */ k("p", {
183
+ className: "truncate text-xs text-text-secondary",
184
+ children: e.styling
185
+ })]
186
+ }),
187
+ e.styleItem && /* @__PURE__ */ k("span", {
188
+ className: "shrink-0 text-sm font-semibold text-text-primary",
189
+ children: p(e.styleItem.price, e.styleItem.currency)
190
+ })
191
+ ]
192
+ }, e.id))
193
+ })]
194
+ }),
195
+ /* @__PURE__ */ k(_, {
196
+ entityType: "CooLook",
197
+ entityId: B.id
198
+ })
199
+ ]
200
+ }), /* @__PURE__ */ A("div", {
161
201
  className: "space-y-4",
162
202
  children: [
163
- /* @__PURE__ */ w(T, {
203
+ /* @__PURE__ */ A(j, {
164
204
  treatment: "plain",
165
205
  className: "p-5",
166
- children: [/* @__PURE__ */ C("h3", {
206
+ children: [/* @__PURE__ */ k("h3", {
167
207
  className: "mb-3 text-sm font-semibold text-text-primary",
168
208
  children: "Details"
169
- }), /* @__PURE__ */ w("dl", {
209
+ }), /* @__PURE__ */ A("dl", {
170
210
  className: "space-y-2 text-sm",
171
211
  children: [
172
- /* @__PURE__ */ w("div", {
212
+ /* @__PURE__ */ A("div", {
173
213
  className: "flex justify-between gap-2",
174
- children: [/* @__PURE__ */ C("dt", {
214
+ children: [/* @__PURE__ */ k("dt", {
175
215
  className: "text-text-secondary",
176
216
  children: "Occasion"
177
- }), /* @__PURE__ */ C("dd", {
217
+ }), /* @__PURE__ */ k("dd", {
178
218
  className: "text-text-primary",
179
- children: f(M.occasion)
219
+ children: m(B.occasion)
180
220
  })]
181
221
  }),
182
- /* @__PURE__ */ w("div", {
222
+ /* @__PURE__ */ A("div", {
183
223
  className: "flex justify-between gap-2",
184
- children: [/* @__PURE__ */ C("dt", {
224
+ children: [/* @__PURE__ */ k("dt", {
185
225
  className: "text-text-secondary",
186
226
  children: "Visibility"
187
- }), /* @__PURE__ */ C("dd", {
227
+ }), /* @__PURE__ */ k("dd", {
188
228
  className: "text-text-primary",
189
- children: f(M.visibility)
229
+ children: m(B.visibility)
190
230
  })]
191
231
  }),
192
- /* @__PURE__ */ w("div", {
232
+ /* @__PURE__ */ A("div", {
193
233
  className: "flex justify-between gap-2",
194
- children: [/* @__PURE__ */ C("dt", {
234
+ children: [/* @__PURE__ */ k("dt", {
195
235
  className: "text-text-secondary",
196
236
  children: "Published"
197
- }), /* @__PURE__ */ C("dd", {
237
+ }), /* @__PURE__ */ k("dd", {
198
238
  className: "text-text-primary",
199
- children: M.publishedAt ? u(M.publishedAt, {
239
+ children: B.publishedAt ? f(B.publishedAt, {
200
240
  hour: void 0,
201
241
  minute: void 0
202
242
  }) : "—"
@@ -205,27 +245,27 @@ function E() {
205
245
  ]
206
246
  })]
207
247
  }),
208
- M.collaborationId && /* @__PURE__ */ w("button", {
248
+ B.collaborationId && /* @__PURE__ */ A("button", {
209
249
  type: "button",
210
- onClick: () => D(`/collaborations/${M.collaborationId}`),
250
+ onClick: () => N(`/collaborations/${B.collaborationId}`),
211
251
  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",
212
- children: [/* @__PURE__ */ C("div", {
252
+ children: [/* @__PURE__ */ k("div", {
213
253
  className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-status-warning-bg-subtle text-status-warning-text",
214
- children: /* @__PURE__ */ C(y, { className: "h-5 w-5" })
215
- }), /* @__PURE__ */ w("div", {
254
+ children: /* @__PURE__ */ k(T, { className: "h-5 w-5" })
255
+ }), /* @__PURE__ */ A("div", {
216
256
  className: "min-w-0",
217
- children: [/* @__PURE__ */ C("p", {
257
+ children: [/* @__PURE__ */ k("p", {
218
258
  className: "truncate text-sm font-medium text-text-primary",
219
259
  children: "Part of a collaboration"
220
- }), /* @__PURE__ */ C("p", {
260
+ }), /* @__PURE__ */ k("p", {
221
261
  className: "truncate text-xs text-text-secondary",
222
262
  children: "View collaboration"
223
263
  })]
224
264
  })]
225
265
  }),
226
- (A.isError || j.isError || k.isError) && /* @__PURE__ */ C("p", {
266
+ (L.isError || R.isError || I.isError) && /* @__PURE__ */ k("p", {
227
267
  className: "rounded-lg bg-status-error-bg-subtle px-3 py-2 text-xs text-status-error-text",
228
- children: (A.error ?? j.error ?? k.error) instanceof Error ? (A.error ?? j.error ?? k.error)?.message : "Action failed"
268
+ children: (L.error ?? R.error ?? I.error) instanceof Error ? (L.error ?? R.error ?? I.error)?.message : "Action failed"
229
269
  })
230
270
  ]
231
271
  })]
@@ -233,6 +273,6 @@ function E() {
233
273
  });
234
274
  }
235
275
  //#endregion
236
- export { E as LookDetailPage };
276
+ export { M as LookDetailPage };
237
277
 
238
278
  //# sourceMappingURL=LookDetailPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"LookDetailPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/looks/LookDetailPage.tsx"],"sourcesContent":["/**\n * Look Detail Page\n * @module coolandlovely/pages/looks\n *\n * Single look (`cooLook`) with its look items, like (`cooLikeLook`), publish\n * (`cooPublishLook`) and delete (`cooDeleteLook`) actions.\n */\n\nimport { useParams } from 'react-router-dom';\nimport { ArrowLeft, Heart, Bookmark, Rocket, Trash2, Loader2, Sparkles, Star } 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 { useLook, useLikeLook, usePublishLook, useDeleteLook } from '../../hooks';\nimport { formatPrice, formatDate, titleCase } from '../../utils/formatters';\n\nexport function LookDetailPage() {\n const { lookId } = useParams<{ lookId: string }>();\n const { navigateTo } = useCoolAndLovely();\n const query = useLook(lookId);\n const like = useLikeLook();\n const publish = usePublishLook();\n const remove = useDeleteLook();\n\n if (query.isLoading) {\n return (\n <PageLayout title=\"Look\">\n <LoadingView label=\"Loading look…\" />\n </PageLayout>\n );\n }\n\n if (query.isError || !query.data) {\n return (\n <PageLayout title=\"Look\">\n <ErrorView title=\"Look not found\" onRetry={() => void query.refetch()} />\n </PageLayout>\n );\n }\n\n const look = query.data;\n const items = look.items ?? [];\n const isPublished = look.publishedAt !== null;\n\n return (\n <PageLayout\n title={look.title}\n description={titleCase(look.occasion)}\n actions={\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/looks')}\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 {!isPublished && (\n <button\n type=\"button\"\n disabled={publish.isPending}\n onClick={() => publish.mutate(look.id)}\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 disabled:opacity-50\"\n >\n {publish.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Rocket className=\"h-4 w-4\" />\n )}\n Publish\n </button>\n )}\n <button\n type=\"button\"\n disabled={remove.isPending}\n onClick={() => remove.mutate(look.id, { onSuccess: () => navigateTo('/looks') })}\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 {remove.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Trash2 className=\"h-4 w-4\" />\n )}\n Delete\n </button>\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={<Sparkles className=\"h-14 w-14\" />}\n seed={look.id}\n className=\"h-60 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\">{look.title}</h2>\n {look.isFeatured && (\n <Star className=\"h-4 w-4 fill-status-warning-text text-status-warning-text\" />\n )}\n <StatusBadge status={isPublished ? 'published' : 'draft'} className=\"ml-auto\" />\n </div>\n {look.caption && <p className=\"mt-3 text-sm text-text-secondary\">{look.caption}</p>}\n {look.tags.length > 0 && <TagList tags={look.tags} className=\"mt-4\" tone=\"accent\" />}\n\n <div className=\"mt-5 flex items-center gap-3\">\n <button\n type=\"button\"\n disabled={like.isPending}\n onClick={() => like.mutate(look.id)}\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-status-error-bg-subtle disabled:opacity-50\"\n >\n {like.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Heart className=\"h-4 w-4\" />\n )}\n Like · {look.likeCount}\n </button>\n <span className=\"inline-flex items-center gap-1.5 text-sm text-text-secondary\">\n <Bookmark className=\"h-4 w-4\" /> {look.saveCount} saves\n </span>\n </div>\n </div>\n </GlassCard>\n\n {/* Shop the look */}\n <section className=\"mt-6\">\n <h3 className=\"mb-3 text-lg font-semibold text-text-primary\">\n Shop the look ({items.length})\n </h3>\n {items.length === 0 ? (\n <p className=\"rounded-lg border border-border-seam bg-bg-surface p-4 text-sm text-text-secondary\">\n No items tagged in this look yet.\n </p>\n ) : (\n <div className=\"divide-y divide-border-seam rounded-lg border border-border-seam bg-bg-surface\">\n {[...items]\n .sort((a, b) => a.position - b.position)\n .map((li) => (\n <button\n key={li.id}\n type=\"button\"\n onClick={() => li.styleItem && navigateTo(`/items/${li.styleItem.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={<Sparkles className=\"h-5 w-5\" />}\n seed={li.id}\n className=\"h-11 w-11 shrink-0\"\n />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {li.styleItem?.name ?? 'Catalogue piece'}\n </p>\n {li.styling && (\n <p className=\"truncate text-xs text-text-secondary\">{li.styling}</p>\n )}\n </div>\n {li.styleItem && (\n <span className=\"shrink-0 text-sm font-semibold text-text-primary\">\n {formatPrice(li.styleItem.price, li.styleItem.currency)}\n </span>\n )}\n </button>\n ))}\n </div>\n )}\n </section>\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\">Occasion</dt>\n <dd className=\"text-text-primary\">{titleCase(look.occasion)}</dd>\n </div>\n <div className=\"flex justify-between gap-2\">\n <dt className=\"text-text-secondary\">Visibility</dt>\n <dd className=\"text-text-primary\">{titleCase(look.visibility)}</dd>\n </div>\n <div className=\"flex justify-between gap-2\">\n <dt className=\"text-text-secondary\">Published</dt>\n <dd className=\"text-text-primary\">\n {look.publishedAt\n ? formatDate(look.publishedAt, { hour: undefined, minute: undefined })\n : '—'}\n </dd>\n </div>\n </dl>\n </GlassCard>\n\n {look.collaborationId && (\n <button\n type=\"button\"\n onClick={() => navigateTo(`/collaborations/${look.collaborationId}`)}\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 <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-status-warning-bg-subtle text-status-warning-text\">\n <Sparkles className=\"h-5 w-5\" />\n </div>\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n Part of a collaboration\n </p>\n <p className=\"truncate text-xs text-text-secondary\">View collaboration</p>\n </div>\n </button>\n )}\n\n {(publish.isError || remove.isError || like.isError) && (\n <p className=\"rounded-lg bg-status-error-bg-subtle px-3 py-2 text-xs text-status-error-text\">\n {(publish.error ?? remove.error ?? like.error) instanceof Error\n ? (publish.error ?? remove.error ?? like.error)?.message\n : 'Action failed'}\n </p>\n )}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"LookDetailPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/looks/LookDetailPage.tsx"],"sourcesContent":["/**\n * Look Detail Page\n * @module coolandlovely/pages/looks\n *\n * Single look (`cooLook`) with its look items, like (`cooLikeLook`), publish\n * (`cooPublishLook`) and delete (`cooDeleteLook`) actions.\n */\n\nimport { useParams } from 'react-router-dom';\nimport { ArrowLeft, Heart, Bookmark, Rocket, Trash2, Loader2, Sparkles, Star } 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 { ActorName } from '../../components/ActorName';\nimport { Comments } from '../../components/Comments';\nimport { FollowButton } from '../../components/FollowButton';\nimport { AddToLookbookButton } from '../../components/AddToLookbookButton';\nimport { useCoolAndLovely } from '../../context/CoolAndLovelyContext';\nimport { useLook, useLikeLook, usePublishLook, useDeleteLook, useUpdateLook } from '../../hooks';\nimport { formatPrice, formatDate, titleCase } from '../../utils/formatters';\nimport { cn } from '../../utils/cn';\n\nexport function LookDetailPage() {\n const { lookId } = useParams<{ lookId: string }>();\n const { navigateTo, currentUser } = useCoolAndLovely();\n const query = useLook(lookId);\n const like = useLikeLook();\n const publish = usePublishLook();\n const remove = useDeleteLook();\n const update = useUpdateLook();\n\n if (query.isLoading) {\n return (\n <PageLayout title=\"Look\">\n <LoadingView label=\"Loading look…\" />\n </PageLayout>\n );\n }\n\n if (query.isError || !query.data) {\n return (\n <PageLayout title=\"Look\">\n <ErrorView title=\"Look not found\" onRetry={() => void query.refetch()} />\n </PageLayout>\n );\n }\n\n const look = query.data;\n const items = look.items ?? [];\n const isPublished = look.publishedAt !== null;\n const isOwnLook = Boolean(currentUser?.id && currentUser.id === look.authorId);\n\n return (\n <PageLayout\n title={look.title}\n description={titleCase(look.occasion)}\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/looks')}\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 lookId={look.id} />\n <button\n type=\"button\"\n disabled={update.isPending}\n onClick={() => update.mutate({ id: look.id, input: { isFeatured: !look.isFeatured } })}\n aria-pressed={look.isFeatured}\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-lg border px-3 py-2 text-sm font-medium transition-colors disabled:opacity-50',\n look.isFeatured\n ? 'border-status-warning-text/40 bg-status-warning-bg-subtle text-status-warning-text'\n : 'border-border-seam text-text-primary hover:bg-bg-sunken'\n )}\n >\n {update.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Star className={cn('h-4 w-4', look.isFeatured && 'fill-status-warning-text')} />\n )}\n {look.isFeatured ? 'Featured' : 'Feature'}\n </button>\n {!isPublished && (\n <button\n type=\"button\"\n disabled={publish.isPending}\n onClick={() => publish.mutate(look.id)}\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 disabled:opacity-50\"\n >\n {publish.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Rocket className=\"h-4 w-4\" />\n )}\n Publish\n </button>\n )}\n <button\n type=\"button\"\n disabled={remove.isPending}\n onClick={() => remove.mutate(look.id, { onSuccess: () => navigateTo('/looks') })}\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 {remove.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Trash2 className=\"h-4 w-4\" />\n )}\n Delete\n </button>\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={<Sparkles className=\"h-14 w-14\" />}\n seed={look.id}\n fileId={look.image?.id}\n alt={look.title}\n className=\"h-60 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\">{look.title}</h2>\n {look.isFeatured && (\n <Star className=\"h-4 w-4 fill-status-warning-text text-status-warning-text\" />\n )}\n <StatusBadge status={isPublished ? 'published' : 'draft'} className=\"ml-auto\" />\n </div>\n {look.caption && <p className=\"mt-3 text-sm text-text-secondary\">{look.caption}</p>}\n {look.tags.length > 0 && <TagList tags={look.tags} className=\"mt-4\" tone=\"accent\" />}\n\n <div className=\"mt-4 flex flex-wrap items-center gap-2 text-sm text-text-secondary\">\n <span>\n By{' '}\n <ActorName id={look.authorId} className=\"font-medium text-text-primary\" />\n </span>\n {!isOwnLook && <FollowButton followeeId={look.authorId} size=\"sm\" />}\n </div>\n\n <div className=\"mt-5 flex items-center gap-3\">\n <button\n type=\"button\"\n disabled={like.isPending}\n onClick={() => like.mutate(look.id)}\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-status-error-bg-subtle disabled:opacity-50\"\n >\n {like.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Heart className=\"h-4 w-4\" />\n )}\n Like · {look.likeCount}\n </button>\n <span className=\"inline-flex items-center gap-1.5 text-sm text-text-secondary\">\n <Bookmark className=\"h-4 w-4\" /> {look.saveCount} saves\n </span>\n </div>\n </div>\n </GlassCard>\n\n {/* Shop the look */}\n <section className=\"mt-6\">\n <h3 className=\"mb-3 text-lg font-semibold text-text-primary\">\n Shop the look ({items.length})\n </h3>\n {items.length === 0 ? (\n <p className=\"rounded-lg border border-border-seam bg-bg-surface p-4 text-sm text-text-secondary\">\n No items tagged in this look yet.\n </p>\n ) : (\n <div className=\"divide-y divide-border-seam rounded-lg border border-border-seam bg-bg-surface\">\n {[...items]\n .sort((a, b) => a.position - b.position)\n .map((li) => (\n <button\n key={li.id}\n type=\"button\"\n onClick={() => li.styleItem && navigateTo(`/items/${li.styleItem.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={<Sparkles className=\"h-5 w-5\" />}\n seed={li.id}\n className=\"h-11 w-11 shrink-0\"\n />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {li.styleItem?.name ?? 'Catalogue piece'}\n </p>\n {li.styling && (\n <p className=\"truncate text-xs text-text-secondary\">{li.styling}</p>\n )}\n </div>\n {li.styleItem && (\n <span className=\"shrink-0 text-sm font-semibold text-text-primary\">\n {formatPrice(li.styleItem.price, li.styleItem.currency)}\n </span>\n )}\n </button>\n ))}\n </div>\n )}\n </section>\n\n <Comments entityType=\"CooLook\" entityId={look.id} />\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\">Occasion</dt>\n <dd className=\"text-text-primary\">{titleCase(look.occasion)}</dd>\n </div>\n <div className=\"flex justify-between gap-2\">\n <dt className=\"text-text-secondary\">Visibility</dt>\n <dd className=\"text-text-primary\">{titleCase(look.visibility)}</dd>\n </div>\n <div className=\"flex justify-between gap-2\">\n <dt className=\"text-text-secondary\">Published</dt>\n <dd className=\"text-text-primary\">\n {look.publishedAt\n ? formatDate(look.publishedAt, { hour: undefined, minute: undefined })\n : '—'}\n </dd>\n </div>\n </dl>\n </GlassCard>\n\n {look.collaborationId && (\n <button\n type=\"button\"\n onClick={() => navigateTo(`/collaborations/${look.collaborationId}`)}\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 <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-status-warning-bg-subtle text-status-warning-text\">\n <Sparkles className=\"h-5 w-5\" />\n </div>\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n Part of a collaboration\n </p>\n <p className=\"truncate text-xs text-text-secondary\">View collaboration</p>\n </div>\n </button>\n )}\n\n {(publish.isError || remove.isError || like.isError) && (\n <p className=\"rounded-lg bg-status-error-bg-subtle px-3 py-2 text-xs text-status-error-text\">\n {(publish.error ?? remove.error ?? like.error) instanceof Error\n ? (publish.error ?? remove.error ?? like.error)?.message\n : 'Action failed'}\n </p>\n )}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}