@burdenoff/microfe-coolandlovely 2026.628.1 → 2026.706.1
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.
- package/dist/coolandlovely/components/Field.js.map +1 -1
- package/dist/coolandlovely/components/StateViews.js.map +1 -1
- package/dist/coolandlovely/context/CoolAndLovelyContext.js.map +1 -1
- package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js +149 -148
- package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js.map +1 -1
- package/dist/coolandlovely/pages/HomePage.js.map +1 -1
- package/dist/coolandlovely/pages/brands/BrandDetailPage.js.map +1 -1
- package/dist/coolandlovely/pages/brands/BrandFormPage.js +1 -1
- package/dist/coolandlovely/pages/brands/BrandFormPage.js.map +1 -1
- package/dist/coolandlovely/pages/brands/BrandsListPage.js +5 -1
- package/dist/coolandlovely/pages/brands/BrandsListPage.js.map +1 -1
- package/dist/coolandlovely/pages/collaborations/CollaborationDetailPage.js.map +1 -1
- package/dist/coolandlovely/pages/collaborations/CollaborationsListPage.js.map +1 -1
- package/dist/coolandlovely/pages/collections/CollectionDetailPage.js.map +1 -1
- package/dist/coolandlovely/pages/collections/CollectionsListPage.js.map +1 -1
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.js.map +1 -1
- package/dist/coolandlovely/pages/items/StyleItemsListPage.js.map +1 -1
- package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.js.map +1 -1
- package/dist/coolandlovely/pages/looks/LookDetailPage.js.map +1 -1
- package/dist/coolandlovely/pages/looks/LookFormPage.js.map +1 -1
- package/dist/coolandlovely/pages/looks/LooksListPage.js +5 -1
- package/dist/coolandlovely/pages/looks/LooksListPage.js.map +1 -1
- package/dist/coolandlovely/pages/wardrobe/WardrobeFormPage.js.map +1 -1
- package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -83,7 +83,11 @@ function C() {
|
|
|
83
83
|
D((e) => !e), k(0);
|
|
84
84
|
},
|
|
85
85
|
className: t("ml-auto inline-flex items-center gap-1.5 rounded-full px-3 py-1.5 text-sm font-medium transition-colors", E ? "bg-status-warning-bg-subtle text-status-warning-text" : "bg-bg-sunken text-text-secondary hover:text-text-primary"),
|
|
86
|
-
children: [
|
|
86
|
+
children: [
|
|
87
|
+
/* @__PURE__ */ y(_, { className: t("h-3.5 w-3.5", E && "fill-status-warning-text") }),
|
|
88
|
+
" ",
|
|
89
|
+
"Featured"
|
|
90
|
+
]
|
|
87
91
|
})]
|
|
88
92
|
}), A.isLoading ? /* @__PURE__ */ y(a, { label: "Loading looks…" }) : A.isError ? /* @__PURE__ */ y(i, { onRetry: () => void A.refetch() }) : j.length === 0 ? /* @__PURE__ */ y(l, {
|
|
89
93
|
illustration: "empty-data",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LooksListPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/looks/LooksListPage.tsx"],"sourcesContent":["/**\n * Looks List Page\n * @module coolandlovely/pages/looks\n *\n * Cursor-paginated feed of published looks (`cooListLooks`) with occasion &\n * featured filters.\n */\n\nimport { useState } from 'react';\nimport { Plus, Heart, Bookmark, Sparkles, ChevronLeft, ChevronRight, Star } 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 { useLooks } from '../../hooks';\nimport { titleCase } from '../../utils/formatters';\nimport { cn } from '../../utils/cn';\nimport type { CooLookOccasion } from '../../types';\n\nconst PAGE_SIZE = 24;\n\nconst OCCASIONS: Array<{ value: CooLookOccasion | 'ALL'; label: string }> = [\n { value: 'ALL', label: 'All' },\n { value: 'EVERYDAY', label: 'Everyday' },\n { value: 'WORK', label: 'Work' },\n { value: 'EVENING', label: 'Evening' },\n { value: 'WEDDING_GUEST', label: 'Wedding guest' },\n { value: 'VACATION', label: 'Vacation' },\n { value: 'PARTY', label: 'Party' },\n { value: 'ACTIVE', label: 'Active' },\n { value: 'OTHER', label: 'Other' },\n];\n\nexport function LooksListPage() {\n const { navigateTo } = useCoolAndLovely();\n const [occasion, setOccasion] = useState<CooLookOccasion | 'ALL'>('ALL');\n const [featuredOnly, setFeaturedOnly] = useState(false);\n const [offset, setOffset] = useState(0);\n\n const query = useLooks({\n occasion: occasion === 'ALL' ? undefined : occasion,\n featured: featuredOnly ? true : undefined,\n pagination: { limit: PAGE_SIZE, offset },\n });\n\n const looks = query.data?.items ?? [];\n const hasMore = query.data?.pageInfo.hasMore ?? false;\n\n return (\n <PageLayout\n title=\"Looks\"\n description=\"Shop-the-look outfits built from real catalogue pieces\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/looks/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 look\n </button>\n }\n >\n <div className=\"mb-6 flex flex-wrap items-center gap-2\">\n {OCCASIONS.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n onClick={() => {\n setOccasion(opt.value);\n setOffset(0);\n }}\n className={cn(\n 'rounded-full px-3 py-1.5 text-sm font-medium transition-colors',\n occasion === 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')} /> Featured\n </button>\n </div>\n\n {query.isLoading ? (\n <LoadingView label=\"Loading looks…\" />\n ) : query.isError ? (\n <ErrorView onRetry={() => void query.refetch()} />\n ) : looks.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Sparkles className=\"h-10 w-10\" />}\n title=\"No looks yet\"\n description=\"Publish a shop-the-look outfit from catalogue pieces.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/looks/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 look\n </button>\n }\n />\n ) : (\n <>\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4\">\n {looks.map((look) => (\n <button\n key={look.id}\n type=\"button\"\n onClick={() => navigateTo(`/looks/${look.id}`)}\n className=\"overflow-hidden rounded-lg 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 icon={<Sparkles className=\"h-9 w-9\" />} seed={look.id} className=\"h-40 w-full\" />\n {look.isFeatured && (\n <div className=\"absolute left-2 top-2\">\n <span className=\"inline-flex items-center gap-1 rounded-full bg-status-warning-bg-subtle px-2 py-0.5 text-xs font-medium text-status-warning-text\">\n <Star className=\"h-3 w-3 fill-status-warning-text\" /> Featured\n </span>\n </div>\n )}\n {look.publishedAt === null && (\n <div className=\"absolute right-2 top-2\">\n <StatusBadge status=\"draft\" />\n </div>\n )}\n </div>\n <div className=\"p-3\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{look.title}</p>\n <div className=\"mt-1.5 flex items-center justify-between text-xs text-text-secondary\">\n <span>{titleCase(look.occasion)}</span>\n <span className=\"flex items-center gap-2\">\n <span className=\"flex items-center gap-1\">\n <Heart className=\"h-3 w-3\" /> {look.likeCount}\n </span>\n <span className=\"flex items-center gap-1\">\n <Bookmark className=\"h-3 w-3\" /> {look.saveCount}\n </span>\n </span>\n </div>\n </div>\n </button>\n ))}\n </div>\n\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":"LooksListPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/looks/LooksListPage.tsx"],"sourcesContent":["/**\n * Looks List Page\n * @module coolandlovely/pages/looks\n *\n * Cursor-paginated feed of published looks (`cooListLooks`) with occasion &\n * featured filters.\n */\n\nimport { useState } from 'react';\nimport { Plus, Heart, Bookmark, Sparkles, ChevronLeft, ChevronRight, Star } 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 { useLooks } from '../../hooks';\nimport { titleCase } from '../../utils/formatters';\nimport { cn } from '../../utils/cn';\nimport type { CooLookOccasion } from '../../types';\n\nconst PAGE_SIZE = 24;\n\nconst OCCASIONS: Array<{ value: CooLookOccasion | 'ALL'; label: string }> = [\n { value: 'ALL', label: 'All' },\n { value: 'EVERYDAY', label: 'Everyday' },\n { value: 'WORK', label: 'Work' },\n { value: 'EVENING', label: 'Evening' },\n { value: 'WEDDING_GUEST', label: 'Wedding guest' },\n { value: 'VACATION', label: 'Vacation' },\n { value: 'PARTY', label: 'Party' },\n { value: 'ACTIVE', label: 'Active' },\n { value: 'OTHER', label: 'Other' },\n];\n\nexport function LooksListPage() {\n const { navigateTo } = useCoolAndLovely();\n const [occasion, setOccasion] = useState<CooLookOccasion | 'ALL'>('ALL');\n const [featuredOnly, setFeaturedOnly] = useState(false);\n const [offset, setOffset] = useState(0);\n\n const query = useLooks({\n occasion: occasion === 'ALL' ? undefined : occasion,\n featured: featuredOnly ? true : undefined,\n pagination: { limit: PAGE_SIZE, offset },\n });\n\n const looks = query.data?.items ?? [];\n const hasMore = query.data?.pageInfo.hasMore ?? false;\n\n return (\n <PageLayout\n title=\"Looks\"\n description=\"Shop-the-look outfits built from real catalogue pieces\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/looks/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 look\n </button>\n }\n >\n <div className=\"mb-6 flex flex-wrap items-center gap-2\">\n {OCCASIONS.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n onClick={() => {\n setOccasion(opt.value);\n setOffset(0);\n }}\n className={cn(\n 'rounded-full px-3 py-1.5 text-sm font-medium transition-colors',\n occasion === 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 looks…\" />\n ) : query.isError ? (\n <ErrorView onRetry={() => void query.refetch()} />\n ) : looks.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Sparkles className=\"h-10 w-10\" />}\n title=\"No looks yet\"\n description=\"Publish a shop-the-look outfit from catalogue pieces.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/looks/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 look\n </button>\n }\n />\n ) : (\n <>\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4\">\n {looks.map((look) => (\n <button\n key={look.id}\n type=\"button\"\n onClick={() => navigateTo(`/looks/${look.id}`)}\n className=\"overflow-hidden rounded-lg 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={<Sparkles className=\"h-9 w-9\" />}\n seed={look.id}\n className=\"h-40 w-full\"\n />\n {look.isFeatured && (\n <div className=\"absolute left-2 top-2\">\n <span className=\"inline-flex items-center gap-1 rounded-full bg-status-warning-bg-subtle px-2 py-0.5 text-xs font-medium text-status-warning-text\">\n <Star className=\"h-3 w-3 fill-status-warning-text\" /> Featured\n </span>\n </div>\n )}\n {look.publishedAt === null && (\n <div className=\"absolute right-2 top-2\">\n <StatusBadge status=\"draft\" />\n </div>\n )}\n </div>\n <div className=\"p-3\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{look.title}</p>\n <div className=\"mt-1.5 flex items-center justify-between text-xs text-text-secondary\">\n <span>{titleCase(look.occasion)}</span>\n <span className=\"flex items-center gap-2\">\n <span className=\"flex items-center gap-1\">\n <Heart className=\"h-3 w-3\" /> {look.likeCount}\n </span>\n <span className=\"flex items-center gap-1\">\n <Bookmark className=\"h-3 w-3\" /> {look.saveCount}\n </span>\n </span>\n </div>\n </div>\n </button>\n ))}\n </div>\n\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":";;;;;;;;;;;;;;AAqBA,IAAM,IAAY,IAEZ,IAAsE;CAC1E;EAAE,OAAO;EAAO,OAAO;EAAO;CAC9B;EAAE,OAAO;EAAY,OAAO;EAAY;CACxC;EAAE,OAAO;EAAQ,OAAO;EAAQ;CAChC;EAAE,OAAO;EAAW,OAAO;EAAW;CACtC;EAAE,OAAO;EAAiB,OAAO;EAAiB;CAClD;EAAE,OAAO;EAAY,OAAO;EAAY;CACxC;EAAE,OAAO;EAAS,OAAO;EAAS;CAClC;EAAE,OAAO;EAAU,OAAO;EAAU;CACpC;EAAE,OAAO;EAAS,OAAO;EAAS;CACnC;AAED,SAAgB,IAAgB;CAC9B,IAAM,EAAE,kBAAe,GAAkB,EACnC,CAAC,GAAU,KAAe,EAAkC,MAAM,EAClE,CAAC,GAAc,KAAmB,EAAS,GAAM,EACjD,CAAC,GAAQ,KAAa,EAAS,EAAE,EAEjC,IAAQ,EAAS;EACrB,UAAU,MAAa,QAAQ,KAAA,IAAY;EAC3C,UAAU,IAAe,KAAO,KAAA;EAChC,YAAY;GAAE,OAAO;GAAW;GAAQ;EACzC,CAAC,EAEI,IAAQ,EAAM,MAAM,SAAS,EAAE,EAC/B,IAAU,EAAM,MAAM,SAAS,WAAW;AAEhD,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,UAAD;GACE,MAAK;GACL,eAAe,EAAW,aAAa;GACvC,WAAU;aAHZ,CAKE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,YACrB;;YAVb,CAaE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACG,EAAU,KAAK,MACd,kBAAC,UAAD;IAEE,MAAK;IACL,eAAe;AAEb,KADA,EAAY,EAAI,MAAM,EACtB,EAAU,EAAE;;IAEd,WAAW,EACT,kEACA,MAAa,EAAI,QACb,kDACA,2DACL;cAEA,EAAI;IACE,EAdF,EAAI,MAcF,CACT,EACF,kBAAC,UAAD;IACE,MAAK;IACL,eAAe;AAEb,KADA,GAAiB,MAAM,CAAC,EAAE,EAC1B,EAAU,EAAE;;IAEd,WAAW,EACT,2GACA,IACI,yDACA,2DACL;cAXH;KAaE,kBAAC,GAAD,EAAM,WAAW,EAAG,eAAe,KAAgB,2BAA2B,EAAI,CAAA;KAAC;KAAI;KAEhF;MACL;MAEL,EAAM,YACL,kBAAC,GAAD,EAAa,OAAM,kBAAmB,CAAA,GACpC,EAAM,UACR,kBAAC,GAAD,EAAW,eAAe,KAAK,EAAM,SAAS,EAAI,CAAA,GAChD,EAAM,WAAW,IACnB,kBAAC,GAAD;GACE,cAAa;GACb,MAAM,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA;GACxC,OAAM;GACN,aAAY;GACZ,QACE,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,EAAW,aAAa;IACvC,WAAU;cAHZ,CAKE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,YACrB;;GAEX,CAAA,GAEF,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAM,KAAK,MACV,kBAAC,UAAD;IAEE,MAAK;IACL,eAAe,EAAW,UAAU,EAAK,KAAK;IAC9C,WAAU;cAJZ,CAME,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,GAAD;OACE,MAAM,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA;OACtC,MAAM,EAAK;OACX,WAAU;OACV,CAAA;MACD,EAAK,cACJ,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,QAAD;QAAM,WAAU;kBAAhB,CACE,kBAAC,GAAD,EAAM,WAAU,oCAAqC,CAAA,EAAA,YAChD;;OACH,CAAA;MAEP,EAAK,gBAAgB,QACpB,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD,EAAa,QAAO,SAAU,CAAA;OAC1B,CAAA;MAEJ;QACN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,KAAD;MAAG,WAAU;gBAAkD,EAAK;MAAU,CAAA,EAC9E,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,QAAD,EAAA,UAAO,EAAU,EAAK,SAAS,EAAQ,CAAA,EACvC,kBAAC,QAAD;OAAM,WAAU;iBAAhB,CACE,kBAAC,QAAD;QAAM,WAAU;kBAAhB;SACE,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;;SAAE,EAAK;SAC/B;WACP,kBAAC,QAAD;QAAM,WAAU;kBAAhB;SACE,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA;;SAAE,EAAK;SAClC;UACF;SACH;QACF;OACC;MAtCF,EAAK,GAsCH,CACT;GACE,CAAA,GAEJ,IAAS,KAAK,MACd,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,UAAD;KACE,MAAK;KACL,UAAU,MAAW;KACrB,eAAe,GAAW,MAAM,KAAK,IAAI,GAAG,IAAI,EAAU,CAAC;KAC3D,WAAU;eAJZ,CAME,kBAAC,GAAD,EAAa,WAAU,WAAY,CAAA,EAAA,YAC5B;;IACT,kBAAC,QAAD;KAAM,WAAU;eAAhB,CAA8C,SAAM,IAAS,IAAY,EAAS;;IAClF,kBAAC,UAAD;KACE,MAAK;KACL,UAAU,CAAC;KACX,eAAe,GAAW,MAAM,IAAI,EAAU;KAC9C,WAAU;eAJZ,CAKC,SACM,kBAAC,GAAD,EAAc,WAAU,WAAY,CAAA,CAClC;;IACL;KAEP,EAAA,CAAA,CAEM"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WardrobeFormPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/wardrobe/WardrobeFormPage.tsx"],"sourcesContent":["/**\n * Wardrobe Item Create Page (self-scoped)\n * @module coolandlovely/pages/wardrobe\n *\n * Drives `cooCreateWardrobeItem`. Belongs to the calling shopper's profile.\n */\n\nimport { useState } from 'react';\nimport { ArrowLeft, Loader2, Save, Heart } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { TextField, TextAreaField, SelectField } from '../../components/Field';\nimport { useCoolAndLovely } from '../../context/CoolAndLovelyContext';\nimport { useCreateWardrobeItem } from '../../hooks';\nimport { STYLE_CATEGORIES } from '../../utils/icons';\nimport { parseCsv, titleCase } from '../../utils/formatters';\nimport type { CooStyleCategory, CooWardrobeSource } from '../../types';\n\nconst SOURCES: CooWardrobeSource[] = ['OWNED', 'WISHLIST', 'PURCHASED_ON_PLATFORM', 'GIFTED'];\n\ninterface FormState {\n name: string;\n category: CooStyleCategory;\n source: CooWardrobeSource;\n brandName: string;\n colour: string;\n size: string;\n notes: string;\n tags: string;\n}\n\nconst EMPTY: FormState = {\n name: '',\n category: 'OTHER',\n source: 'OWNED',\n brandName: '',\n colour: '',\n size: '',\n notes: '',\n tags: '',\n};\n\nexport function WardrobeFormPage() {\n const { navigateTo } = useCoolAndLovely();\n const createItem = useCreateWardrobeItem();\n\n const [form, setForm] = useState<FormState>(EMPTY);\n const [nameError, setNameError] = useState<string | undefined>();\n\n const setField = <K extends keyof FormState>(key: K, value: FormState[K]) =>\n setForm((f) => ({ ...f, [key]: value }));\n\n const categoryOptions = STYLE_CATEGORIES.map((c) => ({ value: c, label: titleCase(c) }));\n const sourceOptions = SOURCES.map((s) => ({ value: s, label: titleCase(s) }));\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n if (!form.name.trim()) {\n setNameError('Name is required');\n return;\n }\n setNameError(undefined);\n\n createItem.mutate(\n {\n name: form.name.trim(),\n category: form.category,\n source: form.source,\n brandName: form.brandName.trim() || undefined,\n colour: form.colour.trim() || undefined,\n size: form.size.trim() || undefined,\n notes: form.notes.trim() || undefined,\n tags: parseCsv(form.tags),\n },\n { onSuccess: () => navigateTo('/wardrobe') }\n );\n };\n\n return (\n <PageLayout\n title=\"Add a wardrobe piece\"\n description=\"Catalogue something you own or want\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/wardrobe')}\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\" /> Cancel\n </button>\n }\n >\n <form onSubmit={handleSubmit} className=\"mx-auto max-w-2xl\">\n <GlassCard treatment=\"plain\" className=\"p-6\">\n <div className=\"mb-6 flex items-center gap-3\">\n <div className=\"flex h-11 w-11 items-center justify-center rounded-lg bg-status-error-bg-subtle text-status-error-text\">\n <Heart className=\"h-5 w-5\" />\n </div>\n <div>\n <h2 className=\"text-base font-semibold text-text-primary\">Piece details</h2>\n <p className=\"text-xs text-text-secondary\">Only you can see your wardrobe.</p>\n </div>\n </div>\n\n <TextField\n id=\"name\"\n label=\"Name\"\n value={form.name}\n onChange={(v) => setField('name', v)}\n placeholder=\"Vintage denim jacket\"\n required\n error={nameError}\n />\n\n <div className=\"mt-4 grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <SelectField\n id=\"category\"\n label=\"Category\"\n value={form.category}\n onChange={(v) => setField('category', v as CooStyleCategory)}\n options={categoryOptions}\n />\n <SelectField\n id=\"source\"\n label=\"Source\"\n value={form.source}\n onChange={(v) => setField('source', v as CooWardrobeSource)}\n options={sourceOptions}\n />\n </div>\n\n <div className=\"mt-4 grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <TextField\n id=\"brandName\"\n label=\"Brand\"\n value={form.brandName}\n onChange={(v) => setField('brandName', v)}\n placeholder=\"Levi's\"\n />\n <TextField\n id=\"colour\"\n label=\"Colour\"\n value={form.colour}\n onChange={(v) => setField('colour', v)}\n placeholder=\"Indigo\"\n />\n <TextField\n id=\"size\"\n label=\"Size\"\n value={form.size}\n onChange={(v) => setField('size', v)}\n placeholder=\"M\"\n />\n </div>\n\n <TextAreaField\n id=\"notes\"\n label=\"Notes\"\n value={form.notes}\n onChange={(v) => setField('notes', v)}\n placeholder=\"Where you got it, how you wear it…\"\n rows={3}\n className=\"mt-4\"\n />\n\n <TextField\n id=\"tags\"\n label=\"Tags\"\n value={form.tags}\n onChange={(v) => setField('tags', v)}\n placeholder=\"denim, layering\"\n hint=\"Comma-separated\"\n className=\"mt-4\"\n />\n\n {createItem.isError && (\n <p className=\"mt-4 rounded-lg bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text\">\n {createItem.error instanceof Error
|
|
1
|
+
{"version":3,"file":"WardrobeFormPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/wardrobe/WardrobeFormPage.tsx"],"sourcesContent":["/**\n * Wardrobe Item Create Page (self-scoped)\n * @module coolandlovely/pages/wardrobe\n *\n * Drives `cooCreateWardrobeItem`. Belongs to the calling shopper's profile.\n */\n\nimport { useState } from 'react';\nimport { ArrowLeft, Loader2, Save, Heart } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { TextField, TextAreaField, SelectField } from '../../components/Field';\nimport { useCoolAndLovely } from '../../context/CoolAndLovelyContext';\nimport { useCreateWardrobeItem } from '../../hooks';\nimport { STYLE_CATEGORIES } from '../../utils/icons';\nimport { parseCsv, titleCase } from '../../utils/formatters';\nimport type { CooStyleCategory, CooWardrobeSource } from '../../types';\n\nconst SOURCES: CooWardrobeSource[] = ['OWNED', 'WISHLIST', 'PURCHASED_ON_PLATFORM', 'GIFTED'];\n\ninterface FormState {\n name: string;\n category: CooStyleCategory;\n source: CooWardrobeSource;\n brandName: string;\n colour: string;\n size: string;\n notes: string;\n tags: string;\n}\n\nconst EMPTY: FormState = {\n name: '',\n category: 'OTHER',\n source: 'OWNED',\n brandName: '',\n colour: '',\n size: '',\n notes: '',\n tags: '',\n};\n\nexport function WardrobeFormPage() {\n const { navigateTo } = useCoolAndLovely();\n const createItem = useCreateWardrobeItem();\n\n const [form, setForm] = useState<FormState>(EMPTY);\n const [nameError, setNameError] = useState<string | undefined>();\n\n const setField = <K extends keyof FormState>(key: K, value: FormState[K]) =>\n setForm((f) => ({ ...f, [key]: value }));\n\n const categoryOptions = STYLE_CATEGORIES.map((c) => ({ value: c, label: titleCase(c) }));\n const sourceOptions = SOURCES.map((s) => ({ value: s, label: titleCase(s) }));\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n if (!form.name.trim()) {\n setNameError('Name is required');\n return;\n }\n setNameError(undefined);\n\n createItem.mutate(\n {\n name: form.name.trim(),\n category: form.category,\n source: form.source,\n brandName: form.brandName.trim() || undefined,\n colour: form.colour.trim() || undefined,\n size: form.size.trim() || undefined,\n notes: form.notes.trim() || undefined,\n tags: parseCsv(form.tags),\n },\n { onSuccess: () => navigateTo('/wardrobe') }\n );\n };\n\n return (\n <PageLayout\n title=\"Add a wardrobe piece\"\n description=\"Catalogue something you own or want\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/wardrobe')}\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\" /> Cancel\n </button>\n }\n >\n <form onSubmit={handleSubmit} className=\"mx-auto max-w-2xl\">\n <GlassCard treatment=\"plain\" className=\"p-6\">\n <div className=\"mb-6 flex items-center gap-3\">\n <div className=\"flex h-11 w-11 items-center justify-center rounded-lg bg-status-error-bg-subtle text-status-error-text\">\n <Heart className=\"h-5 w-5\" />\n </div>\n <div>\n <h2 className=\"text-base font-semibold text-text-primary\">Piece details</h2>\n <p className=\"text-xs text-text-secondary\">Only you can see your wardrobe.</p>\n </div>\n </div>\n\n <TextField\n id=\"name\"\n label=\"Name\"\n value={form.name}\n onChange={(v) => setField('name', v)}\n placeholder=\"Vintage denim jacket\"\n required\n error={nameError}\n />\n\n <div className=\"mt-4 grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <SelectField\n id=\"category\"\n label=\"Category\"\n value={form.category}\n onChange={(v) => setField('category', v as CooStyleCategory)}\n options={categoryOptions}\n />\n <SelectField\n id=\"source\"\n label=\"Source\"\n value={form.source}\n onChange={(v) => setField('source', v as CooWardrobeSource)}\n options={sourceOptions}\n />\n </div>\n\n <div className=\"mt-4 grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <TextField\n id=\"brandName\"\n label=\"Brand\"\n value={form.brandName}\n onChange={(v) => setField('brandName', v)}\n placeholder=\"Levi's\"\n />\n <TextField\n id=\"colour\"\n label=\"Colour\"\n value={form.colour}\n onChange={(v) => setField('colour', v)}\n placeholder=\"Indigo\"\n />\n <TextField\n id=\"size\"\n label=\"Size\"\n value={form.size}\n onChange={(v) => setField('size', v)}\n placeholder=\"M\"\n />\n </div>\n\n <TextAreaField\n id=\"notes\"\n label=\"Notes\"\n value={form.notes}\n onChange={(v) => setField('notes', v)}\n placeholder=\"Where you got it, how you wear it…\"\n rows={3}\n className=\"mt-4\"\n />\n\n <TextField\n id=\"tags\"\n label=\"Tags\"\n value={form.tags}\n onChange={(v) => setField('tags', v)}\n placeholder=\"denim, layering\"\n hint=\"Comma-separated\"\n className=\"mt-4\"\n />\n\n {createItem.isError && (\n <p className=\"mt-4 rounded-lg bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text\">\n {createItem.error instanceof Error\n ? createItem.error.message\n : 'Something went wrong'}\n </p>\n )}\n\n <div className=\"mt-6 flex justify-end gap-2\">\n <button\n type=\"submit\"\n disabled={createItem.isPending}\n className=\"inline-flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-5 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {createItem.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"h-4 w-4\" />\n )}\n Add to wardrobe\n </button>\n </div>\n </GlassCard>\n </form>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WardrobeListPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/wardrobe/WardrobeListPage.tsx"],"sourcesContent":["/**\n * Wardrobe List Page (self-scoped)\n * @module coolandlovely/pages/wardrobe\n *\n * The shopper's digital wardrobe (`cooListWardrobeItems`, self-scoped) with\n * category & source filters, wear logging (`cooLogWardrobeWear`) and removal\n * (`cooRemoveWardrobeItem`).\n */\n\nimport { useState } from 'react';\nimport { Plus, Heart, CheckCircle2, Trash2, Loader2 } 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 { useWardrobeItems, useLogWardrobeWear, useRemoveWardrobeItem } from '../../hooks';\nimport { categoryIcon, STYLE_CATEGORIES } from '../../utils/icons';\nimport { titleCase, formatRelativeTime } from '../../utils/formatters';\nimport { cn } from '../../utils/cn';\nimport type { CooStyleCategory, CooWardrobeSource } from '../../types';\n\nconst SOURCES: Array<{ value: CooWardrobeSource | 'ALL'; label: string }> = [\n { value: 'ALL', label: 'All' },\n { value: 'OWNED', label: 'Owned' },\n { value: 'WISHLIST', label: 'Wishlist' },\n { value: 'PURCHASED_ON_PLATFORM', label: 'Purchased' },\n { value: 'GIFTED', label: 'Gifted' },\n];\n\nexport function WardrobeListPage() {\n const { navigateTo } = useCoolAndLovely();\n const [category, setCategory] = useState<CooStyleCategory | 'ALL'>('ALL');\n const [source, setSource] = useState<CooWardrobeSource | 'ALL'>('ALL');\n\n const query = useWardrobeItems({\n category: category === 'ALL' ? undefined : category,\n source: source === 'ALL' ? undefined : source,\n });\n const logWear = useLogWardrobeWear();\n const remove = useRemoveWardrobeItem();\n\n const items = query.data ?? [];\n\n return (\n <PageLayout\n title=\"My Wardrobe\"\n description=\"A private catalogue of what you own — with a wear log\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/wardrobe/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\" /> Add piece\n </button>\n }\n >\n {/* Source filter */}\n <div className=\"mb-3 flex flex-wrap items-center gap-2\">\n {SOURCES.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n onClick={() => setSource(opt.value)}\n className={cn(\n 'rounded-full px-3 py-1.5 text-sm font-medium transition-colors',\n source === 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 {/* Category filter */}\n <div className=\"mb-6 flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => setCategory('ALL')}\n className={cn(\n 'rounded-full px-3 py-1.5 text-xs font-medium transition-colors',\n category === 'ALL'\n ? 'bg-accent-purple-subtle text-text-primary'\n : 'bg-bg-sunken text-text-secondary hover:text-text-primary'\n )}\n >\n All categories\n </button>\n {STYLE_CATEGORIES.map((c) => (\n <button\n key={c}\n type=\"button\"\n onClick={() => setCategory(c)}\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full px-3 py-1.5 text-xs font-medium transition-colors',\n category === c\n ? 'bg-accent-purple-subtle text-text-primary'\n : 'bg-bg-sunken text-text-secondary hover:text-text-primary'\n )}\n >\n {categoryIcon(c, 14)} {titleCase(c)}\n </button>\n ))}\n </div>\n\n {query.isLoading ? (\n <LoadingView label=\"Loading your wardrobe…\" />\n ) : query.isError ? (\n <ErrorView onRetry={() => void query.refetch()} />\n ) : items.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Heart className=\"h-10 w-10\" />}\n title=\"Your wardrobe is empty\"\n description=\"Add the pieces you already own (or want) to start your digital closet.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/wardrobe/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\" /> Add piece\n </button>\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {items.map((item) => (\n <div\n key={item.id}\n className=\"flex flex-col overflow-hidden rounded-lg border border-border-seam bg-bg-surface shadow-sm\"\n >\n <div className=\"flex items-start gap-3 p-4\">\n <Thumbnail icon={categoryIcon(item.category, 22)} seed={item.id} className=\"h-14 w-14 shrink-0\" />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-semibold text-text-primary\">{item.name}</p>\n {item.brandName && (\n <p className=\"truncate text-xs text-text-secondary\">{item.brandName}</p>\n )}\n <div className=\"mt-1.5 flex flex-wrap items-center gap-1.5\">\n <StatusBadge status={item.source} />\n {item.colour && (\n <span className=\"rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\">\n {item.colour}\n </span>\n )}\n {item.size && (\n <span className=\"rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\">\n {item.size}\n </span>\n )}\n </div>\n </div>\n </div>\n {item.notes && (\n <p className=\"px-4 pb-2 text-xs text-text-secondary line-clamp-2\">{item.notes}</p>\n )}\n <div className=\"mt-auto flex items-center justify-between border-t border-border-seam px-4 py-2.5\">\n <span className=\"text-xs text-text-secondary\">\n Worn {item.timesWorn}×\n {item.lastWornAt ? ` · ${formatRelativeTime(item.lastWornAt)}` : ''}\n </span>\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n disabled={logWear.isPending}\n onClick={() => logWear.mutate(item.id)}\n aria-label=\"Log a wear\"\n className=\"inline-flex items-center gap-1 rounded-lg px-2 py-1 text-xs font-medium text-status-success-text transition-colors hover:bg-status-success-bg-subtle disabled:opacity-50\"\n >\n {logWear.isPending && logWear.variables === item.id ? (\n <Loader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n <CheckCircle2 className=\"h-3.5 w-3.5\" />\n )}\n Wore it\n </button>\n <button\n type=\"button\"\n disabled={remove.isPending}\n onClick={() => remove.mutate(item.id)}\n aria-label=\"Remove piece\"\n className=\"inline-flex h-7 w-7 items-center justify-center rounded-lg text-text-secondary transition-colors hover:bg-status-error-bg-subtle hover:text-status-error-text disabled:opacity-50\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WardrobeListPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/wardrobe/WardrobeListPage.tsx"],"sourcesContent":["/**\n * Wardrobe List Page (self-scoped)\n * @module coolandlovely/pages/wardrobe\n *\n * The shopper's digital wardrobe (`cooListWardrobeItems`, self-scoped) with\n * category & source filters, wear logging (`cooLogWardrobeWear`) and removal\n * (`cooRemoveWardrobeItem`).\n */\n\nimport { useState } from 'react';\nimport { Plus, Heart, CheckCircle2, Trash2, Loader2 } 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 { useWardrobeItems, useLogWardrobeWear, useRemoveWardrobeItem } from '../../hooks';\nimport { categoryIcon, STYLE_CATEGORIES } from '../../utils/icons';\nimport { titleCase, formatRelativeTime } from '../../utils/formatters';\nimport { cn } from '../../utils/cn';\nimport type { CooStyleCategory, CooWardrobeSource } from '../../types';\n\nconst SOURCES: Array<{ value: CooWardrobeSource | 'ALL'; label: string }> = [\n { value: 'ALL', label: 'All' },\n { value: 'OWNED', label: 'Owned' },\n { value: 'WISHLIST', label: 'Wishlist' },\n { value: 'PURCHASED_ON_PLATFORM', label: 'Purchased' },\n { value: 'GIFTED', label: 'Gifted' },\n];\n\nexport function WardrobeListPage() {\n const { navigateTo } = useCoolAndLovely();\n const [category, setCategory] = useState<CooStyleCategory | 'ALL'>('ALL');\n const [source, setSource] = useState<CooWardrobeSource | 'ALL'>('ALL');\n\n const query = useWardrobeItems({\n category: category === 'ALL' ? undefined : category,\n source: source === 'ALL' ? undefined : source,\n });\n const logWear = useLogWardrobeWear();\n const remove = useRemoveWardrobeItem();\n\n const items = query.data ?? [];\n\n return (\n <PageLayout\n title=\"My Wardrobe\"\n description=\"A private catalogue of what you own — with a wear log\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/wardrobe/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\" /> Add piece\n </button>\n }\n >\n {/* Source filter */}\n <div className=\"mb-3 flex flex-wrap items-center gap-2\">\n {SOURCES.map((opt) => (\n <button\n key={opt.value}\n type=\"button\"\n onClick={() => setSource(opt.value)}\n className={cn(\n 'rounded-full px-3 py-1.5 text-sm font-medium transition-colors',\n source === 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 {/* Category filter */}\n <div className=\"mb-6 flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => setCategory('ALL')}\n className={cn(\n 'rounded-full px-3 py-1.5 text-xs font-medium transition-colors',\n category === 'ALL'\n ? 'bg-accent-purple-subtle text-text-primary'\n : 'bg-bg-sunken text-text-secondary hover:text-text-primary'\n )}\n >\n All categories\n </button>\n {STYLE_CATEGORIES.map((c) => (\n <button\n key={c}\n type=\"button\"\n onClick={() => setCategory(c)}\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full px-3 py-1.5 text-xs font-medium transition-colors',\n category === c\n ? 'bg-accent-purple-subtle text-text-primary'\n : 'bg-bg-sunken text-text-secondary hover:text-text-primary'\n )}\n >\n {categoryIcon(c, 14)} {titleCase(c)}\n </button>\n ))}\n </div>\n\n {query.isLoading ? (\n <LoadingView label=\"Loading your wardrobe…\" />\n ) : query.isError ? (\n <ErrorView onRetry={() => void query.refetch()} />\n ) : items.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Heart className=\"h-10 w-10\" />}\n title=\"Your wardrobe is empty\"\n description=\"Add the pieces you already own (or want) to start your digital closet.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/wardrobe/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\" /> Add piece\n </button>\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {items.map((item) => (\n <div\n key={item.id}\n className=\"flex flex-col overflow-hidden rounded-lg border border-border-seam bg-bg-surface shadow-sm\"\n >\n <div className=\"flex items-start gap-3 p-4\">\n <Thumbnail\n icon={categoryIcon(item.category, 22)}\n seed={item.id}\n className=\"h-14 w-14 shrink-0\"\n />\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-semibold text-text-primary\">{item.name}</p>\n {item.brandName && (\n <p className=\"truncate text-xs text-text-secondary\">{item.brandName}</p>\n )}\n <div className=\"mt-1.5 flex flex-wrap items-center gap-1.5\">\n <StatusBadge status={item.source} />\n {item.colour && (\n <span className=\"rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\">\n {item.colour}\n </span>\n )}\n {item.size && (\n <span className=\"rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\">\n {item.size}\n </span>\n )}\n </div>\n </div>\n </div>\n {item.notes && (\n <p className=\"px-4 pb-2 text-xs text-text-secondary line-clamp-2\">{item.notes}</p>\n )}\n <div className=\"mt-auto flex items-center justify-between border-t border-border-seam px-4 py-2.5\">\n <span className=\"text-xs text-text-secondary\">\n Worn {item.timesWorn}×\n {item.lastWornAt ? ` · ${formatRelativeTime(item.lastWornAt)}` : ''}\n </span>\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n disabled={logWear.isPending}\n onClick={() => logWear.mutate(item.id)}\n aria-label=\"Log a wear\"\n className=\"inline-flex items-center gap-1 rounded-lg px-2 py-1 text-xs font-medium text-status-success-text transition-colors hover:bg-status-success-bg-subtle disabled:opacity-50\"\n >\n {logWear.isPending && logWear.variables === item.id ? (\n <Loader2 className=\"h-3.5 w-3.5 animate-spin\" />\n ) : (\n <CheckCircle2 className=\"h-3.5 w-3.5\" />\n )}\n Wore it\n </button>\n <button\n type=\"button\"\n disabled={remove.isPending}\n onClick={() => remove.mutate(item.id)}\n aria-label=\"Remove piece\"\n className=\"inline-flex h-7 w-7 items-center justify-center rounded-lg text-text-secondary transition-colors hover:bg-status-error-bg-subtle hover:text-status-error-text disabled:opacity-50\"\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n </div>\n </div>\n ))}\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|