@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
@@ -3,16 +3,17 @@ import { cn as t } from "../../utils/cn.js";
3
3
  import { PageLayout as n } from "../../components/PageLayout.js";
4
4
  import { StatusBadge as r } from "../../components/StatusBadge.js";
5
5
  import { ErrorView as i, LoadingView as a } from "../../components/StateViews.js";
6
- import { Thumbnail as o } from "../../components/Thumbnail.js";
7
- import { useCollaborations as s } from "../../hooks/useCoolAndLovelyApi.js";
6
+ import { useCollaborations as o } from "../../hooks/useCoolAndLovelyApi.js";
7
+ import { formatDate as s, formatPrice as c, titleCase as l } from "../../utils/formatters.js";
8
8
  import "../../hooks/index.js";
9
- import { formatDate as c, formatPrice as l, titleCase as u } from "../../utils/formatters.js";
9
+ import { ActorName as u } from "../../components/ActorName.js";
10
10
  import { EmptyState as d } from "../../components/EmptyState.js";
11
- import { useState as f } from "react";
12
- import { Handshake as p, Plus as m } from "lucide-react";
13
- import { jsx as h, jsxs as g } from "react/jsx-runtime";
11
+ import { BrandCreatorAvatars as f } from "../../components/BrandCreatorAvatars.js";
12
+ import { useState as p } from "react";
13
+ import { Handshake as m, Plus as h } from "lucide-react";
14
+ import { jsx as g, jsxs as _ } from "react/jsx-runtime";
14
15
  //#region src/coolandlovely/pages/collaborations/CollaborationsListPage.tsx
