@burdenoff/microfe-coolandlovely 2026.805.1 → 2026.820.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/CoolAndLovelyRoot.d.ts.map +1 -1
  2. package/dist/coolandlovely/CoolAndLovelyRoot.js +60 -58
  3. package/dist/coolandlovely/CoolAndLovelyRoot.js.map +1 -1
  4. package/dist/coolandlovely/components/AddToLookbookButton.d.ts.map +1 -1
  5. package/dist/coolandlovely/components/AddToLookbookButton.js +1 -0
  6. package/dist/coolandlovely/components/AddToLookbookButton.js.map +1 -1
  7. package/dist/coolandlovely/components/BrandCard.d.ts +11 -0
  8. package/dist/coolandlovely/components/BrandCard.d.ts.map +1 -0
  9. package/dist/coolandlovely/components/BrandCard.js +55 -0
  10. package/dist/coolandlovely/components/BrandCard.js.map +1 -0
  11. package/dist/coolandlovely/components/CollectionCard.d.ts +11 -0
  12. package/dist/coolandlovely/components/CollectionCard.d.ts.map +1 -0
  13. package/dist/coolandlovely/components/CollectionCard.js +60 -0
  14. package/dist/coolandlovely/components/CollectionCard.js.map +1 -0
  15. package/dist/coolandlovely/components/FeedbackWidget.d.ts +4 -0
  16. package/dist/coolandlovely/components/FeedbackWidget.d.ts.map +1 -0
  17. package/dist/coolandlovely/components/FeedbackWidget.js +134 -0
  18. package/dist/coolandlovely/components/FeedbackWidget.js.map +1 -0
  19. package/dist/coolandlovely/components/LookbookCard.d.ts +11 -0
  20. package/dist/coolandlovely/components/LookbookCard.d.ts.map +1 -0
  21. package/dist/coolandlovely/components/LookbookCard.js +60 -0
  22. package/dist/coolandlovely/components/LookbookCard.js.map +1 -0
  23. package/dist/coolandlovely/components/WardrobeItemCard.d.ts +14 -0
  24. package/dist/coolandlovely/components/WardrobeItemCard.d.ts.map +1 -0
  25. package/dist/coolandlovely/components/WardrobeItemCard.js +92 -0
  26. package/dist/coolandlovely/components/WardrobeItemCard.js.map +1 -0
  27. package/dist/coolandlovely/components/index.d.ts +5 -0
  28. package/dist/coolandlovely/components/index.d.ts.map +1 -1
  29. package/dist/coolandlovely/components/index.js +26 -0
  30. package/dist/coolandlovely/pages/HomePage.d.ts.map +1 -1
  31. package/dist/coolandlovely/pages/HomePage.js +10 -4
  32. package/dist/coolandlovely/pages/HomePage.js.map +1 -1
  33. package/dist/coolandlovely/pages/brands/BrandDetailPage.js +7 -7
  34. package/dist/coolandlovely/pages/brands/BrandsListPage.d.ts.map +1 -1
  35. package/dist/coolandlovely/pages/brands/BrandsListPage.js +48 -89
  36. package/dist/coolandlovely/pages/brands/BrandsListPage.js.map +1 -1
  37. package/dist/coolandlovely/pages/collaborations/CollaborationDetailPage.js +4 -4
  38. package/dist/coolandlovely/pages/collaborations/CollaborationFormPage.js +13 -13
  39. package/dist/coolandlovely/pages/collaborations/CollaborationsListPage.js +4 -4
  40. package/dist/coolandlovely/pages/collections/CollectionsListPage.d.ts.map +1 -1
  41. package/dist/coolandlovely/pages/collections/CollectionsListPage.js +28 -74
  42. package/dist/coolandlovely/pages/collections/CollectionsListPage.js.map +1 -1
  43. package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.js +5 -5
  44. package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.d.ts.map +1 -1
  45. package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.js +66 -112
  46. package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.js.map +1 -1
  47. package/dist/coolandlovely/pages/profile/StyleProfilePage.js +124 -124
  48. package/dist/coolandlovely/pages/profile/StyleProfilePage.js.map +1 -1
  49. package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.d.ts.map +1 -1
  50. package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.js +46 -120
  51. package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.js.map +1 -1
  52. package/dist/stories/BrandCard.stories.d.ts +10 -0
  53. package/dist/stories/BrandCard.stories.d.ts.map +1 -0
  54. package/dist/stories/CollectionCard.stories.d.ts +10 -0
  55. package/dist/stories/CollectionCard.stories.d.ts.map +1 -0
  56. package/dist/stories/FeedbackWidget.stories.d.ts +9 -0
  57. package/dist/stories/FeedbackWidget.stories.d.ts.map +1 -0
  58. package/dist/stories/LookCard.stories.d.ts +10 -0
  59. package/dist/stories/LookCard.stories.d.ts.map +1 -0
  60. package/dist/stories/LookbookCard.stories.d.ts +10 -0
  61. package/dist/stories/LookbookCard.stories.d.ts.map +1 -0
  62. package/dist/stories/WardrobeItemCard.stories.d.ts +11 -0
  63. package/dist/stories/WardrobeItemCard.stories.d.ts.map +1 -0
  64. package/dist/stories/__fixtures__/coolandlovely.d.ts +13 -0
  65. package/dist/stories/__fixtures__/coolandlovely.d.ts.map +1 -0
  66. package/package.json +4 -1
@@ -1,19 +1,16 @@
1
1
  import { useCoolAndLovely as e } from "../../context/CoolAndLovelyContext.js";
2
2
  import { cn as t } from "../../utils/cn.js";
3
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 { useBrands as o } from "../../hooks/useCoolAndLovelyApi.js";
7
- import { titleCase as s } from "../../utils/formatters.js";
4
+ import { ErrorView as r, LoadingView as i } from "../../components/StateViews.js";
5
+ import { useBrands as a } from "../../hooks/useCoolAndLovelyApi.js";
8
6
  import "../../hooks/index.js";
9
- import { BrandCover as c } from "../../components/BrandCover.js";
10
- import { TagList as l } from "../../components/TagList.js";
11
- import { EmptyState as u } from "../../components/EmptyState.js";
12
- import { useState as d } from "react";
13
- import { ChevronLeft as f, ChevronRight as p, Plus as m, Star as h, Store as g } from "lucide-react";
14
- import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
7
+ import { EmptyState as o } from "../../components/EmptyState.js";
8
+ import { BrandCard as s } from "../../components/BrandCard.js";
9
+ import { useState as c } from "react";
10
+ import { ChevronLeft as l, ChevronRight as u, Plus as d, Star as f, Store as p } from "lucide-react";
11
+ import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
15
12
  //#region src/coolandlovely/pages/brands/BrandsListPage.tsx
