@burdenoff/microfe-coolandlovely 2026.827.1 → 2026.1024.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/ActivityTrail.js +7 -7
- package/dist/coolandlovely/components/Comments.js +4 -4
- package/dist/coolandlovely/components/FeedbackWidget.d.ts.map +1 -1
- package/dist/coolandlovely/components/FeedbackWidget.js +72 -70
- package/dist/coolandlovely/components/FeedbackWidget.js.map +1 -1
- package/dist/coolandlovely/components/LookCard.js +24 -24
- package/dist/coolandlovely/components/StateViews.d.ts.map +1 -1
- package/dist/coolandlovely/components/StateViews.js +35 -26
- package/dist/coolandlovely/components/StateViews.js.map +1 -1
- package/dist/coolandlovely/components/StatusBadge.d.ts.map +1 -1
- package/dist/coolandlovely/components/StatusBadge.js +45 -15
- package/dist/coolandlovely/components/StatusBadge.js.map +1 -1
- package/dist/coolandlovely/components/VisibilityChip.d.ts.map +1 -1
- package/dist/coolandlovely/components/VisibilityChip.js +22 -17
- package/dist/coolandlovely/components/VisibilityChip.js.map +1 -1
- package/dist/coolandlovely/hooks/index.d.ts +1 -0
- package/dist/coolandlovely/hooks/index.d.ts.map +1 -1
- package/dist/coolandlovely/hooks/index.js +2 -1
- package/dist/coolandlovely/hooks/useTr.d.ts +2 -0
- package/dist/coolandlovely/hooks/useTr.d.ts.map +1 -0
- package/dist/coolandlovely/hooks/useTr.js +14 -0
- package/dist/coolandlovely/hooks/useTr.js.map +1 -0
- package/dist/coolandlovely/pages/HomePage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/HomePage.js +172 -132
- package/dist/coolandlovely/pages/HomePage.js.map +1 -1
- package/dist/coolandlovely/pages/admin/AdminBrandsPage.js +10 -10
- package/dist/coolandlovely/pages/admin/AdminCollaborationsPage.js +16 -16
- package/dist/coolandlovely/pages/admin/AdminFeaturedItemsPage.js +17 -17
- package/dist/coolandlovely/pages/brands/BrandDetailPage.js +22 -22
- package/dist/coolandlovely/pages/brands/BrandFormPage.js +9 -9
- package/dist/coolandlovely/pages/brands/BrandsListPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/brands/BrandsListPage.js +80 -76
- package/dist/coolandlovely/pages/brands/BrandsListPage.js.map +1 -1
- package/dist/coolandlovely/pages/collaborations/CollaborationDetailPage.js +21 -21
- package/dist/coolandlovely/pages/collaborations/CollaborationFormPage.js +7 -7
- package/dist/coolandlovely/pages/collaborations/CollaborationsListPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/collaborations/CollaborationsListPage.js +82 -81
- package/dist/coolandlovely/pages/collaborations/CollaborationsListPage.js.map +1 -1
- package/dist/coolandlovely/pages/collections/CollectionDetailPage.js +19 -19
- package/dist/coolandlovely/pages/collections/CollectionFormPage.js +9 -9
- package/dist/coolandlovely/pages/collections/CollectionsListPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/collections/CollectionsListPage.js +54 -55
- package/dist/coolandlovely/pages/collections/CollectionsListPage.js.map +1 -1
- package/dist/coolandlovely/pages/discover/DiscoverPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/discover/DiscoverPage.js +322 -315
- package/dist/coolandlovely/pages/discover/DiscoverPage.js.map +1 -1
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.js +21 -21
- package/dist/coolandlovely/pages/items/StyleItemFormPage.js +10 -10
- package/dist/coolandlovely/pages/items/StyleItemsListPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/items/StyleItemsListPage.js +105 -95
- package/dist/coolandlovely/pages/items/StyleItemsListPage.js.map +1 -1
- package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.js +20 -20
- package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.js.map +1 -1
- package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.js +88 -79
- package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.js.map +1 -1
- package/dist/coolandlovely/pages/looks/LookDetailPage.js +18 -18
- package/dist/coolandlovely/pages/looks/LookFormPage.js +6 -6
- package/dist/coolandlovely/pages/looks/LookFormPage.js.map +1 -1
- package/dist/coolandlovely/pages/looks/LooksListPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/looks/LooksListPage.js +94 -94
- package/dist/coolandlovely/pages/looks/LooksListPage.js.map +1 -1
- package/dist/coolandlovely/pages/profile/StyleProfilePage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/profile/StyleProfilePage.js +226 -199
- package/dist/coolandlovely/pages/profile/StyleProfilePage.js.map +1 -1
- package/dist/coolandlovely/pages/trends/TrendsPage.js +8 -8
- package/dist/coolandlovely/pages/wardrobe/WardrobeFormPage.js +5 -5
- package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.js +71 -69
- package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,109 +1,97 @@
|
|
|
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 {
|
|
5
|
-
import {
|
|
6
|
-
import { useLooks as o } from "../../hooks/useCoolAndLovelyApi.js";
|
|
7
|
-
import { LookCard as s } from "../../components/LookCard.js";
|
|
4
|
+
import { useLooks as r } from "../../hooks/useCoolAndLovelyApi.js";
|
|
5
|
+
import { useTr as i } from "../../hooks/useTr.js";
|
|
8
6
|
import "../../hooks/index.js";
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
7
|
+
import { StatusBadge as a } from "../../components/StatusBadge.js";
|
|
8
|
+
import { ErrorView as o, LoadingView as s } from "../../components/StateViews.js";
|
|
9
|
+
import { titleCase as c } from "../../utils/formatters.js";
|
|
10
|
+
import { LookCard as l } from "../../components/LookCard.js";
|
|
11
|
+
import { EmptyState as u } from "../../components/EmptyState.js";
|
|
12
|
+
import { useMemo as d, useState as f } from "react";
|
|
13
|
+
import { ChevronLeft as p, ChevronRight as m, Plus as h, Sparkles as g, Star as _ } from "lucide-react";
|
|
14
|
+
import { Fragment as v, jsx as y, jsxs as b } from "react/jsx-runtime";
|
|
13
15
|
//#region src/coolandlovely/pages/looks/LooksListPage.tsx
|
|
14
|
-
var
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
{
|
|
24
|
-
value: "WORK",
|
|
25
|
-
label: "Work"
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
value: "EVENING",
|
|
29
|
-
label: "Evening"
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
value: "WEDDING_GUEST",
|
|
33
|
-
label: "Wedding guest"
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
value: "VACATION",
|
|
37
|
-
label: "Vacation"
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
value: "PARTY",
|
|
41
|
-
label: "Party"
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
value: "ACTIVE",
|
|
45
|
-
label: "Active"
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
value: "OTHER",
|
|
49
|
-
label: "Other"
|
|
50
|
-
}
|
|
16
|
+
var x = 24, S = [
|
|
17
|
+
"EVERYDAY",
|
|
18
|
+
"WORK",
|
|
19
|
+
"EVENING",
|
|
20
|
+
"WEDDING_GUEST",
|
|
21
|
+
"VACATION",
|
|
22
|
+
"PARTY",
|
|
23
|
+
"ACTIVE",
|
|
24
|
+
"OTHER"
|
|
51
25
|
];
|
|
52
|
-
function
|
|
53
|
-
let { navigateTo:
|
|
54
|
-
|
|
55
|
-
|
|
26
|
+
function C() {
|
|
27
|
+
let { navigateTo: C } = e(), w = i(), [T, E] = f("ALL"), [D, O] = f(!1), [k, A] = f(0), j = d(() => [{
|
|
28
|
+
value: "ALL",
|
|
29
|
+
label: w("coolandlovely.filters.all", "All")
|
|
30
|
+
}, ...S.map((e) => ({
|
|
31
|
+
value: e,
|
|
32
|
+
label: w(`coolandlovely.occasion.${e.toLowerCase()}`, c(e))
|
|
33
|
+
}))], [w]), M = r({
|
|
34
|
+
occasion: T === "ALL" ? void 0 : T,
|
|
35
|
+
featured: D ? !0 : void 0,
|
|
56
36
|
pagination: {
|
|
57
|
-
limit:
|
|
58
|
-
offset:
|
|
37
|
+
limit: x,
|
|
38
|
+
offset: k
|
|
59
39
|
}
|
|
60
|
-
}),
|
|
61
|
-
return /* @__PURE__ */
|
|
62
|
-
title: "Looks",
|
|
63
|
-
description: "Shop-the-look outfits built from real catalogue pieces",
|
|
64
|
-
actions: /* @__PURE__ */
|
|
40
|
+
}), N = M.data?.items ?? [], P = M.data?.pageInfo.hasMore ?? !1;
|
|
41
|
+
return /* @__PURE__ */ b(n, {
|
|
42
|
+
title: w("coolandlovely.page.looksTitle", "Looks"),
|
|
43
|
+
description: w("coolandlovely.page.looksSubtitle", "Shop-the-look outfits built from real catalogue pieces"),
|
|
44
|
+
actions: /* @__PURE__ */ b("button", {
|
|
65
45
|
type: "button",
|
|
66
|
-
onClick: () =>
|
|
46
|
+
onClick: () => C("/looks/new"),
|
|
67
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",
|
|
68
|
-
children: [
|
|
48
|
+
children: [
|
|
49
|
+
/* @__PURE__ */ y(h, { className: "h-4 w-4" }),
|
|
50
|
+
" ",
|
|
51
|
+
w("coolandlovely.actions.newLook", "New look")
|
|
52
|
+
]
|
|
69
53
|
}),
|
|
70
|
-
children: [/* @__PURE__ */
|
|
54
|
+
children: [/* @__PURE__ */ b("div", {
|
|
71
55
|
className: "mb-6 flex flex-wrap items-center gap-2",
|
|
72
|
-
children: [
|
|
56
|
+
children: [j.map((e) => /* @__PURE__ */ y("button", {
|
|
73
57
|
type: "button",
|
|
74
58
|
onClick: () => {
|
|
75
|
-
|
|
59
|
+
E(e.value), A(0);
|
|
76
60
|
},
|
|
77
|
-
className: t("rounded-full px-3 py-1.5 text-sm font-medium transition-colors",
|
|
61
|
+
className: t("rounded-full px-3 py-1.5 text-sm font-medium transition-colors", T === e.value ? "bg-action-primary-bg text-action-primary-text" : "bg-bg-sunken text-text-secondary hover:text-text-primary"),
|
|
78
62
|
children: e.label
|
|
79
|
-
}, e.value)), /* @__PURE__ */
|
|
63
|
+
}, e.value)), /* @__PURE__ */ b("button", {
|
|
80
64
|
type: "button",
|
|
81
65
|
onClick: () => {
|
|
82
|
-
|
|
66
|
+
O((e) => !e), A(0);
|
|
83
67
|
},
|
|
84
|
-
className: t("ml-auto inline-flex items-center gap-1.5 rounded-full px-3 py-1.5 text-sm font-medium transition-colors",
|
|
68
|
+
className: t("ml-auto inline-flex items-center gap-1.5 rounded-full px-3 py-1.5 text-sm font-medium transition-colors", D ? "bg-status-warning-bg-subtle text-status-warning-text" : "bg-bg-sunken text-text-secondary hover:text-text-primary"),
|
|
85
69
|
children: [
|
|
86
|
-
/* @__PURE__ */
|
|
70
|
+
/* @__PURE__ */ y(_, { className: t("h-3.5 w-3.5", D && "fill-status-warning-text") }),
|
|
87
71
|
" ",
|
|
88
|
-
"Featured"
|
|
72
|
+
w("coolandlovely.filters.featured", "Featured")
|
|
89
73
|
]
|
|
90
74
|
})]
|
|
91
|
-
}),
|
|
75
|
+
}), M.isLoading ? /* @__PURE__ */ y(s, { label: w("coolandlovely.loading.looks", "Loading looks…") }) : M.isError ? /* @__PURE__ */ y(o, { onRetry: () => void M.refetch() }) : N.length === 0 ? /* @__PURE__ */ y(u, {
|
|
92
76
|
illustration: "empty-data",
|
|
93
|
-
icon: /* @__PURE__ */ g
|
|
94
|
-
title: "No looks yet",
|
|
95
|
-
description: "Publish a shop-the-look outfit from catalogue pieces.",
|
|
96
|
-
action: /* @__PURE__ */
|
|
77
|
+
icon: /* @__PURE__ */ y(g, { className: "h-10 w-10" }),
|
|
78
|
+
title: w("coolandlovely.empty.looksTitle", "No looks yet"),
|
|
79
|
+
description: w("coolandlovely.empty.looksDescription", "Publish a shop-the-look outfit from catalogue pieces."),
|
|
80
|
+
action: /* @__PURE__ */ b("button", {
|
|
97
81
|
type: "button",
|
|
98
|
-
onClick: () =>
|
|
82
|
+
onClick: () => C("/looks/new"),
|
|
99
83
|
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",
|
|
100
|
-
children: [
|
|
84
|
+
children: [
|
|
85
|
+
/* @__PURE__ */ y(h, { className: "h-4 w-4" }),
|
|
86
|
+
" ",
|
|
87
|
+
w("coolandlovely.actions.newLook", "New look")
|
|
88
|
+
]
|
|
101
89
|
})
|
|
102
|
-
}) : /* @__PURE__ */
|
|
90
|
+
}) : /* @__PURE__ */ b(v, { children: [/* @__PURE__ */ y("div", {
|
|
103
91
|
className: "grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-4",
|
|
104
|
-
children:
|
|
92
|
+
children: N.map((e) => /* @__PURE__ */ b("div", {
|
|
105
93
|
className: "relative",
|
|
106
|
-
children: [/* @__PURE__ */
|
|
94
|
+
children: [/* @__PURE__ */ y(l, {
|
|
107
95
|
id: e.id,
|
|
108
96
|
title: e.title,
|
|
109
97
|
occasion: e.occasion,
|
|
@@ -111,42 +99,54 @@ function b() {
|
|
|
111
99
|
likeCount: e.likeCount,
|
|
112
100
|
isLikedByMe: e.isLikedByMe,
|
|
113
101
|
isSavedByMe: e.isSavedByMe,
|
|
114
|
-
onOpen: () =>
|
|
102
|
+
onOpen: () => C(`/looks/${e.id}`),
|
|
115
103
|
showActions: !0
|
|
116
|
-
}), (e.isFeatured || e.publishedAt === null) && /* @__PURE__ */
|
|
104
|
+
}), (e.isFeatured || e.publishedAt === null) && /* @__PURE__ */ b("div", {
|
|
117
105
|
className: "pointer-events-none absolute left-2 top-2 z-10 flex flex-col items-start gap-1",
|
|
118
|
-
children: [e.isFeatured && /* @__PURE__ */
|
|
106
|
+
children: [e.isFeatured && /* @__PURE__ */ b("span", {
|
|
119
107
|
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 shadow-sm backdrop-blur",
|
|
120
|
-
children: [
|
|
121
|
-
|
|
108
|
+
children: [
|
|
109
|
+
/* @__PURE__ */ y(_, { className: "h-3 w-3 fill-status-warning-text" }),
|
|
110
|
+
" ",
|
|
111
|
+
w("coolandlovely.filters.featured", "Featured")
|
|
112
|
+
]
|
|
113
|
+
}), e.publishedAt === null && /* @__PURE__ */ y(a, { status: "draft" })]
|
|
122
114
|
})]
|
|
123
115
|
}, e.id))
|
|
124
|
-
}), (
|
|
116
|
+
}), (k > 0 || P) && /* @__PURE__ */ b("div", {
|
|
125
117
|
className: "mt-6 flex items-center justify-center gap-2",
|
|
126
118
|
children: [
|
|
127
|
-
/* @__PURE__ */
|
|
119
|
+
/* @__PURE__ */ b("button", {
|
|
128
120
|
type: "button",
|
|
129
|
-
disabled:
|
|
130
|
-
onClick: () =>
|
|
121
|
+
disabled: k === 0,
|
|
122
|
+
onClick: () => A((e) => Math.max(0, e - x)),
|
|
131
123
|
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",
|
|
132
|
-
children: [
|
|
124
|
+
children: [
|
|
125
|
+
/* @__PURE__ */ y(p, { className: "h-4 w-4" }),
|
|
126
|
+
" ",
|
|
127
|
+
w("coolandlovely.pagination.previous", "Previous")
|
|
128
|
+
]
|
|
133
129
|
}),
|
|
134
|
-
/* @__PURE__ */
|
|
130
|
+
/* @__PURE__ */ y("span", {
|
|
135
131
|
className: "text-sm text-text-secondary",
|
|
136
|
-
children:
|
|
132
|
+
children: w("coolandlovely.pagination.page", "Page {{page}}", { page: k / x + 1 })
|
|
137
133
|
}),
|
|
138
|
-
/* @__PURE__ */
|
|
134
|
+
/* @__PURE__ */ b("button", {
|
|
139
135
|
type: "button",
|
|
140
|
-
disabled: !
|
|
141
|
-
onClick: () =>
|
|
136
|
+
disabled: !P,
|
|
137
|
+
onClick: () => A((e) => e + x),
|
|
142
138
|
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",
|
|
143
|
-
children: [
|
|
139
|
+
children: [
|
|
140
|
+
w("coolandlovely.pagination.next", "Next"),
|
|
141
|
+
" ",
|
|
142
|
+
/* @__PURE__ */ y(m, { className: "h-4 w-4" })
|
|
143
|
+
]
|
|
144
144
|
})
|
|
145
145
|
]
|
|
146
146
|
})] })]
|
|
147
147
|
});
|
|
148
148
|
}
|
|
149
149
|
//#endregion
|
|
150
|
-
export {
|
|
150
|
+
export { C as LooksListPage };
|
|
151
151
|
|
|
152
152
|
//# sourceMappingURL=LooksListPage.js.map
|
|
@@ -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, 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 { LookCard } from '../../components/LookCard';\nimport { useCoolAndLovely } from '../../context/CoolAndLovelyContext';\nimport { useLooks } from '../../hooks';\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 <div key={look.id} className=\"relative\">\n <LookCard\n id={look.id}\n title={look.title}\n occasion={look.occasion}\n imageFileId={look.image?.id}\n likeCount={look.likeCount}\n isLikedByMe={look.isLikedByMe}\n isSavedByMe={look.isSavedByMe}\n onOpen={() => navigateTo(`/looks/${look.id}`)}\n showActions\n />\n {(look.isFeatured || look.publishedAt === null) && (\n <div className=\"pointer-events-none absolute left-2 top-2 z-10 flex flex-col items-start gap-1\">\n {look.isFeatured && (\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 shadow-sm backdrop-blur\">\n <Star className=\"h-3 w-3 fill-status-warning-text\" /> Featured\n </span>\n )}\n {look.publishedAt === null && <StatusBadge status=\"draft\" />}\n </div>\n )}\n </div>\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 { useMemo, useState } from 'react';\nimport { Plus, 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 { LookCard } from '../../components/LookCard';\nimport { useCoolAndLovely } from '../../context/CoolAndLovelyContext';\nimport { useLooks, useTr } from '../../hooks';\nimport { titleCase } from '../../utils/formatters';\nimport { cn } from '../../utils/cn';\nimport type { CooLookOccasion } from '../../types';\n\nconst PAGE_SIZE = 24;\nconst OCCASION_ORDER: CooLookOccasion[] = [\n 'EVERYDAY',\n 'WORK',\n 'EVENING',\n 'WEDDING_GUEST',\n 'VACATION',\n 'PARTY',\n 'ACTIVE',\n 'OTHER',\n];\n\nexport function LooksListPage() {\n const { navigateTo } = useCoolAndLovely();\n const tr = useTr();\n const [occasion, setOccasion] = useState<CooLookOccasion | 'ALL'>('ALL');\n const [featuredOnly, setFeaturedOnly] = useState(false);\n const [offset, setOffset] = useState(0);\n\n const occasionOptions = useMemo(\n () => [\n { value: 'ALL' as const, label: tr('coolandlovely.filters.all', 'All') },\n ...OCCASION_ORDER.map((value) => ({\n value,\n label: tr(`coolandlovely.occasion.${value.toLowerCase()}`, titleCase(value)),\n })),\n ],\n [tr]\n );\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={tr('coolandlovely.page.looksTitle', 'Looks')}\n description={tr(\n 'coolandlovely.page.looksSubtitle',\n 'Shop-the-look outfits built from real catalogue pieces'\n )}\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\" /> {tr('coolandlovely.actions.newLook', 'New look')}\n </button>\n }\n >\n <div className=\"mb-6 flex flex-wrap items-center gap-2\">\n {occasionOptions.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 {tr('coolandlovely.filters.featured', 'Featured')}\n </button>\n </div>\n\n {query.isLoading ? (\n <LoadingView label={tr('coolandlovely.loading.looks', '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={tr('coolandlovely.empty.looksTitle', 'No looks yet')}\n description={tr(\n 'coolandlovely.empty.looksDescription',\n 'Publish a shop-the-look outfit from catalogue pieces.'\n )}\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\" /> {tr('coolandlovely.actions.newLook', '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 <div key={look.id} className=\"relative\">\n <LookCard\n id={look.id}\n title={look.title}\n occasion={look.occasion}\n imageFileId={look.image?.id}\n likeCount={look.likeCount}\n isLikedByMe={look.isLikedByMe}\n isSavedByMe={look.isSavedByMe}\n onOpen={() => navigateTo(`/looks/${look.id}`)}\n showActions\n />\n {(look.isFeatured || look.publishedAt === null) && (\n <div className=\"pointer-events-none absolute left-2 top-2 z-10 flex flex-col items-start gap-1\">\n {look.isFeatured && (\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 shadow-sm backdrop-blur\">\n <Star className=\"h-3 w-3 fill-status-warning-text\" />{' '}\n {tr('coolandlovely.filters.featured', 'Featured')}\n </span>\n )}\n {look.publishedAt === null && <StatusBadge status=\"draft\" />}\n </div>\n )}\n </div>\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\" />{' '}\n {tr('coolandlovely.pagination.previous', 'Previous')}\n </button>\n <span className=\"text-sm text-text-secondary\">\n {tr('coolandlovely.pagination.page', 'Page {{page}}', {\n page: offset / PAGE_SIZE + 1,\n })}\n </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 {tr('coolandlovely.pagination.next', '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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StyleProfilePage.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/pages/profile/StyleProfilePage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"StyleProfilePage.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/pages/profile/StyleProfilePage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAgFH,wBAAgB,gBAAgB,gCA2jB/B"}
|