15
- var _ = [
16
+ var v = [
16
17
  {
17
18
  value: "ALL",
18
19
  label: "All"
@@ -42,78 +43,84 @@ var _ = [
42
43
  label: "Cancelled"
43
44
  }
44
45
  ];
45
- function v() {
46
- let { navigateTo: v } = e(), [y, b] = f("ALL"), x = s({ status: y === "ALL" ? void 0 : y }), S = x.data ?? [];
47
- return /* @__PURE__ */ g(n, {
46
+ function y() {
47
+ let { navigateTo: y } = e(), [b, x] = p("ALL"), S = o({ status: b === "ALL" ? void 0 : b }), C = S.data ?? [];
48
+ return /* @__PURE__ */ _(n, {
48
49
  title: "Collaborations",
49
50
  description: "Brand × creator partnerships with a real lifecycle",
50
- actions: /* @__PURE__ */ g("button", {
51
+ actions: /* @__PURE__ */ _("button", {
51
52
  type: "button",
52
- onClick: () => v("/collaborations/new"),
53
+ onClick: () => y("/collaborations/new"),
53
54
  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",
54
- children: [/* @__PURE__ */ h(m, { className: "h-4 w-4" }), " New collaboration"]
55
+ children: [/* @__PURE__ */ g(h, { className: "h-4 w-4" }), " New collaboration"]
55
56
  }),
56
- children: [/* @__PURE__ */ h("div", {
57
+ children: [/* @__PURE__ */ g("div", {
57
58
  className: "mb-6 flex flex-wrap items-center gap-2",
58
- children: _.map((e) => /* @__PURE__ */ h("button", {
59
+ children: v.map((e) => /* @__PURE__ */ g("button", {
59
60
  type: "button",
60
- onClick: () => b(e.value),
61
- className: t("rounded-full px-3 py-1.5 text-sm font-medium transition-colors", y === e.value ? "bg-action-primary-bg text-action-primary-text" : "bg-bg-sunken text-text-secondary hover:text-text-primary"),
61
+ onClick: () => x(e.value),
62
+ className: t("rounded-full px-3 py-1.5 text-sm font-medium transition-colors", b === e.value ? "bg-action-primary-bg text-action-primary-text" : "bg-bg-sunken text-text-secondary hover:text-text-primary"),
62
63
  children: e.label
63
64
  }, e.value))
64
- }), x.isLoading ? /* @__PURE__ */ h(a, { label: "Loading collaborations…" }) : x.isError ? /* @__PURE__ */ h(i, { onRetry: () => void x.refetch() }) : S.length === 0 ? /* @__PURE__ */ h(d, {
65
+ }), S.isLoading ? /* @__PURE__ */ g(a, { label: "Loading collaborations…" }) : S.isError ? /* @__PURE__ */ g(i, { onRetry: () => void S.refetch() }) : C.length === 0 ? /* @__PURE__ */ g(d, {
65
66
  illustration: "empty-data",
66
- icon: /* @__PURE__ */ h(p, { className: "h-10 w-10" }),
67
+ icon: /* @__PURE__ */ g(m, { className: "h-10 w-10" }),
67
68
  title: "No collaborations yet",
68
69
  description: "Propose a brand × creator partnership to get started.",
69
- action: /* @__PURE__ */ g("button", {
70
+ action: /* @__PURE__ */ _("button", {
70
71
  type: "button",
71
- onClick: () => v("/collaborations/new"),
72
+ onClick: () => y("/collaborations/new"),
72
73
  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",
73
- children: [/* @__PURE__ */ h(m, { className: "h-4 w-4" }), " New collaboration"]
74
+ children: [/* @__PURE__ */ g(h, { className: "h-4 w-4" }), " New collaboration"]
74
75
  })
75
- }) : /* @__PURE__ */ h("div", {
76
+ }) : /* @__PURE__ */ g("div", {
76
77
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
77
- children: S.map((e) => /* @__PURE__ */ g("button", {
78
+ children: C.map((e) => /* @__PURE__ */ _("button", {
78
79
  type: "button",
79
- onClick: () => v(`/collaborations/${e.id}`),
80
+ onClick: () => y(`/collaborations/${e.id}`),
80
81
  className: "flex flex-col 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",
81
82
  children: [
82
- /* @__PURE__ */ g("div", {
83
+ /* @__PURE__ */ _("div", {
83
84
  className: "flex items-start gap-3",
84
85
  children: [
85
- /* @__PURE__ */ h(o, {
86
- icon: /* @__PURE__ */ h(p, { className: "h-5 w-5" }),
87
- seed: e.id,
88
- className: "h-11 w-11 shrink-0"
86
+ /* @__PURE__ */ g(f, {
87
+ brandLogoFileId: e.brand?.logo?.id,
88
+ brandSeed: e.brandId,
89
+ creatorId: e.creatorId,
90
+ size: "sm",
91
+ className: "shrink-0"
89
92
  }),
90
- /* @__PURE__ */ g("div", {
93
+ /* @__PURE__ */ _("div", {
91
94
  className: "min-w-0 flex-1",
92
- children: [/* @__PURE__ */ h("h3", {
95
+ children: [/* @__PURE__ */ g("h3", {
93
96
  className: "truncate text-base font-semibold text-text-primary",
94
97
  children: e.title
95
- }), e.brand?.name && /* @__PURE__ */ h("p", {
98
+ }), /* @__PURE__ */ _("p", {
96
99
  className: "truncate text-xs text-text-secondary",
97
- children: e.brand.name
100
+ children: [
101
+ e.brand?.name ?? "Brand",
102
+ " × ",
103
+ /* @__PURE__ */ g(u, { id: e.creatorId })
104
+ ]
98
105
  })]
99
106
  }),
100
- /* @__PURE__ */ h(r, { status: e.status })
107
+ /* @__PURE__ */ g(r, { status: e.status })
101
108
  ]
102
109
  }),
103
- e.brief && /* @__PURE__ */ h("p", {
110
+ e.brief && /* @__PURE__ */ g("p", {
104
111
  className: "mt-3 line-clamp-2 text-sm text-text-secondary",
105
112
  children: e.brief
106
113
  }),
107
- /* @__PURE__ */ g("div", {
114
+ /* @__PURE__ */ _("div", {
108
115
  className: "mt-3 flex items-center justify-between text-xs text-text-secondary",
109
- children: [/* @__PURE__ */ h("span", {
116
+ children: [/* @__PURE__ */ g("span", {
110
117
  className: "rounded-full bg-bg-sunken px-2 py-0.5",
111
- children: u(e.role)
112
- }), /* @__PURE__ */ h("span", { children: l(e.compensation, e.currency) })]
118
+ children: l(e.role)
119
+ }), /* @__PURE__ */ g("span", { children: c(e.compensation, e.currency) })]
113
120
  }),
114
- e.startDate && /* @__PURE__ */ g("p", {
121
+ e.startDate && /* @__PURE__ */ _("p", {
115
122
  className: "mt-2 text-xs text-text-secondary",
116
- children: ["Starts ", c(e.startDate, {
123
+ children: ["Starts ", s(e.startDate, {
117
124
  hour: void 0,
118
125
  minute: void 0
119
126
  })]
@@ -124,6 +131,6 @@ function v() {
124
131
  });
125
132
  }
126
133
  //#endregion
127
- export { v as CollaborationsListPage };
134
+ export { y as CollaborationsListPage };
128
135
 
129
136
  //# sourceMappingURL=CollaborationsListPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CollaborationsListPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/collaborations/CollaborationsListPage.tsx"],"sourcesContent":["/**\n * Collaborations List Page\n * @module coolandlovely/pages/collaborations\n *\n * Lists brand × creator partnerships (`cooListCollaborations`) with status\n * filter.\n */\n\nimport { useState } from 'react';\nimport { Plus, Handshake } from 'lucide-react';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { Thumbnail } from '../../components/Thumbnail';\nimport { useCoolAndLovely } from '../../context/CoolAndLovelyContext';\nimport { useCollaborations } from '../../hooks';\nimport { formatPrice, formatDate, titleCase } from '../../utils/formatters';\nimport { cn } from '../../utils/cn';\nimport type { CooCollaborationStatus } from '../../types';\n\nconst STATUS_OPTIONS: Array<{ value: CooCollaborationStatus | 'ALL'; label: string }> = [\n { value: 'ALL', label: 'All' },\n { value: 'PROPOSED', label: 'Proposed' },\n { value: 'ACCEPTED', label: 'Accepted' },\n { value: 'IN_PROGRESS', label: 'In progress' },\n { value: 'PUBLISHED', label: 'Published' },\n { value: 'DECLINED', label: 'Declined' },\n { value: 'CANCELLED', label: 'Cancelled' },\n];\n\nexport function CollaborationsListPage() {\n const { navigateTo } = useCoolAndLovely();\n const [status, setStatus] = useState<CooCollaborationStatus | 'ALL'>('ALL');\n\n const query = useCollaborations({ status: status === 'ALL' ? undefined : status });\n const collaborations = query.data ?? [];\n\n return (\n <PageLayout\n title=\"Collaborations\"\n description=\"Brand × creator partnerships with a real lifecycle\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/collaborations/new')}\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 <Plus className=\"h-4 w-4\" /> New collaboration\n </button>\n }\n >\n <div className=\"mb-6 flex flex-wrap items-center gap-2\">\n {STATUS_OPTIONS.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n onClick={() => setStatus(opt.value)}\n className={cn(\n 'rounded-full px-3 py-1.5 text-sm font-medium transition-colors',\n status === opt.value\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-secondary hover:text-text-primary'\n )}\n >\n {opt.label}\n </button>\n ))}\n </div>\n\n {query.isLoading ? (\n <LoadingView label=\"Loading collaborations…\" />\n ) : query.isError ? (\n <ErrorView onRetry={() => void query.refetch()} />\n ) : collaborations.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Handshake className=\"h-10 w-10\" />}\n title=\"No collaborations yet\"\n description=\"Propose a brand × creator partnership to get started.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/collaborations/new')}\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\"\n >\n <Plus className=\"h-4 w-4\" /> New collaboration\n </button>\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {collaborations.map((c) => (\n <button\n key={c.id}\n type=\"button\"\n onClick={() => navigateTo(`/collaborations/${c.id}`)}\n className=\"flex flex-col 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\"\n >\n <div className=\"flex items-start gap-3\">\n <Thumbnail\n icon={<Handshake className=\"h-5 w-5\" />}\n seed={c.id}\n className=\"h-11 w-11 shrink-0\"\n />\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"truncate text-base font-semibold text-text-primary\">{c.title}</h3>\n {c.brand?.name && (\n <p className=\"truncate text-xs text-text-secondary\">{c.brand.name}</p>\n )}\n </div>\n <StatusBadge status={c.status} />\n </div>\n {c.brief && (\n <p className=\"mt-3 line-clamp-2 text-sm text-text-secondary\">{c.brief}</p>\n )}\n <div className=\"mt-3 flex items-center justify-between text-xs text-text-secondary\">\n <span className=\"rounded-full bg-bg-sunken px-2 py-0.5\">{titleCase(c.role)}</span>\n <span>{formatPrice(c.compensation, c.currency)}</span>\n </div>\n {c.startDate && (\n <p className=\"mt-2 text-xs text-text-secondary\">\n Starts {formatDate(c.startDate, { hour: undefined, minute: undefined })}\n </p>\n )}\n </button>\n ))}\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAqBA,IAAM,IAAkF;CACtF;EAAE,OAAO;EAAO,OAAO;EAAO;CAC9B;EAAE,OAAO;EAAY,OAAO;EAAY;CACxC;EAAE,OAAO;EAAY,OAAO;EAAY;CACxC;EAAE,OAAO;EAAe,OAAO;EAAe;CAC9C;EAAE,OAAO;EAAa,OAAO;EAAa;CAC1C;EAAE,OAAO;EAAY,OAAO;EAAY;CACxC;EAAE,OAAO;EAAa,OAAO;EAAa;CAC3C;AAED,SAAgB,IAAyB;CACvC,IAAM,EAAE,kBAAe,GAAkB,EACnC,CAAC,GAAQ,KAAa,EAAyC,MAAM,EAErE,IAAQ,EAAkB,EAAE,QAAQ,MAAW,QAAQ,KAAA,IAAY,GAAQ,CAAC,EAC5E,IAAiB,EAAM,QAAQ,EAAE;AAEvC,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,UAAD;GACE,MAAK;GACL,eAAe,EAAW,sBAAsB;GAChD,WAAU;aAHZ,CAKE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,qBACrB;;YAVb,CAaE,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAe,KAAK,MACnB,kBAAC,UAAD;IAEE,MAAK;IACL,eAAe,EAAU,EAAI,MAAM;IACnC,WAAW,EACT,kEACA,MAAW,EAAI,QACX,kDACA,2DACL;cAEA,EAAI;IACE,EAXF,EAAI,MAWF,CACT;GACE,CAAA,EAEL,EAAM,YACL,kBAAC,GAAD,EAAa,OAAM,2BAA4B,CAAA,GAC7C,EAAM,UACR,kBAAC,GAAD,EAAW,eAAe,KAAK,EAAM,SAAS,EAAI,CAAA,GAChD,EAAe,WAAW,IAC5B,kBAAC,GAAD;GACE,cAAa;GACb,MAAM,kBAAC,GAAD,EAAW,WAAU,aAAc,CAAA;GACzC,OAAM;GACN,aAAY;GACZ,QACE,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,EAAW,sBAAsB;IAChD,WAAU;cAHZ,CAKE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,qBACrB;;GAEX,CAAA,GAEF,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAe,KAAK,MACnB,kBAAC,UAAD;IAEE,MAAK;IACL,eAAe,EAAW,mBAAmB,EAAE,KAAK;IACpD,WAAU;cAJZ;KAME,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,GAAD;QACE,MAAM,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA;QACvC,MAAM,EAAE;QACR,WAAU;QACV,CAAA;OACF,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,MAAD;SAAI,WAAU;mBAAsD,EAAE;SAAW,CAAA,EAChF,EAAE,OAAO,QACR,kBAAC,KAAD;SAAG,WAAU;mBAAwC,EAAE,MAAM;SAAS,CAAA,CAEpE;;OACN,kBAAC,GAAD,EAAa,QAAQ,EAAE,QAAU,CAAA;OAC7B;;KACL,EAAE,SACD,kBAAC,KAAD;MAAG,WAAU;gBAAiD,EAAE;MAAU,CAAA;KAE5E,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,QAAD;OAAM,WAAU;iBAAyC,EAAU,EAAE,KAAK;OAAQ,CAAA,EAClF,kBAAC,QAAD,EAAA,UAAO,EAAY,EAAE,cAAc,EAAE,SAAS,EAAQ,CAAA,CAClD;;KACL,EAAE,aACD,kBAAC,KAAD;MAAG,WAAU;gBAAb,CAAgD,WACtC,EAAW,EAAE,WAAW;OAAE,MAAM,KAAA;OAAW,QAAQ,KAAA;OAAW,CAAC,CACrE;;KAEC;MA/BF,EAAE,GA+BA,CACT;GACE,CAAA,CAEG"}
1
+ {"version":3,"file":"CollaborationsListPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/collaborations/CollaborationsListPage.tsx"],"sourcesContent":["/**\n * Collaborations List Page\n * @module coolandlovely/pages/collaborations\n *\n * Lists brand × creator partnerships (`cooListCollaborations`) with status\n * filter.\n */\n\nimport { useState } from 'react';\nimport { Plus, Handshake } from 'lucide-react';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { BrandCreatorAvatars } from '../../components/BrandCreatorAvatars';\nimport { ActorName } from '../../components/ActorName';\nimport { useCoolAndLovely } from '../../context/CoolAndLovelyContext';\nimport { useCollaborations } from '../../hooks';\nimport { formatPrice, formatDate, titleCase } from '../../utils/formatters';\nimport { cn } from '../../utils/cn';\nimport type { CooCollaborationStatus } from '../../types';\n\nconst STATUS_OPTIONS: Array<{ value: CooCollaborationStatus | 'ALL'; label: string }> = [\n { value: 'ALL', label: 'All' },\n { value: 'PROPOSED', label: 'Proposed' },\n { value: 'ACCEPTED', label: 'Accepted' },\n { value: 'IN_PROGRESS', label: 'In progress' },\n { value: 'PUBLISHED', label: 'Published' },\n { value: 'DECLINED', label: 'Declined' },\n { value: 'CANCELLED', label: 'Cancelled' },\n];\n\nexport function CollaborationsListPage() {\n const { navigateTo } = useCoolAndLovely();\n const [status, setStatus] = useState<CooCollaborationStatus | 'ALL'>('ALL');\n\n const query = useCollaborations({ status: status === 'ALL' ? undefined : status });\n const collaborations = query.data ?? [];\n\n return (\n <PageLayout\n title=\"Collaborations\"\n description=\"Brand × creator partnerships with a real lifecycle\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/collaborations/new')}\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 <Plus className=\"h-4 w-4\" /> New collaboration\n </button>\n }\n >\n <div className=\"mb-6 flex flex-wrap items-center gap-2\">\n {STATUS_OPTIONS.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n onClick={() => setStatus(opt.value)}\n className={cn(\n 'rounded-full px-3 py-1.5 text-sm font-medium transition-colors',\n status === opt.value\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-secondary hover:text-text-primary'\n )}\n >\n {opt.label}\n </button>\n ))}\n </div>\n\n {query.isLoading ? (\n <LoadingView label=\"Loading collaborations…\" />\n ) : query.isError ? (\n <ErrorView onRetry={() => void query.refetch()} />\n ) : collaborations.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Handshake className=\"h-10 w-10\" />}\n title=\"No collaborations yet\"\n description=\"Propose a brand × creator partnership to get started.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/collaborations/new')}\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\"\n >\n <Plus className=\"h-4 w-4\" /> New collaboration\n </button>\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {collaborations.map((c) => (\n <button\n key={c.id}\n type=\"button\"\n onClick={() => navigateTo(`/collaborations/${c.id}`)}\n className=\"flex flex-col 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\"\n >\n <div className=\"flex items-start gap-3\">\n <BrandCreatorAvatars\n brandLogoFileId={c.brand?.logo?.id}\n brandSeed={c.brandId}\n creatorId={c.creatorId}\n size=\"sm\"\n className=\"shrink-0\"\n />\n <div className=\"min-w-0 flex-1\">\n <h3 className=\"truncate text-base font-semibold text-text-primary\">{c.title}</h3>\n <p className=\"truncate text-xs text-text-secondary\">\n {c.brand?.name ?? 'Brand'} × <ActorName id={c.creatorId} />\n </p>\n </div>\n <StatusBadge status={c.status} />\n </div>\n {c.brief && (\n <p className=\"mt-3 line-clamp-2 text-sm text-text-secondary\">{c.brief}</p>\n )}\n <div className=\"mt-3 flex items-center justify-between text-xs text-text-secondary\">\n <span className=\"rounded-full bg-bg-sunken px-2 py-0.5\">{titleCase(c.role)}</span>\n <span>{formatPrice(c.compensation, c.currency)}</span>\n </div>\n {c.startDate && (\n <p className=\"mt-2 text-xs text-text-secondary\">\n Starts {formatDate(c.startDate, { hour: undefined, minute: undefined })}\n </p>\n )}\n </button>\n ))}\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AAsBA,IAAM,IAAkF;CACtF;EAAE,OAAO;EAAO,OAAO;EAAO;CAC9B;EAAE,OAAO;EAAY,OAAO;EAAY;CACxC;EAAE,OAAO;EAAY,OAAO;EAAY;CACxC;EAAE,OAAO;EAAe,OAAO;EAAe;CAC9C;EAAE,OAAO;EAAa,OAAO;EAAa;CAC1C;EAAE,OAAO;EAAY,OAAO;EAAY;CACxC;EAAE,OAAO;EAAa,OAAO;EAAa;CAC3C;AAED,SAAgB,IAAyB;CACvC,IAAM,EAAE,kBAAe,GAAkB,EACnC,CAAC,GAAQ,KAAa,EAAyC,MAAM,EAErE,IAAQ,EAAkB,EAAE,QAAQ,MAAW,QAAQ,KAAA,IAAY,GAAQ,CAAC,EAC5E,IAAiB,EAAM,QAAQ,EAAE;AAEvC,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,UAAD;GACE,MAAK;GACL,eAAe,EAAW,sBAAsB;GAChD,WAAU;aAHZ,CAKE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,qBACrB;;YAVb,CAaE,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAe,KAAK,MACnB,kBAAC,UAAD;IAEE,MAAK;IACL,eAAe,EAAU,EAAI,MAAM;IACnC,WAAW,EACT,kEACA,MAAW,EAAI,QACX,kDACA,2DACL;cAEA,EAAI;IACE,EAXF,EAAI,MAWF,CACT;GACE,CAAA,EAEL,EAAM,YACL,kBAAC,GAAD,EAAa,OAAM,2BAA4B,CAAA,GAC7C,EAAM,UACR,kBAAC,GAAD,EAAW,eAAe,KAAK,EAAM,SAAS,EAAI,CAAA,GAChD,EAAe,WAAW,IAC5B,kBAAC,GAAD;GACE,cAAa;GACb,MAAM,kBAAC,GAAD,EAAW,WAAU,aAAc,CAAA;GACzC,OAAM;GACN,aAAY;GACZ,QACE,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,EAAW,sBAAsB;IAChD,WAAU;cAHZ,CAKE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,qBACrB;;GAEX,CAAA,GAEF,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAe,KAAK,MACnB,kBAAC,UAAD;IAEE,MAAK;IACL,eAAe,EAAW,mBAAmB,EAAE,KAAK;IACpD,WAAU;cAJZ;KAME,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,GAAD;QACE,iBAAiB,EAAE,OAAO,MAAM;QAChC,WAAW,EAAE;QACb,WAAW,EAAE;QACb,MAAK;QACL,WAAU;QACV,CAAA;OACF,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,MAAD;SAAI,WAAU;mBAAsD,EAAE;SAAW,CAAA,EACjF,kBAAC,KAAD;SAAG,WAAU;mBAAb;UACG,EAAE,OAAO,QAAQ;UAAQ;UAAG,kBAAC,GAAD,EAAW,IAAI,EAAE,WAAa,CAAA;UACzD;WACA;;OACN,kBAAC,GAAD,EAAa,QAAQ,EAAE,QAAU,CAAA;OAC7B;;KACL,EAAE,SACD,kBAAC,KAAD;MAAG,WAAU;gBAAiD,EAAE;MAAU,CAAA;KAE5E,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,QAAD;OAAM,WAAU;iBAAyC,EAAU,EAAE,KAAK;OAAQ,CAAA,EAClF,kBAAC,QAAD,EAAA,UAAO,EAAY,EAAE,cAAc,EAAE,SAAS,EAAQ,CAAA,CAClD;;KACL,EAAE,aACD,kBAAC,KAAD;MAAG,WAAU;gBAAb,CAAgD,WACtC,EAAW,EAAE,WAAW;OAAE,MAAM,KAAA;OAAW,QAAQ,KAAA;OAAW,CAAC,CACrE;;KAEC;MAjCF,EAAE,GAiCA,CACT;GACE,CAAA,CAEG"}
@@ -4,181 +4,204 @@ 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
6
  import { useCollection as o, usePublishCollection as s } from "../../hooks/useCoolAndLovelyApi.js";
7
- import "../../hooks/index.js";
8
7
  import { formatDate as c, formatPrice as l, titleCase as u } from "../../utils/formatters.js";
8
+ import "../../hooks/index.js";
9
9
  import { TagList as d } from "../../components/TagList.js";
10
10
  import { categoryIcon as f } from "../../utils/icons.js";
11
- import { ArrowLeft as p, Loader2 as m, Pencil as h, Plus as g, Rocket as _, Shapes as v, Store as y } from "lucide-react";
12
- import { useParams as b } from "react-router-dom";
13
- import { jsx as x, jsxs as S } from "react/jsx-runtime";
14
- import { GlassCard as C } from "@burdenoff/fe-libs/ui";
11
+ import { ColourSwatchRow as p } from "../../components/ColourSwatchRow.js";
12
+ import { ArrowLeft as m, Loader2 as h, Pencil as g, Plus as _, Rocket as v, Shapes as y, Store as b } from "lucide-react";
13
+ import { useParams as x } from "react-router-dom";
14
+ import { Fragment as S, jsx as C, jsxs as w } from "react/jsx-runtime";
15
+ import { GlassCard as T } from "@burdenoff/fe-libs/ui";
15
16
  //#region src/coolandlovely/pages/collections/CollectionDetailPage.tsx
16
- function w() {
17
- let { collectionId: w } = b(), { navigateTo: T } = e(), E = o(w), D = s();
18
- if (E.isLoading) return /* @__PURE__ */ x(t, {
17
+ function E() {
18
+ let { collectionId: E } = x(), { navigateTo: D } = e(), O = o(E), k = s();
19
+ if (O.isLoading) return /* @__PURE__ */ C(t, {
19
20
  title: "Collection",
20
- children: /* @__PURE__ */ x(i, { label: "Loading collection…" })
21
+ children: /* @__PURE__ */ C(i, { label: "Loading collection…" })
21
22
  });
22
- if (E.isError || !E.data) return /* @__PURE__ */ x(t, {
23
+ if (O.isError || !O.data) return /* @__PURE__ */ C(t, {
23
24
  title: "Collection",
24
- children: /* @__PURE__ */ x(r, {
25
+ children: /* @__PURE__ */ C(r, {
25
26
  title: "Collection not found",
26
- onRetry: () => void E.refetch()
27
+ onRetry: () => void O.refetch()
27
28
  })
28
29
  });
29
- let O = E.data, k = O.items ?? [], A = O.status === "DRAFT" || O.status === "SCHEDULED";
30
- return /* @__PURE__ */ x(t, {
31
- title: O.name,
32
- description: O.brand?.name ?? void 0,
33
- actions: /* @__PURE__ */ S("div", {
30
+ let A = O.data, j = A.items ?? [], M = A.status === "DRAFT" || A.status === "SCHEDULED";
31
+ return /* @__PURE__ */ C(t, {
32
+ title: A.name,
33
+ description: A.brand?.name ?? void 0,
34
+ actions: /* @__PURE__ */ w("div", {
34
35
  className: "flex flex-wrap items-center gap-2",
35
36
  children: [
36
- /* @__PURE__ */ S("button", {
37
+ /* @__PURE__ */ w("button", {
37
38
  type: "button",
38
- onClick: () => T("/collections"),
39
+ onClick: () => D("/collections"),
39
40
  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__ */ x(p, { className: "h-4 w-4" }), " Back"]
41
+ children: [/* @__PURE__ */ C(m, { className: "h-4 w-4" }), " Back"]
41
42
  }),
42
- /* @__PURE__ */ S("button", {
43
+ /* @__PURE__ */ w("button", {
43
44
  type: "button",
44
- onClick: () => T(`/collections/${O.id}/edit`),
45
+ onClick: () => D(`/collections/${A.id}/edit`),
45
46
  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",
46
- children: [/* @__PURE__ */ x(h, { className: "h-4 w-4" }), " Edit"]
47
+ children: [/* @__PURE__ */ C(g, { className: "h-4 w-4" }), " Edit"]
47
48
  }),
48
- A && /* @__PURE__ */ S("button", {
49
+ M && /* @__PURE__ */ w("button", {
49
50
  type: "button",
50
- disabled: D.isPending,
51
- onClick: () => D.mutate(O.id),
51
+ disabled: k.isPending,
52
+ onClick: () => k.mutate(A.id),
52
53
  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",
53
- children: [D.isPending ? /* @__PURE__ */ x(m, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ x(_, { className: "h-4 w-4" }), "Publish"]
54
+ children: [k.isPending ? /* @__PURE__ */ C(h, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ C(v, { className: "h-4 w-4" }), "Publish"]
54
55
  })
55
56
  ]
56
57
  }),
57
- children: /* @__PURE__ */ S("div", {
58
+ children: /* @__PURE__ */ w("div", {
58
59
  className: "grid grid-cols-1 gap-6 lg:grid-cols-3",
59
- children: [/* @__PURE__ */ S("div", {
60
+ children: [/* @__PURE__ */ w("div", {
60
61
  className: "lg:col-span-2",
61
- children: [/* @__PURE__ */ S(C, {
62
+ children: [/* @__PURE__ */ w(T, {
62
63
  treatment: "glass",
63
- className: "overflow-hidden p-0",
64
- children: [/* @__PURE__ */ x(a, {
65
- icon: /* @__PURE__ */ x(v, { className: "h-12 w-12" }),
66
- seed: O.id,
67
- fileId: O.cover?.id,
68
- alt: O.name,
69
- className: "h-40 w-full"
70
- }), /* @__PURE__ */ S("div", {
71
- className: "p-6",
72
- children: [
73
- /* @__PURE__ */ S("div", {
74
- className: "flex items-center gap-2",
75
- children: [/* @__PURE__ */ x("h2", {
76
- className: "text-xl font-semibold text-text-primary",
77
- children: O.name
78
- }), /* @__PURE__ */ x(n, {
79
- status: O.status,
80
- className: "ml-auto"
64
+ className: "group overflow-hidden p-0",
65
+ children: [/* @__PURE__ */ C(a, {
66
+ icon: /* @__PURE__ */ C(y, { className: "h-12 w-12" }),
67
+ seed: A.id,
68
+ fileId: A.cover?.id,
69
+ alt: A.name,
70
+ className: "aspect-[16/9] w-full sm:aspect-[21/9]",
71
+ overlay: /* @__PURE__ */ w(S, { children: [/* @__PURE__ */ C("div", { className: "pointer-events-none absolute inset-0 bg-gradient-to-t from-bg-canvas via-bg-canvas/55 to-transparent" }), /* @__PURE__ */ w("div", {
72
+ className: "absolute inset-x-0 bottom-0 flex flex-wrap items-end justify-between gap-3 p-6",
73
+ children: [/* @__PURE__ */ w("div", {
74
+ className: "min-w-0",
75
+ children: [/* @__PURE__ */ C("h2", {
76
+ className: "font-serif text-3xl font-semibold leading-tight text-text-primary",
77
+ children: A.name
78
+ }), /* @__PURE__ */ w("div", {
79
+ className: "mt-2 flex flex-wrap items-center gap-2 text-sm text-text-secondary",
80
+ children: [
81
+ A.brand?.name && /* @__PURE__ */ C("span", { children: A.brand.name }),
82
+ A.brand?.name && /* @__PURE__ */ C("span", {
83
+ "aria-hidden": "true",
84
+ className: "opacity-60",
85
+ children: "·"
86
+ }),
87
+ /* @__PURE__ */ C("span", {
88
+ className: "rounded-full border border-border-seam bg-bg-surface/80 px-2.5 py-0.5 text-xs font-medium text-text-primary backdrop-blur-sm",
89
+ children: u(A.season)
90
+ })
91
+ ]
81
92
  })]
82
- }),
83
- O.description && /* @__PURE__ */ x("p", {
84
- className: "mt-3 text-sm text-text-secondary",
85
- children: O.description
86
- }),
87
- O.tags.length > 0 && /* @__PURE__ */ x(d, {
88
- tags: O.tags,
89
- className: "mt-4"
90
- })
91
- ]
93
+ }), /* @__PURE__ */ C(n, {
94
+ status: A.status,
95
+ className: "shrink-0 shadow-sm"
96
+ })]
97
+ })] })
98
+ }), (A.description || A.tags.length > 0) && /* @__PURE__ */ w("div", {
99
+ className: "p-6",
100
+ children: [A.description && /* @__PURE__ */ C("p", {
101
+ className: "text-sm text-text-secondary",
102
+ children: A.description
103
+ }), A.tags.length > 0 && /* @__PURE__ */ C(d, {
104
+ tags: A.tags,
105
+ className: A.description ? "mt-4" : void 0
106
+ })]
92
107
  })]
93
- }), /* @__PURE__ */ S("section", {
108
+ }), /* @__PURE__ */ w("section", {
94
109
  className: "mt-6",
95
110
  children: [
96
- /* @__PURE__ */ S("h3", {
111
+ /* @__PURE__ */ w("h3", {
97
112
  className: "mb-3 text-lg font-semibold text-text-primary",
98
113
  children: [
99
114
  "Items (",
100
- k.length,
115
+ j.length,
101
116
  ")"
102
117
  ]
103
118
  }),
104
- k.length === 0 ? /* @__PURE__ */ x("p", {
119
+ j.length === 0 ? /* @__PURE__ */ C("p", {
105
120
  className: "rounded-lg border border-border-seam bg-bg-surface p-4 text-sm text-text-secondary",
106
121
  children: "No items in this collection yet."
107
- }) : /* @__PURE__ */ x("div", {
122
+ }) : /* @__PURE__ */ C("div", {
108
123
  className: "grid grid-cols-2 gap-3 sm:grid-cols-3",
109
- children: k.map((e) => /* @__PURE__ */ S("button", {
124
+ children: j.map((e) => /* @__PURE__ */ w("button", {
110
125
  type: "button",
111
- onClick: () => T(`/items/${e.id}`),
112
- className: "overflow-hidden rounded-lg border border-border-seam bg-bg-surface text-left transition-all hover:border-accent-foreground/20 hover:shadow-md",
113
- children: [/* @__PURE__ */ x(a, {
114
- icon: f(e.category, 24),
126
+ onClick: () => D(`/items/${e.id}`),
127
+ 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",
128
+ children: [/* @__PURE__ */ C(a, {
129
+ icon: f(e.category, 28),
115
130
  seed: e.id,
116
131
  fileId: e.image?.id,
117
132
  alt: e.name,
118
- className: "h-24 w-full"
119
- }), /* @__PURE__ */ S("div", {
133
+ className: "aspect-[3/4] w-full"
134
+ }), /* @__PURE__ */ w("div", {
120
135
  className: "p-3",
121
- children: [/* @__PURE__ */ x("p", {
122
- className: "truncate text-sm font-medium text-text-primary",
123
- children: e.name
124
- }), /* @__PURE__ */ x("p", {
125
- className: "mt-0.5 text-xs text-text-secondary",
126
- children: l(e.price, e.currency)
127
- })]
136
+ children: [
137
+ /* @__PURE__ */ C("p", {
138
+ className: "truncate text-sm font-medium text-text-primary",
139
+ children: e.name
140
+ }),
141
+ /* @__PURE__ */ C("p", {
142
+ className: "mt-0.5 text-xs font-semibold text-text-primary tabular-nums",
143
+ children: l(e.price, e.currency)
144
+ }),
145
+ e.colours.length > 0 && /* @__PURE__ */ C(p, {
146
+ colours: e.colours,
147
+ max: 5,
148
+ className: "mt-2"
149
+ })
150
+ ]
128
151
  })]
129
152
  }, e.id))
130
153
  }),
131
- /* @__PURE__ */ S("button", {
154
+ /* @__PURE__ */ w("button", {
132
155
  type: "button",
133
- onClick: () => T(`/items/new?brandId=${O.brandId}&collectionId=${O.id}`),
156
+ onClick: () => D(`/items/new?brandId=${A.brandId}&collectionId=${A.id}`),
134
157
  className: "mt-3 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",
135
- children: [/* @__PURE__ */ x(g, { className: "h-4 w-4" }), " Add item to this collection"]
158
+ children: [/* @__PURE__ */ C(_, { className: "h-4 w-4" }), " Add item to this collection"]
136
159
  })
137
160
  ]
138
161
  })]
139
- }), /* @__PURE__ */ S("div", {
162
+ }), /* @__PURE__ */ w("div", {
140
163
  className: "space-y-4",
141
164
  children: [
142
- /* @__PURE__ */ S(C, {
165
+ /* @__PURE__ */ w(T, {
143
166
  treatment: "plain",
144
167
  className: "p-5",
145
- children: [/* @__PURE__ */ x("h3", {
168
+ children: [/* @__PURE__ */ C("h3", {
146
169
  className: "mb-3 text-sm font-semibold text-text-primary",
147
170
  children: "Details"
148
- }), /* @__PURE__ */ S("dl", {
171
+ }), /* @__PURE__ */ w("dl", {
149
172
  className: "space-y-2 text-sm",
150
173
  children: [
151
- /* @__PURE__ */ S("div", {
174
+ /* @__PURE__ */ w("div", {
152
175
  className: "flex justify-between gap-2",
153
- children: [/* @__PURE__ */ x("dt", {
176
+ children: [/* @__PURE__ */ C("dt", {
154
177
  className: "text-text-secondary",
155
178
  children: "Season"
156
- }), /* @__PURE__ */ x("dd", {
179
+ }), /* @__PURE__ */ C("dd", {
157
180
  className: "text-text-primary",
158
- children: u(O.season)
181
+ children: u(A.season)
159
182
  })]
160
183
  }),
161
- /* @__PURE__ */ S("div", {
184
+ /* @__PURE__ */ w("div", {
162
185
  className: "flex justify-between gap-2",
163
- children: [/* @__PURE__ */ x("dt", {
186
+ children: [/* @__PURE__ */ C("dt", {
164
187
  className: "text-text-secondary",
165
188
  children: "Publish at"
166
- }), /* @__PURE__ */ x("dd", {
189
+ }), /* @__PURE__ */ C("dd", {
167
190
  className: "text-text-primary",
168
- children: O.publishAt ? c(O.publishAt, {
191
+ children: A.publishAt ? c(A.publishAt, {
169
192
  hour: void 0,
170
193
  minute: void 0
171
194
  }) : "—"
172
195
  })]
173
196
  }),
174
- /* @__PURE__ */ S("div", {
197
+ /* @__PURE__ */ w("div", {
175
198
  className: "flex justify-between gap-2",
176
- children: [/* @__PURE__ */ x("dt", {
199
+ children: [/* @__PURE__ */ C("dt", {
177
200
  className: "text-text-secondary",
178
201
  children: "Ends at"
179
- }), /* @__PURE__ */ x("dd", {
202
+ }), /* @__PURE__ */ C("dd", {
180
203
  className: "text-text-primary",
181
- children: O.endAt ? c(O.endAt, {
204
+ children: A.endAt ? c(A.endAt, {
182
205
  hour: void 0,
183
206
  minute: void 0
184
207
  }) : "—"
@@ -187,28 +210,28 @@ function w() {
187
210
  ]
188
211
  })]
189
212
  }),
190
- O.brand && /* @__PURE__ */ S("button", {
213
+ A.brand && /* @__PURE__ */ w("button", {
191
214
  type: "button",
192
- onClick: () => T(`/brands/${O.brand?.id}`),
215
+ onClick: () => D(`/brands/${A.brand?.id}`),
193
216
  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",
194
- children: [/* @__PURE__ */ x(a, {
195
- icon: /* @__PURE__ */ x(y, { className: "h-5 w-5" }),
196
- seed: O.brand.id,
217
+ children: [/* @__PURE__ */ C(a, {
218
+ icon: /* @__PURE__ */ C(b, { className: "h-5 w-5" }),
219
+ seed: A.brand.id,
197
220
  className: "h-10 w-10 shrink-0"
198
- }), /* @__PURE__ */ S("div", {
221
+ }), /* @__PURE__ */ w("div", {
199
222
  className: "min-w-0",
200
- children: [/* @__PURE__ */ x("p", {
223
+ children: [/* @__PURE__ */ C("p", {
201
224
  className: "truncate text-sm font-medium text-text-primary",
202
- children: O.brand.name
203
- }), /* @__PURE__ */ x("p", {
225
+ children: A.brand.name
226
+ }), /* @__PURE__ */ C("p", {
204
227
  className: "truncate text-xs text-text-secondary",
205
228
  children: "View brand"
206
229
  })]
207
230
  })]
208
231
  }),
209
- D.isError && /* @__PURE__ */ x("p", {
232
+ k.isError && /* @__PURE__ */ C("p", {
210
233
  className: "rounded-lg bg-status-error-bg-subtle px-3 py-2 text-xs text-status-error-text",
211
- children: D.error instanceof Error ? D.error.message : "Publish failed"
234
+ children: k.error instanceof Error ? k.error.message : "Publish failed"
212
235
  })
213
236
  ]
214
237
  })]
@@ -216,6 +239,6 @@ function w() {
216
239
  });
217
240
  }
218
241
  //#endregion
219
- export { w as CollectionDetailPage };
242
+ export { E as CollectionDetailPage };
220
243
 
221
244
  //# sourceMappingURL=CollectionDetailPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CollectionDetailPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/collections/CollectionDetailPage.tsx"],"sourcesContent":["/**\n * Collection Detail Page\n * @module coolandlovely/pages/collections\n *\n * Single collection (`cooCollection`) with publish (`cooPublishCollection`),\n * edit, its brand link and member items.\n */\n\nimport { useParams } from 'react-router-dom';\nimport { ArrowLeft, Pencil, Rocket, Loader2, Shapes, Store, Plus } 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 { useCollection, usePublishCollection } from '../../hooks';\nimport { categoryIcon } from '../../utils/icons';\nimport { formatPrice, formatDate, titleCase } from '../../utils/formatters';\n\nexport function CollectionDetailPage() {\n const { collectionId } = useParams<{ collectionId: string }>();\n const { navigateTo } = useCoolAndLovely();\n const query = useCollection(collectionId);\n const publish = usePublishCollection();\n\n if (query.isLoading) {\n return (\n <PageLayout title=\"Collection\">\n <LoadingView label=\"Loading collection…\" />\n </PageLayout>\n );\n }\n\n if (query.isError || !query.data) {\n return (\n <PageLayout title=\"Collection\">\n <ErrorView title=\"Collection not found\" onRetry={() => void query.refetch()} />\n </PageLayout>\n );\n }\n\n const collection = query.data;\n const items = collection.items ?? [];\n const canPublish = collection.status === 'DRAFT' || collection.status === 'SCHEDULED';\n\n return (\n <PageLayout\n title={collection.name}\n description={collection.brand?.name ?? undefined}\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/collections')}\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(`/collections/${collection.id}/edit`)}\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 <Pencil className=\"h-4 w-4\" /> Edit\n </button>\n {canPublish && (\n <button\n type=\"button\"\n disabled={publish.isPending}\n onClick={() => publish.mutate(collection.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 </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={<Shapes className=\"h-12 w-12\" />}\n seed={collection.id}\n fileId={collection.cover?.id}\n alt={collection.name}\n className=\"h-40 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\">{collection.name}</h2>\n <StatusBadge status={collection.status} className=\"ml-auto\" />\n </div>\n {collection.description && (\n <p className=\"mt-3 text-sm text-text-secondary\">{collection.description}</p>\n )}\n {collection.tags.length > 0 && <TagList tags={collection.tags} className=\"mt-4\" />}\n </div>\n </GlassCard>\n\n <section className=\"mt-6\">\n <h3 className=\"mb-3 text-lg font-semibold text-text-primary\">Items ({items.length})</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 in this collection yet.\n </p>\n ) : (\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">\n {items.map((item) => (\n <button\n key={item.id}\n type=\"button\"\n onClick={() => navigateTo(`/items/${item.id}`)}\n className=\"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={categoryIcon(item.category, 24)}\n seed={item.id}\n fileId={item.image?.id}\n alt={item.name}\n className=\"h-24 w-full\"\n />\n <div className=\"p-3\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{item.name}</p>\n <p className=\"mt-0.5 text-xs text-text-secondary\">\n {formatPrice(item.price, item.currency)}\n </p>\n </div>\n </button>\n ))}\n </div>\n )}\n <button\n type=\"button\"\n onClick={() =>\n navigateTo(`/items/new?brandId=${collection.brandId}&collectionId=${collection.id}`)\n }\n className=\"mt-3 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 <Plus className=\"h-4 w-4\" /> Add item to this collection\n </button>\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\">Season</dt>\n <dd className=\"text-text-primary\">{titleCase(collection.season)}</dd>\n </div>\n <div className=\"flex justify-between gap-2\">\n <dt className=\"text-text-secondary\">Publish at</dt>\n <dd className=\"text-text-primary\">\n {collection.publishAt\n ? formatDate(collection.publishAt, { hour: undefined, minute: undefined })\n : '—'}\n </dd>\n </div>\n <div className=\"flex justify-between gap-2\">\n <dt className=\"text-text-secondary\">Ends at</dt>\n <dd className=\"text-text-primary\">\n {collection.endAt\n ? formatDate(collection.endAt, { hour: undefined, minute: undefined })\n : '—'}\n </dd>\n </div>\n </dl>\n </GlassCard>\n\n {collection.brand && (\n <button\n type=\"button\"\n onClick={() => navigateTo(`/brands/${collection.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={collection.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\">\n {collection.brand.name}\n </p>\n <p className=\"truncate text-xs text-text-secondary\">View brand</p>\n </div>\n </button>\n )}\n\n {publish.isError && (\n <p className=\"rounded-lg bg-status-error-bg-subtle px-3 py-2 text-xs text-status-error-text\">\n {publish.error instanceof Error ? publish.error.message : 'Publish failed'}\n </p>\n )}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CollectionDetailPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/collections/CollectionDetailPage.tsx"],"sourcesContent":["/**\n * Collection Detail Page\n * @module coolandlovely/pages/collections\n *\n * Single collection (`cooCollection`) with publish (`cooPublishCollection`),\n * edit, its brand link and member items.\n */\n\nimport { useParams } from 'react-router-dom';\nimport { ArrowLeft, Pencil, Rocket, Loader2, Shapes, Store, Plus } 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 { ColourSwatchRow } from '../../components/ColourSwatchRow';\nimport { useCoolAndLovely } from '../../context/CoolAndLovelyContext';\nimport { useCollection, usePublishCollection } from '../../hooks';\nimport { categoryIcon } from '../../utils/icons';\nimport { formatPrice, formatDate, titleCase } from '../../utils/formatters';\n\nexport function CollectionDetailPage() {\n const { collectionId } = useParams<{ collectionId: string }>();\n const { navigateTo } = useCoolAndLovely();\n const query = useCollection(collectionId);\n const publish = usePublishCollection();\n\n if (query.isLoading) {\n return (\n <PageLayout title=\"Collection\">\n <LoadingView label=\"Loading collection…\" />\n </PageLayout>\n );\n }\n\n if (query.isError || !query.data) {\n return (\n <PageLayout title=\"Collection\">\n <ErrorView title=\"Collection not found\" onRetry={() => void query.refetch()} />\n </PageLayout>\n );\n }\n\n const collection = query.data;\n const items = collection.items ?? [];\n const canPublish = collection.status === 'DRAFT' || collection.status === 'SCHEDULED';\n\n return (\n <PageLayout\n title={collection.name}\n description={collection.brand?.name ?? undefined}\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/collections')}\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(`/collections/${collection.id}/edit`)}\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 <Pencil className=\"h-4 w-4\" /> Edit\n </button>\n {canPublish && (\n <button\n type=\"button\"\n disabled={publish.isPending}\n onClick={() => publish.mutate(collection.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 </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=\"group overflow-hidden p-0\">\n <Thumbnail\n icon={<Shapes className=\"h-12 w-12\" />}\n seed={collection.id}\n fileId={collection.cover?.id}\n alt={collection.name}\n className=\"aspect-[16/9] w-full sm:aspect-[21/9]\"\n overlay={\n <>\n <div className=\"pointer-events-none absolute inset-0 bg-gradient-to-t from-bg-canvas via-bg-canvas/55 to-transparent\" />\n <div className=\"absolute inset-x-0 bottom-0 flex flex-wrap items-end justify-between gap-3 p-6\">\n <div className=\"min-w-0\">\n <h2 className=\"font-serif text-3xl font-semibold leading-tight text-text-primary\">\n {collection.name}\n </h2>\n <div className=\"mt-2 flex flex-wrap items-center gap-2 text-sm text-text-secondary\">\n {collection.brand?.name && <span>{collection.brand.name}</span>}\n {collection.brand?.name && (\n <span aria-hidden=\"true\" className=\"opacity-60\">\n ·\n </span>\n )}\n <span className=\"rounded-full border border-border-seam bg-bg-surface/80 px-2.5 py-0.5 text-xs font-medium text-text-primary backdrop-blur-sm\">\n {titleCase(collection.season)}\n </span>\n </div>\n </div>\n <StatusBadge status={collection.status} className=\"shrink-0 shadow-sm\" />\n </div>\n </>\n }\n />\n {(collection.description || collection.tags.length > 0) && (\n <div className=\"p-6\">\n {collection.description && (\n <p className=\"text-sm text-text-secondary\">{collection.description}</p>\n )}\n {collection.tags.length > 0 && (\n <TagList\n tags={collection.tags}\n className={collection.description ? 'mt-4' : undefined}\n />\n )}\n </div>\n )}\n </GlassCard>\n\n <section className=\"mt-6\">\n <h3 className=\"mb-3 text-lg font-semibold text-text-primary\">Items ({items.length})</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 in this collection yet.\n </p>\n ) : (\n <div className=\"grid grid-cols-2 gap-3 sm:grid-cols-3\">\n {items.map((item) => (\n <button\n key={item.id}\n type=\"button\"\n onClick={() => navigateTo(`/items/${item.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={categoryIcon(item.category, 28)}\n seed={item.id}\n fileId={item.image?.id}\n alt={item.name}\n className=\"aspect-[3/4] w-full\"\n />\n <div className=\"p-3\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{item.name}</p>\n <p className=\"mt-0.5 text-xs font-semibold text-text-primary tabular-nums\">\n {formatPrice(item.price, item.currency)}\n </p>\n {item.colours.length > 0 && (\n <ColourSwatchRow colours={item.colours} max={5} className=\"mt-2\" />\n )}\n </div>\n </button>\n ))}\n </div>\n )}\n <button\n type=\"button\"\n onClick={() =>\n navigateTo(`/items/new?brandId=${collection.brandId}&collectionId=${collection.id}`)\n }\n className=\"mt-3 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 <Plus className=\"h-4 w-4\" /> Add item to this collection\n </button>\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\">Season</dt>\n <dd className=\"text-text-primary\">{titleCase(collection.season)}</dd>\n </div>\n <div className=\"flex justify-between gap-2\">\n <dt className=\"text-text-secondary\">Publish at</dt>\n <dd className=\"text-text-primary\">\n {collection.publishAt\n ? formatDate(collection.publishAt, { hour: undefined, minute: undefined })\n : '—'}\n </dd>\n </div>\n <div className=\"flex justify-between gap-2\">\n <dt className=\"text-text-secondary\">Ends at</dt>\n <dd className=\"text-text-primary\">\n {collection.endAt\n ? formatDate(collection.endAt, { hour: undefined, minute: undefined })\n : '—'}\n </dd>\n </div>\n </dl>\n </GlassCard>\n\n {collection.brand && (\n <button\n type=\"button\"\n onClick={() => navigateTo(`/brands/${collection.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={collection.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\">\n {collection.brand.name}\n </p>\n <p className=\"truncate text-xs text-text-secondary\">View brand</p>\n </div>\n </button>\n )}\n\n {publish.isError && (\n <p className=\"rounded-lg bg-status-error-bg-subtle px-3 py-2 text-xs text-status-error-text\">\n {publish.error instanceof Error ? publish.error.message : 'Publish failed'}\n </p>\n )}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}