16
- var b = 24, x = [
13
+ var _ = 24, v = [
17
14
  {
18
15
  value: "ALL",
19
16
  label: "All"
@@ -39,126 +36,88 @@ var b = 24, x = [
39
36
  label: "Archived"
40
37
  }
41
38
  ];
42
- function S() {
43
- let { navigateTo: S } = e(), [C, w] = d("ALL"), [T, E] = d(!1), [D, O] = d(0), k = o({
44
- status: C === "ALL" ? void 0 : C,
45
- featured: T ? !0 : void 0,
39
+ function y() {
40
+ let { navigateTo: y } = e(), [b, x] = c("ALL"), [S, C] = c(!1), [w, T] = c(0), E = a({
41
+ status: b === "ALL" ? void 0 : b,
42
+ featured: S ? !0 : void 0,
46
43
  pagination: {
47
- limit: b,
48
- offset: D
44
+ limit: _,
45
+ offset: w
49
46
  }
50
- }), A = k.data?.items ?? [], j = k.data?.pageInfo.hasMore ?? !1;
51
- return /* @__PURE__ */ y(n, {
47
+ }), D = E.data?.items ?? [], O = E.data?.pageInfo.hasMore ?? !1;
48
+ return /* @__PURE__ */ g(n, {
52
49
  title: "Brands",
53
50
  description: "Storefronts on the platform with a real publish lifecycle",
54
- actions: /* @__PURE__ */ y("button", {
51
+ actions: /* @__PURE__ */ g("button", {
55
52
  type: "button",
56
- onClick: () => S("/brands/new"),
53
+ onClick: () => y("/brands/new"),
57
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",
58
- children: [/* @__PURE__ */ v(m, { className: "h-4 w-4" }), " New brand"]
55
+ children: [/* @__PURE__ */ h(d, { className: "h-4 w-4" }), " New brand"]
59
56
  }),
60
- children: [/* @__PURE__ */ y("div", {
57
+ children: [/* @__PURE__ */ g("div", {
61
58
  className: "mb-6 flex flex-wrap items-center gap-2",
62
- children: [x.map((e) => /* @__PURE__ */ v("button", {
59
+ children: [v.map((e) => /* @__PURE__ */ h("button", {
63
60
  type: "button",
64
61
  onClick: () => {
65
- w(e.value), O(0);
62
+ x(e.value), T(0);
66
63
  },
67
- className: t("rounded-full px-3 py-1.5 text-sm font-medium transition-colors", C === e.value ? "bg-action-primary-bg text-action-primary-text" : "bg-bg-sunken text-text-secondary hover:text-text-primary"),
64
+ 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"),
68
65
  children: e.label
69
- }, e.value)), /* @__PURE__ */ y("button", {
66
+ }, e.value)), /* @__PURE__ */ g("button", {
70
67
  type: "button",
71
68
  onClick: () => {
72
- E((e) => !e), O(0);
69
+ C((e) => !e), T(0);
73
70
  },
74
- className: t("ml-auto inline-flex items-center gap-1.5 rounded-full px-3 py-1.5 text-sm font-medium transition-colors", T ? "bg-status-warning-bg-subtle text-status-warning-text" : "bg-bg-sunken text-text-secondary hover:text-text-primary"),
71
+ className: t("ml-auto inline-flex items-center gap-1.5 rounded-full px-3 py-1.5 text-sm font-medium transition-colors", S ? "bg-status-warning-bg-subtle text-status-warning-text" : "bg-bg-sunken text-text-secondary hover:text-text-primary"),
75
72
  children: [
76
- /* @__PURE__ */ v(h, { className: t("h-3.5 w-3.5", T && "fill-status-warning-text") }),
73
+ /* @__PURE__ */ h(f, { className: t("h-3.5 w-3.5", S && "fill-status-warning-text") }),
77
74
  " ",
78
75
  "Featured"
79
76
  ]
80
77
  })]
81
- }), k.isLoading ? /* @__PURE__ */ v(a, { label: "Loading brands…" }) : k.isError ? /* @__PURE__ */ v(i, { onRetry: () => void k.refetch() }) : A.length === 0 ? /* @__PURE__ */ v(u, {
78
+ }), E.isLoading ? /* @__PURE__ */ h(i, { label: "Loading brands…" }) : E.isError ? /* @__PURE__ */ h(r, { onRetry: () => void E.refetch() }) : D.length === 0 ? /* @__PURE__ */ h(o, {
82
79
  illustration: "empty-data",
83
- icon: /* @__PURE__ */ v(g, { className: "h-10 w-10" }),
80
+ icon: /* @__PURE__ */ h(p, { className: "h-10 w-10" }),
84
81
  title: "No brands yet",
85
82
  description: "Launch the first storefront to start building the catalogue.",
86
- action: /* @__PURE__ */ y("button", {
83
+ action: /* @__PURE__ */ g("button", {
87
84
  type: "button",
88
- onClick: () => S("/brands/new"),
85
+ onClick: () => y("/brands/new"),
89
86
  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",
90
- children: [/* @__PURE__ */ v(m, { className: "h-4 w-4" }), " New brand"]
87
+ children: [/* @__PURE__ */ h(d, { className: "h-4 w-4" }), " New brand"]
91
88
  })
92
- }) : /* @__PURE__ */ y(_, { children: [/* @__PURE__ */ v("div", {
89
+ }) : /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h("div", {
93
90
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
94
- children: A.map((e) => /* @__PURE__ */ y("button", {
95
- type: "button",
96
- onClick: () => S(`/brands/${e.id}`),
97
- className: "group flex flex-col overflow-hidden rounded-xl border border-border-seam bg-bg-surface text-left shadow-sm transition-all hover:border-accent-foreground/20 hover:shadow-md",
98
- children: [/* @__PURE__ */ v(c, {
99
- coverFileId: e.cover?.id,
100
- logoFileId: e.logo?.id,
101
- name: e.name,
102
- seed: e.id,
103
- showLogo: !0
104
- }), /* @__PURE__ */ y("div", {
105
- className: "px-4 pb-4 pt-3",
106
- children: [
107
- /* @__PURE__ */ y("div", {
108
- className: "flex min-h-[2.5rem] items-start justify-between gap-2 pl-20",
109
- children: [/* @__PURE__ */ y("div", {
110
- className: "min-w-0",
111
- children: [/* @__PURE__ */ y("div", {
112
- className: "flex items-center gap-1.5",
113
- children: [/* @__PURE__ */ v("h3", {
114
- className: "truncate text-base font-semibold text-text-primary",
115
- children: e.name
116
- }), e.isFeatured && /* @__PURE__ */ v(h, { className: "h-3.5 w-3.5 shrink-0 fill-status-warning-text text-status-warning-text" })]
117
- }), /* @__PURE__ */ y("p", {
118
- className: "truncate text-xs text-text-secondary",
119
- children: ["@", e.handle]
120
- })]
121
- }), /* @__PURE__ */ v(r, { status: e.status })]
122
- }),
123
- e.tagline && /* @__PURE__ */ v("p", {
124
- className: "mt-2 line-clamp-2 text-sm text-text-secondary",
125
- children: e.tagline
126
- }),
127
- e.aesthetics.length > 0 && /* @__PURE__ */ v(l, {
128
- tags: e.aesthetics.map(s),
129
- max: 4,
130
- className: "mt-3",
131
- tone: "accent"
132
- })
133
- ]
134
- })]
91
+ children: D.map((e) => /* @__PURE__ */ h(s, {
92
+ brand: e,
93
+ onClick: () => y(`/brands/${e.id}`)
135
94
  }, e.id))
136
- }), (D > 0 || j) && /* @__PURE__ */ y("div", {
95
+ }), (w > 0 || O) && /* @__PURE__ */ g("div", {
137
96
  className: "mt-6 flex items-center justify-center gap-2",
138
97
  children: [
139
- /* @__PURE__ */ y("button", {
98
+ /* @__PURE__ */ g("button", {
140
99
  type: "button",
141
- disabled: D === 0,
142
- onClick: () => O((e) => Math.max(0, e - b)),
100
+ disabled: w === 0,
101
+ onClick: () => T((e) => Math.max(0, e - _)),
143
102
  className: "inline-flex items-center gap-1 rounded-lg border border-border-seam px-3 py-1.5 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-40",
144
- children: [/* @__PURE__ */ v(f, { className: "h-4 w-4" }), " Previous"]
103
+ children: [/* @__PURE__ */ h(l, { className: "h-4 w-4" }), " Previous"]
145
104
  }),
146
- /* @__PURE__ */ y("span", {
105
+ /* @__PURE__ */ g("span", {
147
106
  className: "text-sm text-text-secondary",
148
- children: ["Page ", D / b + 1]
107
+ children: ["Page ", w / _ + 1]
149
108
  }),
150
- /* @__PURE__ */ y("button", {
109
+ /* @__PURE__ */ g("button", {
151
110
  type: "button",
152
- disabled: !j,
153
- onClick: () => O((e) => e + b),
111
+ disabled: !O,
112
+ onClick: () => T((e) => e + _),
154
113
  className: "inline-flex items-center gap-1 rounded-lg border border-border-seam px-3 py-1.5 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-40",
155
- children: ["Next ", /* @__PURE__ */ v(p, { className: "h-4 w-4" })]
114
+ children: ["Next ", /* @__PURE__ */ h(u, { className: "h-4 w-4" })]
156
115
  })
157
116
  ]
158
117
  })] })]
159
118
  });
160
119
  }
161
120
  //#endregion
162
- export { S as BrandsListPage };
121
+ export { y as BrandsListPage };
163
122
 
164
123
  //# sourceMappingURL=BrandsListPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BrandsListPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/brands/BrandsListPage.tsx"],"sourcesContent":["/**\n * Brands List Page\n * @module coolandlovely/pages/brands\n *\n * Lists brand storefronts (cursor-paginated `cooListBrands`) with status &\n * featured filters. Each card links to the brand detail page.\n */\n\nimport { useState } from 'react';\nimport { Store, Plus, Star, ChevronLeft, ChevronRight } 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 { BrandCover } from '../../components/BrandCover';\nimport { TagList } from '../../components/TagList';\nimport { useCoolAndLovely } from '../../context/CoolAndLovelyContext';\nimport { useBrands } from '../../hooks';\nimport { titleCase } from '../../utils/formatters';\nimport { cn } from '../../utils/cn';\nimport type { CooBrandStatus } from '../../types';\n\nconst PAGE_SIZE = 24;\n\nconst STATUS_OPTIONS: Array<{ value: CooBrandStatus | 'ALL'; label: string }> = [\n { value: 'ALL', label: 'All' },\n { value: 'PUBLISHED', label: 'Published' },\n { value: 'DRAFT', label: 'Draft' },\n { value: 'PENDING_REVIEW', label: 'In review' },\n { value: 'SUSPENDED', label: 'Suspended' },\n { value: 'ARCHIVED', label: 'Archived' },\n];\n\nexport function BrandsListPage() {\n const { navigateTo } = useCoolAndLovely();\n const [status, setStatus] = useState<CooBrandStatus | 'ALL'>('ALL');\n const [featuredOnly, setFeaturedOnly] = useState(false);\n const [offset, setOffset] = useState(0);\n\n const query = useBrands({\n status: status === 'ALL' ? undefined : status,\n featured: featuredOnly ? true : undefined,\n pagination: { limit: PAGE_SIZE, offset },\n });\n\n const brands = query.data?.items ?? [];\n const hasMore = query.data?.pageInfo.hasMore ?? false;\n\n return (\n <PageLayout\n title=\"Brands\"\n description=\"Storefronts on the platform with a real publish lifecycle\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/brands/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 brand\n </button>\n }\n >\n {/* Filters */}\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={() => {\n setStatus(opt.value);\n setOffset(0);\n }}\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 <button\n type=\"button\"\n onClick={() => {\n setFeaturedOnly((v) => !v);\n setOffset(0);\n }}\n className={cn(\n 'ml-auto inline-flex items-center gap-1.5 rounded-full px-3 py-1.5 text-sm font-medium transition-colors',\n featuredOnly\n ? 'bg-status-warning-bg-subtle text-status-warning-text'\n : 'bg-bg-sunken text-text-secondary hover:text-text-primary'\n )}\n >\n <Star className={cn('h-3.5 w-3.5', featuredOnly && 'fill-status-warning-text')} />{' '}\n Featured\n </button>\n </div>\n\n {query.isLoading ? (\n <LoadingView label=\"Loading brands…\" />\n ) : query.isError ? (\n <ErrorView onRetry={() => void query.refetch()} />\n ) : brands.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Store className=\"h-10 w-10\" />}\n title=\"No brands yet\"\n description=\"Launch the first storefront to start building the catalogue.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/brands/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 brand\n </button>\n }\n />\n ) : (\n <>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {brands.map((brand) => (\n <button\n key={brand.id}\n type=\"button\"\n onClick={() => navigateTo(`/brands/${brand.id}`)}\n className=\"group flex flex-col overflow-hidden rounded-xl border border-border-seam bg-bg-surface text-left shadow-sm transition-all hover:border-accent-foreground/20 hover:shadow-md\"\n >\n <BrandCover\n coverFileId={brand.cover?.id}\n logoFileId={brand.logo?.id}\n name={brand.name}\n seed={brand.id}\n showLogo\n />\n <div className=\"px-4 pb-4 pt-3\">\n <div className=\"flex min-h-[2.5rem] items-start justify-between gap-2 pl-20\">\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-1.5\">\n <h3 className=\"truncate text-base font-semibold text-text-primary\">\n {brand.name}\n </h3>\n {brand.isFeatured && (\n <Star className=\"h-3.5 w-3.5 shrink-0 fill-status-warning-text text-status-warning-text\" />\n )}\n </div>\n <p className=\"truncate text-xs text-text-secondary\">@{brand.handle}</p>\n </div>\n <StatusBadge status={brand.status} />\n </div>\n {brand.tagline && (\n <p className=\"mt-2 line-clamp-2 text-sm text-text-secondary\">{brand.tagline}</p>\n )}\n {brand.aesthetics.length > 0 && (\n <TagList\n tags={brand.aesthetics.map(titleCase)}\n max={4}\n className=\"mt-3\"\n tone=\"accent\"\n />\n )}\n </div>\n </button>\n ))}\n </div>\n\n {/* Pagination */}\n {(offset > 0 || hasMore) && (\n <div className=\"mt-6 flex items-center justify-center gap-2\">\n <button\n type=\"button\"\n disabled={offset === 0}\n onClick={() => setOffset((o) => Math.max(0, o - PAGE_SIZE))}\n className=\"inline-flex items-center gap-1 rounded-lg border border-border-seam px-3 py-1.5 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-40\"\n >\n <ChevronLeft className=\"h-4 w-4\" /> Previous\n </button>\n <span className=\"text-sm text-text-secondary\">Page {offset / PAGE_SIZE + 1}</span>\n <button\n type=\"button\"\n disabled={!hasMore}\n onClick={() => setOffset((o) => o + PAGE_SIZE)}\n className=\"inline-flex items-center gap-1 rounded-lg border border-border-seam px-3 py-1.5 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-40\"\n >\n Next <ChevronRight className=\"h-4 w-4\" />\n </button>\n </div>\n )}\n </>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"BrandsListPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/brands/BrandsListPage.tsx"],"sourcesContent":["/**\n * Brands List Page\n * @module coolandlovely/pages/brands\n *\n * Lists brand storefronts (cursor-paginated `cooListBrands`) with status &\n * featured filters. Each card links to the brand detail page.\n */\n\nimport { useState } from 'react';\nimport { Store, Plus, ChevronLeft, ChevronRight, Star } from 'lucide-react';\nimport { PageLayout } from '../../components/PageLayout';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { useCoolAndLovely } from '../../context/CoolAndLovelyContext';\nimport { useBrands } from '../../hooks';\nimport { BrandCard } from '../../components/BrandCard';\nimport { cn } from '../../utils/cn';\nimport type { CooBrandStatus } from '../../types';\n\nconst PAGE_SIZE = 24;\n\nconst STATUS_OPTIONS: Array<{ value: CooBrandStatus | 'ALL'; label: string }> = [\n { value: 'ALL', label: 'All' },\n { value: 'PUBLISHED', label: 'Published' },\n { value: 'DRAFT', label: 'Draft' },\n { value: 'PENDING_REVIEW', label: 'In review' },\n { value: 'SUSPENDED', label: 'Suspended' },\n { value: 'ARCHIVED', label: 'Archived' },\n];\n\nexport function BrandsListPage() {\n const { navigateTo } = useCoolAndLovely();\n const [status, setStatus] = useState<CooBrandStatus | 'ALL'>('ALL');\n const [featuredOnly, setFeaturedOnly] = useState(false);\n const [offset, setOffset] = useState(0);\n\n const query = useBrands({\n status: status === 'ALL' ? undefined : status,\n featured: featuredOnly ? true : undefined,\n pagination: { limit: PAGE_SIZE, offset },\n });\n\n const brands = query.data?.items ?? [];\n const hasMore = query.data?.pageInfo.hasMore ?? false;\n\n return (\n <PageLayout\n title=\"Brands\"\n description=\"Storefronts on the platform with a real publish lifecycle\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/brands/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 brand\n </button>\n }\n >\n {/* Filters */}\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={() => {\n setStatus(opt.value);\n setOffset(0);\n }}\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 <button\n type=\"button\"\n onClick={() => {\n setFeaturedOnly((v) => !v);\n setOffset(0);\n }}\n className={cn(\n 'ml-auto inline-flex items-center gap-1.5 rounded-full px-3 py-1.5 text-sm font-medium transition-colors',\n featuredOnly\n ? 'bg-status-warning-bg-subtle text-status-warning-text'\n : 'bg-bg-sunken text-text-secondary hover:text-text-primary'\n )}\n >\n <Star className={cn('h-3.5 w-3.5', featuredOnly && 'fill-status-warning-text')} />{' '}\n Featured\n </button>\n </div>\n\n {query.isLoading ? (\n <LoadingView label=\"Loading brands…\" />\n ) : query.isError ? (\n <ErrorView onRetry={() => void query.refetch()} />\n ) : brands.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Store className=\"h-10 w-10\" />}\n title=\"No brands yet\"\n description=\"Launch the first storefront to start building the catalogue.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/brands/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 brand\n </button>\n }\n />\n ) : (\n <>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {brands.map((brand) => (\n <BrandCard\n key={brand.id}\n brand={brand}\n onClick={() => navigateTo(`/brands/${brand.id}`)}\n />\n ))}\n </div>\n\n {/* Pagination */}\n {(offset > 0 || hasMore) && (\n <div className=\"mt-6 flex items-center justify-center gap-2\">\n <button\n type=\"button\"\n disabled={offset === 0}\n onClick={() => setOffset((o) => Math.max(0, o - PAGE_SIZE))}\n className=\"inline-flex items-center gap-1 rounded-lg border border-border-seam px-3 py-1.5 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-40\"\n >\n <ChevronLeft className=\"h-4 w-4\" /> Previous\n </button>\n <span className=\"text-sm text-text-secondary\">Page {offset / PAGE_SIZE + 1}</span>\n <button\n type=\"button\"\n disabled={!hasMore}\n onClick={() => setOffset((o) => o + PAGE_SIZE)}\n className=\"inline-flex items-center gap-1 rounded-lg border border-border-seam px-3 py-1.5 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken disabled:cursor-not-allowed disabled:opacity-40\"\n >\n Next <ChevronRight className=\"h-4 w-4\" />\n </button>\n </div>\n )}\n </>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -8,8 +8,8 @@ import { formatDate as l, formatPrice as u, titleCase as d } from "../../utils/f
8
8
  import "../../hooks/index.js";
9
9
  import { TagList as f } from "../../components/TagList.js";
10
10
  import { ActorName as p } from "../../components/ActorName.js";
11
- import { BrandCreatorAvatars as m } from "../../components/BrandCreatorAvatars.js";
12
- import { StepTracker as h } from "../../components/StepTracker.js";
11
+ import { StepTracker as m } from "../../components/StepTracker.js";
12
+ import { BrandCreatorAvatars as h } from "../../components/BrandCreatorAvatars.js";
13
13
  import { ArrowLeft as g, Loader2 as _, Pencil as v, Sparkles as y, Store as b, Trash2 as x } from "lucide-react";
14
14
  import { useParams as S } from "react-router";
15
15
  import { jsx as C, jsxs as w } from "react/jsx-runtime";
@@ -84,7 +84,7 @@ function O() {
84
84
  /* @__PURE__ */ w("div", {
85
85
  className: "flex items-center gap-3",
86
86
  children: [
87
- /* @__PURE__ */ C(m, {
87
+ /* @__PURE__ */ C(h, {
88
88
  brandLogoFileId: N.brand?.logo?.id,
89
89
  brandSeed: N.brandId,
90
90
  creatorId: N.creatorId,
@@ -173,7 +173,7 @@ function O() {
173
173
  className: "mb-3 text-sm font-semibold text-text-primary",
174
174
  children: "Lifecycle"
175
175
  }),
176
- /* @__PURE__ */ C(h, {
176
+ /* @__PURE__ */ C(m, {
177
177
  steps: I,
178
178
  current: N.status,
179
179
  className: "mb-5"
@@ -4,8 +4,8 @@ import { ErrorView as n, LoadingView as r } from "../../components/StateViews.js
4
4
  import { useBrands as i, useCollaboration as a, useCreateCollaboration as o, useUpdateCollaboration as s } from "../../hooks/useCoolAndLovelyApi.js";
5
5
  import { parseCsv as c, titleCase as l } from "../../utils/formatters.js";
6
6
  import "../../hooks/index.js";
7
- import { ActorName as u } from "../../components/ActorName.js";
8
- import { SelectField as d, TextAreaField as f, TextField as p } from "../../components/Field.js";
7
+ import { SelectField as u, TextAreaField as d, TextField as f } from "../../components/Field.js";
8
+ import { ActorName as p } from "../../components/ActorName.js";
9
9
  import { useEffect as m, useMemo as h, useState as g } from "react";
10
10
  import { ArrowLeft as _, Handshake as v, Loader2 as y, Save as b } from "lucide-react";
11
11
  import { useParams as x } from "react-router";
@@ -169,7 +169,7 @@ function A() {
169
169
  }), /* @__PURE__ */ S("p", {
170
170
  className: "rounded-lg border border-border-seam bg-bg-sunken px-3 py-2 text-sm text-text-secondary",
171
171
  children: L.data?.brand?.name ?? R.brandId
172
- })] }) : /* @__PURE__ */ S(d, {
172
+ })] }) : /* @__PURE__ */ S(u, {
173
173
  id: "brandId",
174
174
  label: "Brand",
175
175
  value: R.brandId,
@@ -178,7 +178,7 @@ function A() {
178
178
  required: !0,
179
179
  placeholder: I.isLoading ? "Loading brands…" : "Select a brand",
180
180
  error: B.brandId
181
- }), /* @__PURE__ */ S(d, {
181
+ }), /* @__PURE__ */ S(u, {
182
182
  id: "role",
183
183
  label: "Role",
184
184
  value: R.role,
@@ -187,7 +187,7 @@ function A() {
187
187
  disabled: G
188
188
  })]
189
189
  }),
190
- /* @__PURE__ */ S(p, {
190
+ /* @__PURE__ */ S(f, {
191
191
  id: "title",
192
192
  label: "Title",
193
193
  value: R.title,
@@ -205,9 +205,9 @@ function A() {
205
205
  children: "Creator"
206
206
  }), /* @__PURE__ */ S("p", {
207
207
  className: "rounded-lg border border-border-seam bg-bg-sunken px-3 py-2 text-sm text-text-secondary",
208
- children: /* @__PURE__ */ S(u, { id: R.creatorId })
208
+ children: /* @__PURE__ */ S(p, { id: R.creatorId })
209
209
  })]
210
- }) : /* @__PURE__ */ S(p, {
210
+ }) : /* @__PURE__ */ S(f, {
211
211
  id: "creatorId",
212
212
  label: "Creator ID",
213
213
  value: R.creatorId,
@@ -218,7 +218,7 @@ function A() {
218
218
  error: B.creatorId,
219
219
  className: "mt-4"
220
220
  }),
221
- /* @__PURE__ */ S(f, {
221
+ /* @__PURE__ */ S(d, {
222
222
  id: "brief",
223
223
  label: "Brief",
224
224
  value: R.brief,
@@ -230,7 +230,7 @@ function A() {
230
230
  }),
231
231
  /* @__PURE__ */ C("div", {
232
232
  className: "mt-4 grid grid-cols-1 gap-4 sm:grid-cols-2",
233
- children: [/* @__PURE__ */ S(p, {
233
+ children: [/* @__PURE__ */ S(f, {
234
234
  id: "compensation",
235
235
  label: "Compensation",
236
236
  type: "number",
@@ -239,7 +239,7 @@ function A() {
239
239
  placeholder: "0.00",
240
240
  error: B.compensation,
241
241
  disabled: G
242
- }), /* @__PURE__ */ S(p, {
242
+ }), /* @__PURE__ */ S(f, {
243
243
  id: "currency",
244
244
  label: "Currency",
245
245
  value: R.currency,
@@ -250,14 +250,14 @@ function A() {
250
250
  }),
251
251
  /* @__PURE__ */ C("div", {
252
252
  className: "mt-4 grid grid-cols-1 gap-4 sm:grid-cols-2",
253
- children: [/* @__PURE__ */ S(p, {
253
+ children: [/* @__PURE__ */ S(f, {
254
254
  id: "startDate",
255
255
  label: "Start date",
256
256
  type: "date",
257
257
  value: R.startDate,
258
258
  onChange: (e) => H("startDate", e),
259
259
  disabled: G
260
- }), /* @__PURE__ */ S(p, {
260
+ }), /* @__PURE__ */ S(f, {
261
261
  id: "endDate",
262
262
  label: "End date",
263
263
  type: "date",
@@ -266,7 +266,7 @@ function A() {
266
266
  disabled: G
267
267
  })]
268
268
  }),
269
- /* @__PURE__ */ S(p, {
269
+ /* @__PURE__ */ S(f, {
270
270
  id: "tags",
271
271
  label: "Tags",
272
272
  value: R.tags,
@@ -6,8 +6,8 @@ import { ErrorView as i, LoadingView as a } from "../../components/StateViews.js
6
6
  import { useCollaborations as o } from "../../hooks/useCoolAndLovelyApi.js";
7
7
  import { formatDate as s, formatPrice as c, titleCase as l } from "../../utils/formatters.js";
8
8
  import "../../hooks/index.js";
9
- import { ActorName as u } from "../../components/ActorName.js";
10
- import { EmptyState as d } from "../../components/EmptyState.js";
9
+ import { EmptyState as u } from "../../components/EmptyState.js";
10
+ import { ActorName as d } from "../../components/ActorName.js";
11
11
  import { BrandCreatorAvatars as f } from "../../components/BrandCreatorAvatars.js";
12
12
  import { useState as p } from "react";
13
13
  import { Handshake as m, Plus as h } from "lucide-react";
@@ -62,7 +62,7 @@ function y() {
62
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"),
63
63
  children: e.label
64
64
  }, e.value))
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
+ }), S.isLoading ? /* @__PURE__ */ g(a, { label: "Loading collaborations…" }) : S.isError ? /* @__PURE__ */ g(i, { onRetry: () => void S.refetch() }) : C.length === 0 ? /* @__PURE__ */ g(u, {
66
66
  illustration: "empty-data",
67
67
  icon: /* @__PURE__ */ g(m, { className: "h-10 w-10" }),
68
68
  title: "No collaborations yet",
@@ -100,7 +100,7 @@ function y() {
100
100
  children: [
101
101
  e.brand?.name ?? "Brand",
102
102
  " × ",
103
- /* @__PURE__ */ g(u, { id: e.creatorId })
103
+ /* @__PURE__ */ g(d, { id: e.creatorId })
104
104
  ]
105
105
  })]
106
106
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"CollectionsListPage.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/pages/collections/CollectionsListPage.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAyBH,wBAAgB,mBAAmB,gCAkHlC"}
1
+ {"version":3,"file":"CollectionsListPage.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/pages/collections/CollectionsListPage.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAsBH,wBAAgB,mBAAmB,gCAwElC"}
@@ -1,19 +1,16 @@
1
1
  import { useCoolAndLovely as e } from "../../context/CoolAndLovelyContext.js";
2
2
  import { cn as t } from "../../utils/cn.js";
3
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 { useCollections as s } from "../../hooks/useCoolAndLovelyApi.js";
8
- import { formatDate as c, titleCase as l } from "../../utils/formatters.js";
4
+ import { ErrorView as r, LoadingView as i } from "../../components/StateViews.js";
5
+ import { useCollections as a } from "../../hooks/useCoolAndLovelyApi.js";
9
6
  import "../../hooks/index.js";
10
- import { TagList as u } from "../../components/TagList.js";
11
- import { EmptyState as d } from "../../components/EmptyState.js";
12
- import { useState as f } from "react";
13
- import { Plus as p, Shapes as m } from "lucide-react";
14
- import { Fragment as h, jsx as g, jsxs as _ } from "react/jsx-runtime";
7
+ import { EmptyState as o } from "../../components/EmptyState.js";
8
+ import { CollectionCard as s } from "../../components/CollectionCard.js";
9
+ import { useState as c } from "react";
10
+ import { Plus as l, Shapes as u } from "lucide-react";
11
+ import { jsx as d, jsxs as f } from "react/jsx-runtime";
15
12
  //#region src/coolandlovely/pages/collections/CollectionsListPage.tsx
16
- var v = [
13
+ var p = [
17
14
  {
18
15
  value: "ALL",
19
16
  label: "All"
@@ -39,89 +36,46 @@ var v = [
39
36
  label: "Archived"
40
37
  }
41
38
  ];
42
- function y() {
43
- let { navigateTo: y } = e(), [b, x] = f("ALL"), S = s({ status: b === "ALL" ? void 0 : b }), C = S.data ?? [];
44
- return /* @__PURE__ */ _(n, {
39
+ function m() {
40
+ let { navigateTo: m } = e(), [h, g] = c("ALL"), _ = a({ status: h === "ALL" ? void 0 : h }), v = _.data ?? [];
41
+ return /* @__PURE__ */ f(n, {
45
42
  title: "Collections",
46
43
  description: "Seasonal drops and curated edits grouped by brand",
47
- actions: /* @__PURE__ */ _("button", {
44
+ actions: /* @__PURE__ */ f("button", {
48
45
  type: "button",
49
- onClick: () => y("/collections/new"),
46
+ onClick: () => m("/collections/new"),
50
47
  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",
51
- children: [/* @__PURE__ */ g(p, { className: "h-4 w-4" }), " New collection"]
48
+ children: [/* @__PURE__ */ d(l, { className: "h-4 w-4" }), " New collection"]
52
49
  }),
53
- children: [/* @__PURE__ */ g("div", {
50
+ children: [/* @__PURE__ */ d("div", {
54
51
  className: "mb-6 flex flex-wrap items-center gap-2",
55
- children: v.map((e) => /* @__PURE__ */ g("button", {
52
+ children: p.map((e) => /* @__PURE__ */ d("button", {
56
53
  type: "button",
57
- onClick: () => x(e.value),
58
- className: t("rounded-full px-3 py-1.5 text-sm font-medium transition-colors", b === e.value ? "bg-accent-purple-subtle text-text-primary" : "bg-bg-sunken text-text-secondary hover:text-text-primary"),
54
+ onClick: () => g(e.value),
55
+ className: t("rounded-full px-3 py-1.5 text-sm font-medium transition-colors", h === e.value ? "bg-accent-purple-subtle text-text-primary" : "bg-bg-sunken text-text-secondary hover:text-text-primary"),
59
56
  children: e.label
60
57
  }, e.value))
61
- }), S.isLoading ? /* @__PURE__ */ g(a, { label: "Loading collections…" }) : S.isError ? /* @__PURE__ */ g(i, { onRetry: () => void S.refetch() }) : C.length === 0 ? /* @__PURE__ */ g(d, {
58
+ }), _.isLoading ? /* @__PURE__ */ d(i, { label: "Loading collections…" }) : _.isError ? /* @__PURE__ */ d(r, { onRetry: () => void _.refetch() }) : v.length === 0 ? /* @__PURE__ */ d(o, {
62
59
  illustration: "empty-data",
63
- icon: /* @__PURE__ */ g(m, { className: "h-10 w-10" }),
60
+ icon: /* @__PURE__ */ d(u, { className: "h-10 w-10" }),
64
61
  title: "No collections yet",
65
62
  description: "Group pieces into a seasonal drop to start a collection.",
66
- action: /* @__PURE__ */ _("button", {
63
+ action: /* @__PURE__ */ f("button", {
67
64
  type: "button",
68
- onClick: () => y("/collections/new"),
65
+ onClick: () => m("/collections/new"),
69
66
  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",
70
- children: [/* @__PURE__ */ g(p, { className: "h-4 w-4" }), " New collection"]
67
+ children: [/* @__PURE__ */ d(l, { className: "h-4 w-4" }), " New collection"]
71
68
  })
72
- }) : /* @__PURE__ */ g("div", {
69
+ }) : /* @__PURE__ */ d("div", {
73
70
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
74
- children: C.map((e) => /* @__PURE__ */ _("button", {
75
- type: "button",
76
- onClick: () => y(`/collections/${e.id}`),
77
- className: "group overflow-hidden rounded-xl border border-border-seam bg-bg-surface text-left shadow-sm transition-all hover:border-accent-foreground/20 hover:shadow-md",
78
- children: [/* @__PURE__ */ _("div", {
79
- className: "relative",
80
- children: [/* @__PURE__ */ g(o, {
81
- icon: /* @__PURE__ */ g(m, { className: "h-10 w-10" }),
82
- seed: e.id,
83
- fileId: e.cover?.id,
84
- alt: e.name,
85
- className: "aspect-[16/10] w-full",
86
- overlay: /* @__PURE__ */ _(h, { children: [/* @__PURE__ */ g("div", { className: "pointer-events-none absolute inset-0 bg-gradient-to-t from-bg-canvas via-bg-canvas/55 to-transparent" }), /* @__PURE__ */ _("div", {
87
- className: "absolute inset-x-0 bottom-0 flex items-end justify-between gap-2 p-4",
88
- children: [/* @__PURE__ */ _("div", {
89
- className: "min-w-0",
90
- children: [/* @__PURE__ */ g("h3", {
91
- className: "truncate text-lg font-semibold text-text-primary",
92
- children: e.name
93
- }), e.brand?.name && /* @__PURE__ */ g("p", {
94
- className: "truncate text-xs text-text-secondary",
95
- children: e.brand.name
96
- })]
97
- }), /* @__PURE__ */ g(r, {
98
- status: e.status,
99
- className: "shrink-0 shadow-sm"
100
- })]
101
- })] })
102
- }), /* @__PURE__ */ g("span", {
103
- className: "absolute right-3 top-3 rounded-full border border-border-seam bg-bg-surface/85 px-2.5 py-0.5 text-xs font-medium text-text-primary backdrop-blur-sm",
104
- children: l(e.season)
105
- })]
106
- }), (e.publishAt || e.tags.length > 0) && /* @__PURE__ */ _("div", {
107
- className: "p-4",
108
- children: [e.publishAt && /* @__PURE__ */ _("p", {
109
- className: "text-xs text-text-secondary",
110
- children: ["Publishes ", c(e.publishAt, {
111
- hour: void 0,
112
- minute: void 0
113
- })]
114
- }), e.tags.length > 0 && /* @__PURE__ */ g(u, {
115
- tags: e.tags,
116
- max: 4,
117
- className: e.publishAt ? "mt-2" : void 0
118
- })]
119
- })]
71
+ children: v.map((e) => /* @__PURE__ */ d(s, {
72
+ collection: e,
73
+ onClick: () => m(`/collections/${e.id}`)
120
74
  }, e.id))
121
75
  })]
122
76
  });
123
77
  }
124
78
  //#endregion
125
- export { y as CollectionsListPage };
79
+ export { m as CollectionsListPage };
126
80
 
127
81
  //# sourceMappingURL=CollectionsListPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CollectionsListPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/collections/CollectionsListPage.tsx"],"sourcesContent":["/**\n * Collections List Page\n * @module coolandlovely/pages/collections\n *\n * Lists seasonal collections (`cooListCollections`) with status filter.\n */\n\nimport { useState } from 'react';\nimport { Plus, Shapes } 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 { TagList } from '../../components/TagList';\nimport { useCoolAndLovely } from '../../context/CoolAndLovelyContext';\nimport { useCollections } from '../../hooks';\nimport { titleCase, formatDate } from '../../utils/formatters';\nimport { cn } from '../../utils/cn';\nimport type { CooCollectionStatus } from '../../types';\n\nconst STATUS_OPTIONS: Array<{ value: CooCollectionStatus | 'ALL'; label: string }> = [\n { value: 'ALL', label: 'All' },\n { value: 'LIVE', label: 'Live' },\n { value: 'SCHEDULED', label: 'Scheduled' },\n { value: 'DRAFT', label: 'Draft' },\n { value: 'ENDED', label: 'Ended' },\n { value: 'ARCHIVED', label: 'Archived' },\n];\n\nexport function CollectionsListPage() {\n const { navigateTo } = useCoolAndLovely();\n const [status, setStatus] = useState<CooCollectionStatus | 'ALL'>('ALL');\n\n const query = useCollections({ status: status === 'ALL' ? undefined : status });\n const collections = query.data ?? [];\n\n return (\n <PageLayout\n title=\"Collections\"\n description=\"Seasonal drops and curated edits grouped by brand\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/collections/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 collection\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-accent-purple-subtle text-text-primary'\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 collections…\" />\n ) : query.isError ? (\n <ErrorView onRetry={() => void query.refetch()} />\n ) : collections.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Shapes className=\"h-10 w-10\" />}\n title=\"No collections yet\"\n description=\"Group pieces into a seasonal drop to start a collection.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/collections/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 collection\n </button>\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {collections.map((c) => (\n <button\n key={c.id}\n type=\"button\"\n onClick={() => navigateTo(`/collections/${c.id}`)}\n className=\"group overflow-hidden rounded-xl border border-border-seam bg-bg-surface text-left shadow-sm transition-all hover:border-accent-foreground/20 hover:shadow-md\"\n >\n <div className=\"relative\">\n <Thumbnail\n icon={<Shapes className=\"h-10 w-10\" />}\n seed={c.id}\n fileId={c.cover?.id}\n alt={c.name}\n className=\"aspect-[16/10] w-full\"\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 items-end justify-between gap-2 p-4\">\n <div className=\"min-w-0\">\n <h3 className=\"truncate text-lg font-semibold text-text-primary\">\n {c.name}\n </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} className=\"shrink-0 shadow-sm\" />\n </div>\n </>\n }\n />\n <span className=\"absolute right-3 top-3 rounded-full border border-border-seam bg-bg-surface/85 px-2.5 py-0.5 text-xs font-medium text-text-primary backdrop-blur-sm\">\n {titleCase(c.season)}\n </span>\n </div>\n {(c.publishAt || c.tags.length > 0) && (\n <div className=\"p-4\">\n {c.publishAt && (\n <p className=\"text-xs text-text-secondary\">\n Publishes {formatDate(c.publishAt, { hour: undefined, minute: undefined })}\n </p>\n )}\n {c.tags.length > 0 && (\n <TagList tags={c.tags} max={4} className={c.publishAt ? 'mt-2' : undefined} />\n )}\n </div>\n )}\n </button>\n ))}\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CollectionsListPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/collections/CollectionsListPage.tsx"],"sourcesContent":["/**\n * Collections List Page\n * @module coolandlovely/pages/collections\n *\n * Lists seasonal collections (`cooListCollections`) with status filter.\n */\n\nimport { useState } from 'react';\nimport { Plus, Shapes } from 'lucide-react';\nimport { PageLayout } from '../../components/PageLayout';\nimport { CollectionCard } from '../../components/CollectionCard';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingView, ErrorView } from '../../components/StateViews';\nimport { useCoolAndLovely } from '../../context/CoolAndLovelyContext';\nimport { useCollections } from '../../hooks';\nimport { cn } from '../../utils/cn';\nimport type { CooCollectionStatus } from '../../types';\n\nconst STATUS_OPTIONS: Array<{ value: CooCollectionStatus | 'ALL'; label: string }> = [\n { value: 'ALL', label: 'All' },\n { value: 'LIVE', label: 'Live' },\n { value: 'SCHEDULED', label: 'Scheduled' },\n { value: 'DRAFT', label: 'Draft' },\n { value: 'ENDED', label: 'Ended' },\n { value: 'ARCHIVED', label: 'Archived' },\n];\n\nexport function CollectionsListPage() {\n const { navigateTo } = useCoolAndLovely();\n const [status, setStatus] = useState<CooCollectionStatus | 'ALL'>('ALL');\n\n const query = useCollections({ status: status === 'ALL' ? undefined : status });\n const collections = query.data ?? [];\n\n return (\n <PageLayout\n title=\"Collections\"\n description=\"Seasonal drops and curated edits grouped by brand\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/collections/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 collection\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-accent-purple-subtle text-text-primary'\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 collections…\" />\n ) : query.isError ? (\n <ErrorView onRetry={() => void query.refetch()} />\n ) : collections.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Shapes className=\"h-10 w-10\" />}\n title=\"No collections yet\"\n description=\"Group pieces into a seasonal drop to start a collection.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/collections/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 collection\n </button>\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {collections.map((collection) => (\n <CollectionCard\n key={collection.id}\n collection={collection}\n onClick={() => navigateTo(`/collections/${collection.id}`)}\n />\n ))}\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAkBA,IAAM,IAA+E;CACnF;EAAE,OAAO;EAAO,OAAO;EAAO;CAC9B;EAAE,OAAO;EAAQ,OAAO;EAAQ;CAChC;EAAE,OAAO;EAAa,OAAO;EAAa;CAC1C;EAAE,OAAO;EAAS,OAAO;EAAS;CAClC;EAAE,OAAO;EAAS,OAAO;EAAS;CAClC;EAAE,OAAO;EAAY,OAAO;EAAY;CACzC;AAED,SAAgB,IAAsB;CACpC,IAAM,EAAE,kBAAe,GAAkB,EACnC,CAAC,GAAQ,KAAa,EAAsC,MAAM,EAElE,IAAQ,EAAe,EAAE,QAAQ,MAAW,QAAQ,KAAA,IAAY,GAAQ,CAAC,EACzE,IAAc,EAAM,QAAQ,EAAE;AAEpC,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,UAAD;GACE,MAAK;GACL,eAAe,EAAW,mBAAmB;GAC7C,WAAU;aAHZ,CAKE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,kBACrB;;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,8CACA,2DACL;cAEA,EAAI;IACE,EAXF,EAAI,MAWF,CACT;GACE,CAAA,EAEL,EAAM,YACL,kBAAC,GAAD,EAAa,OAAM,wBAAyB,CAAA,GAC1C,EAAM,UACR,kBAAC,GAAD,EAAW,eAAe,KAAK,EAAM,SAAS,EAAI,CAAA,GAChD,EAAY,WAAW,IACzB,kBAAC,GAAD;GACE,cAAa;GACb,MAAM,kBAAC,GAAD,EAAQ,WAAU,aAAc,CAAA;GACtC,OAAM;GACN,aAAY;GACZ,QACE,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,EAAW,mBAAmB;IAC7C,WAAU;cAHZ,CAKE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,kBACrB;;GAEX,CAAA,GAEF,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAY,KAAK,MAChB,kBAAC,GAAD;IAEc;IACZ,eAAe,EAAW,gBAAgB,EAAW,KAAK;IAC1D,EAHK,EAAW,GAGhB,CACF;GACE,CAAA,CAEG"}