@burdenoff/microfe-coolandlovely 2026.820.5 → 2026.829.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.d.ts +24 -0
- package/dist/coolandlovely/components/ActivityTrail.d.ts.map +1 -0
- package/dist/coolandlovely/components/ActivityTrail.js +70 -0
- package/dist/coolandlovely/components/ActivityTrail.js.map +1 -0
- 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/components/index.d.ts +1 -0
- package/dist/coolandlovely/components/index.d.ts.map +1 -1
- package/dist/coolandlovely/components/index.js +1 -0
- package/dist/coolandlovely/hooks/index.d.ts +4 -0
- package/dist/coolandlovely/hooks/index.d.ts.map +1 -1
- package/dist/coolandlovely/hooks/index.js +4 -1
- package/dist/coolandlovely/hooks/useActivity.d.ts +39 -0
- package/dist/coolandlovely/hooks/useActivity.d.ts.map +1 -0
- package/dist/coolandlovely/hooks/useActivity.js +38 -0
- package/dist/coolandlovely/hooks/useActivity.js.map +1 -0
- package/dist/coolandlovely/hooks/useAssistantEntity.d.ts +24 -0
- package/dist/coolandlovely/hooks/useAssistantEntity.d.ts.map +1 -0
- package/dist/coolandlovely/hooks/useAssistantEntity.js +12 -0
- package/dist/coolandlovely/hooks/useAssistantEntity.js.map +1 -0
- 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.d.ts.map +1 -1
- package/dist/coolandlovely/pages/brands/BrandDetailPage.js +171 -151
- package/dist/coolandlovely/pages/brands/BrandDetailPage.js.map +1 -1
- 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.d.ts.map +1 -1
- package/dist/coolandlovely/pages/collaborations/CollaborationDetailPage.js +121 -120
- package/dist/coolandlovely/pages/collaborations/CollaborationDetailPage.js.map +1 -1
- 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.d.ts.map +1 -1
- package/dist/coolandlovely/pages/collections/CollectionDetailPage.js +111 -110
- package/dist/coolandlovely/pages/collections/CollectionDetailPage.js.map +1 -1
- 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 +452 -307
- package/dist/coolandlovely/pages/discover/DiscoverPage.js.map +1 -1
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.js +117 -116
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.js.map +1 -1
- 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.d.ts.map +1 -1
- package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.js +32 -29
- 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.d.ts.map +1 -1
- package/dist/coolandlovely/pages/looks/LookDetailPage.js +135 -134
- package/dist/coolandlovely/pages/looks/LookDetailPage.js.map +1 -1
- 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/dist/utils/pageContext.d.ts +23 -0
- package/dist/utils/pageContext.d.ts.map +1 -1
- package/dist/utils/pageContext.js +37 -25
- package/dist/utils/pageContext.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StateViews.js","names":[],"sources":["../../../src/coolandlovely/components/StateViews.tsx"],"sourcesContent":["/**\n * Loading / Error state views\n * @module coolandlovely/components\n *\n * Calm, on-token loading and error panels reused across the domain pages so\n * every screen has consistent loading/empty/error treatment.\n */\n\nimport type { FC } from 'react';\nimport { AlertCircle, Loader2, RotateCw } from 'lucide-react';\nimport { cn } from '../utils/cn';\n\ninterface LoadingViewProps {\n label?: string;\n className?: string;\n}\n\nexport const LoadingView: FC<LoadingViewProps> = ({ label = 'Loading…', className }) => (\n <div className={cn('flex min-h-[40vh] flex-col items-center justify-center gap-3', className)}>\n <Loader2 className=\"h-8 w-8 animate-spin text-primary\" />\n <p className=\"text-sm text-text-secondary\">{label}</p>\n </div>\n);\n\ninterface ErrorViewProps {\n title?: string;\n message?: string;\n onRetry?: () => void;\n className?: string;\n}\n\nexport const ErrorView: FC<ErrorViewProps> = ({
|
|
1
|
+
{"version":3,"file":"StateViews.js","names":[],"sources":["../../../src/coolandlovely/components/StateViews.tsx"],"sourcesContent":["/**\n * Loading / Error state views\n * @module coolandlovely/components\n *\n * Calm, on-token loading and error panels reused across the domain pages so\n * every screen has consistent loading/empty/error treatment.\n */\n\nimport type { FC } from 'react';\nimport { AlertCircle, Loader2, RotateCw } from 'lucide-react';\nimport { cn } from '../utils/cn';\nimport { useTr } from '../hooks';\n\ninterface LoadingViewProps {\n label?: string;\n className?: string;\n}\n\nexport const LoadingView: FC<LoadingViewProps> = ({ label = 'Loading…', className }) => (\n <div className={cn('flex min-h-[40vh] flex-col items-center justify-center gap-3', className)}>\n <Loader2 className=\"h-8 w-8 animate-spin text-primary\" />\n <p className=\"text-sm text-text-secondary\">{label}</p>\n </div>\n);\n\ninterface ErrorViewProps {\n title?: string;\n message?: string;\n onRetry?: () => void;\n className?: string;\n}\n\nexport const ErrorView: FC<ErrorViewProps> = ({ title, message, onRetry, className }) => {\n const tr = useTr();\n return (\n <div\n className={cn(\n 'flex min-h-[40vh] flex-col items-center justify-center gap-3 text-center',\n className\n )}\n >\n <AlertCircle className=\"h-10 w-10 text-status-error-text\" />\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {title ?? tr('coolandlovely.error.title', 'Something went wrong')}\n </h2>\n <p className=\"max-w-sm text-sm text-text-secondary\">\n {message ??\n tr('coolandlovely.error.message', 'We could not load this data. Please try again.')}\n </p>\n {onRetry && (\n <button\n type=\"button\"\n onClick={onRetry}\n className=\"mt-1 inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\"\n >\n <RotateCw className=\"h-4 w-4\" /> {tr('coolandlovely.error.retry', 'Retry')}\n </button>\n )}\n </div>\n );\n};\n"],"mappings":";;;;;;AAkBA,IAAa,KAAqC,EAAE,WAAQ,YAAY,mBACtE,kBAAC,OAAD;CAAK,WAAW,EAAG,gEAAgE,EAAU;WAA7F,CACE,kBAAC,GAAD,EAAS,WAAU,qCAAsC,CAAA,EACzD,kBAAC,KAAD;EAAG,WAAU;YAA+B;EAAU,CAAA,CAClD;IAUK,KAAiC,EAAE,UAAO,YAAS,YAAS,mBAAgB;CACvF,IAAM,IAAK,GAAO;AAClB,QACE,kBAAC,OAAD;EACE,WAAW,EACT,4EACA,EACD;YAJH;GAME,kBAAC,GAAD,EAAa,WAAU,oCAAqC,CAAA;GAC5D,kBAAC,MAAD;IAAI,WAAU;cACX,KAAS,EAAG,6BAA6B,uBAAuB;IAC9D,CAAA;GACL,kBAAC,KAAD;IAAG,WAAU;cACV,KACC,EAAG,+BAA+B,iDAAiD;IACnF,CAAA;GACH,KACC,kBAAC,UAAD;IACE,MAAK;IACL,SAAS;IACT,WAAU;cAHZ;KAKE,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA;;KAAE,EAAG,6BAA6B,QAAQ;KACnE;;GAEP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StatusBadge.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/components/StatusBadge.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"StatusBadge.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/components/StatusBadge.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAIhC,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsGD,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,gBAAgB,CA2B5C,CAAC"}
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
import { cn as e } from "../utils/cn.js";
|
|
2
|
-
import {
|
|
2
|
+
import { useTr as t } from "../hooks/useTr.js";
|
|
3
|
+
import "../hooks/index.js";
|
|
4
|
+
import { jsx as n, jsxs as r } from "react/jsx-runtime";
|
|
3
5
|
//#region src/coolandlovely/components/StatusBadge.tsx
|
|
4
|
-
var
|
|
6
|
+
var i = {
|
|
5
7
|
success: "bg-status-success-bg-subtle text-status-success-text",
|
|
6
8
|
warning: "bg-status-warning-bg-subtle text-status-warning-text",
|
|
7
9
|
destructive: "bg-status-error-bg-subtle text-status-error-text",
|
|
8
10
|
secondary: "bg-bg-sunken text-text-secondary",
|
|
9
11
|
info: "bg-accent-blue-subtle text-accent-blue",
|
|
10
12
|
outline: "border border-border-seam text-text-primary"
|
|
11
|
-
},
|
|
13
|
+
}, a = {
|
|
12
14
|
success: "bg-status-success-text",
|
|
13
15
|
warning: "bg-status-warning-text",
|
|
14
16
|
destructive: "bg-status-error-text",
|
|
15
17
|
secondary: "bg-text-secondary",
|
|
16
18
|
info: "bg-accent-blue",
|
|
17
19
|
outline: "bg-text-secondary"
|
|
18
|
-
},
|
|
20
|
+
}, o = {
|
|
19
21
|
draft: "secondary",
|
|
20
22
|
pending_review: "warning",
|
|
21
23
|
published: "success",
|
|
@@ -43,26 +45,54 @@ var r = {
|
|
|
43
45
|
error: "destructive",
|
|
44
46
|
failed: "destructive",
|
|
45
47
|
completed: "success"
|
|
46
|
-
},
|
|
48
|
+
}, s = new Set([
|
|
47
49
|
"live",
|
|
48
50
|
"published",
|
|
49
51
|
"active",
|
|
50
52
|
"in_progress"
|
|
51
|
-
])
|
|
52
|
-
|
|
53
|
+
]), c = {
|
|
54
|
+
draft: "coolandlovely.status.draft",
|
|
55
|
+
pending_review: "coolandlovely.status.pendingReview",
|
|
56
|
+
published: "coolandlovely.status.published",
|
|
57
|
+
suspended: "coolandlovely.status.suspended",
|
|
58
|
+
archived: "coolandlovely.status.archived",
|
|
59
|
+
scheduled: "coolandlovely.status.scheduled",
|
|
60
|
+
live: "coolandlovely.status.live",
|
|
61
|
+
ended: "coolandlovely.status.ended",
|
|
62
|
+
active: "coolandlovely.status.active",
|
|
63
|
+
out_of_stock: "coolandlovely.status.outOfStock",
|
|
64
|
+
retired: "coolandlovely.status.retired",
|
|
65
|
+
proposed: "coolandlovely.status.proposed",
|
|
66
|
+
accepted: "coolandlovely.status.accepted",
|
|
67
|
+
in_progress: "coolandlovely.status.inProgress",
|
|
68
|
+
declined: "coolandlovely.status.declined",
|
|
69
|
+
cancelled: "coolandlovely.status.cancelled",
|
|
70
|
+
public: "coolandlovely.status.public",
|
|
71
|
+
followers: "coolandlovely.status.followers",
|
|
72
|
+
private: "coolandlovely.status.private",
|
|
73
|
+
owned: "coolandlovely.status.owned",
|
|
74
|
+
wishlist: "coolandlovely.status.wishlist",
|
|
75
|
+
purchased_on_platform: "coolandlovely.status.purchasedOnPlatform",
|
|
76
|
+
gifted: "coolandlovely.status.gifted",
|
|
77
|
+
inactive: "coolandlovely.status.inactive",
|
|
78
|
+
error: "coolandlovely.status.error",
|
|
79
|
+
failed: "coolandlovely.status.failed",
|
|
80
|
+
completed: "coolandlovely.status.completed"
|
|
81
|
+
};
|
|
82
|
+
function l(e) {
|
|
53
83
|
return e.replace(/_/g, " ").replace(/\b\w/g, (e) => e.toUpperCase());
|
|
54
84
|
}
|
|
55
|
-
var
|
|
56
|
-
let
|
|
57
|
-
return /* @__PURE__ */
|
|
58
|
-
className: e("inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium",
|
|
59
|
-
children: [/* @__PURE__ */
|
|
85
|
+
var u = ({ status: u, className: d }) => {
|
|
86
|
+
let f = t(), p = u.toLowerCase(), m = o[p] || "secondary", h = s.has(p), g = c[p], _ = g ? f(g, l(u)) : l(u);
|
|
87
|
+
return /* @__PURE__ */ r("span", {
|
|
88
|
+
className: e("inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium", i[m], d),
|
|
89
|
+
children: [/* @__PURE__ */ n("span", {
|
|
60
90
|
"aria-hidden": "true",
|
|
61
|
-
className: e("h-1.5 w-1.5 rounded-full",
|
|
62
|
-
}),
|
|
91
|
+
className: e("h-1.5 w-1.5 rounded-full", a[m], h && "motion-safe:animate-vc-glow-pulse")
|
|
92
|
+
}), _]
|
|
63
93
|
});
|
|
64
94
|
};
|
|
65
95
|
//#endregion
|
|
66
|
-
export {
|
|
96
|
+
export { u as StatusBadge };
|
|
67
97
|
|
|
68
98
|
//# sourceMappingURL=StatusBadge.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StatusBadge.js","names":[],"sources":["../../../src/coolandlovely/components/StatusBadge.tsx"],"sourcesContent":["/**\n * Status Badge Component\n * @module coolandlovely/components\n *\n * A colored badge based on status value with semantic color mapping\n * for various order, cart, and investment statuses.\n */\n\nimport type { FC } from 'react';\nimport { cn } from '../utils/cn';\n\ninterface StatusBadgeProps {\n status: string;\n className?: string;\n}\n\ntype BadgeVariant = 'success' | 'warning' | 'destructive' | 'secondary' | 'info' | 'outline';\n\nconst variantStyles: Record<BadgeVariant, string> = {\n success: 'bg-status-success-bg-subtle text-status-success-text',\n warning: 'bg-status-warning-bg-subtle text-status-warning-text',\n destructive: 'bg-status-error-bg-subtle text-status-error-text',\n secondary: 'bg-bg-sunken text-text-secondary',\n info: 'bg-accent-blue-subtle text-accent-blue',\n outline: 'border border-border-seam text-text-primary',\n};\n\nconst dotStyles: Record<BadgeVariant, string> = {\n success: 'bg-status-success-text',\n warning: 'bg-status-warning-text',\n destructive: 'bg-status-error-text',\n secondary: 'bg-text-secondary',\n info: 'bg-accent-blue',\n outline: 'bg-text-secondary',\n};\n\nconst statusVariantMap: Record<string, BadgeVariant> = {\n // Brand lifecycle\n draft: 'secondary',\n pending_review: 'warning',\n published: 'success',\n suspended: 'destructive',\n archived: 'outline',\n\n // Collection lifecycle\n scheduled: 'info',\n live: 'success',\n ended: 'outline',\n\n // Style item status\n active: 'success',\n out_of_stock: 'warning',\n retired: 'outline',\n\n // Collaboration lifecycle\n proposed: 'secondary',\n accepted: 'info',\n in_progress: 'warning',\n declined: 'destructive',\n cancelled: 'destructive',\n\n // Visibility\n public: 'success',\n followers: 'info',\n private: 'secondary',\n\n // Wardrobe source\n owned: 'success',\n wishlist: 'info',\n purchased_on_platform: 'success',\n gifted: 'warning',\n\n // Generic\n inactive: 'secondary',\n error: 'destructive',\n failed: 'destructive',\n completed: 'success',\n};\n\n/** Statuses that represent a live/active state get a calm opacity pulse on the dot. */\nconst liveStatuses = new Set(['live', 'published', 'active', 'in_progress']);\n\nfunction formatStatusLabel(status: string): string {\n return status.replace(/_/g, ' ').replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\nexport const StatusBadge: FC<StatusBadgeProps> = ({ status, className }) => {\n const key = status.toLowerCase();\n const variant = statusVariantMap[key] || 'secondary';\n const isLive = liveStatuses.has(key);\n\n return (\n <span\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium',\n variantStyles[variant],\n className\n )}\n >\n <span\n aria-hidden=\"true\"\n className={cn(\n 'h-1.5 w-1.5 rounded-full',\n dotStyles[variant],\n isLive && 'motion-safe:animate-vc-glow-pulse'\n )}\n />\n {
|
|
1
|
+
{"version":3,"file":"StatusBadge.js","names":[],"sources":["../../../src/coolandlovely/components/StatusBadge.tsx"],"sourcesContent":["/**\n * Status Badge Component\n * @module coolandlovely/components\n *\n * A colored badge based on status value with semantic color mapping\n * for various order, cart, and investment statuses.\n */\n\nimport type { FC } from 'react';\nimport { cn } from '../utils/cn';\nimport { useTr } from '../hooks';\n\ninterface StatusBadgeProps {\n status: string;\n className?: string;\n}\n\ntype BadgeVariant = 'success' | 'warning' | 'destructive' | 'secondary' | 'info' | 'outline';\n\nconst variantStyles: Record<BadgeVariant, string> = {\n success: 'bg-status-success-bg-subtle text-status-success-text',\n warning: 'bg-status-warning-bg-subtle text-status-warning-text',\n destructive: 'bg-status-error-bg-subtle text-status-error-text',\n secondary: 'bg-bg-sunken text-text-secondary',\n info: 'bg-accent-blue-subtle text-accent-blue',\n outline: 'border border-border-seam text-text-primary',\n};\n\nconst dotStyles: Record<BadgeVariant, string> = {\n success: 'bg-status-success-text',\n warning: 'bg-status-warning-text',\n destructive: 'bg-status-error-text',\n secondary: 'bg-text-secondary',\n info: 'bg-accent-blue',\n outline: 'bg-text-secondary',\n};\n\nconst statusVariantMap: Record<string, BadgeVariant> = {\n // Brand lifecycle\n draft: 'secondary',\n pending_review: 'warning',\n published: 'success',\n suspended: 'destructive',\n archived: 'outline',\n\n // Collection lifecycle\n scheduled: 'info',\n live: 'success',\n ended: 'outline',\n\n // Style item status\n active: 'success',\n out_of_stock: 'warning',\n retired: 'outline',\n\n // Collaboration lifecycle\n proposed: 'secondary',\n accepted: 'info',\n in_progress: 'warning',\n declined: 'destructive',\n cancelled: 'destructive',\n\n // Visibility\n public: 'success',\n followers: 'info',\n private: 'secondary',\n\n // Wardrobe source\n owned: 'success',\n wishlist: 'info',\n purchased_on_platform: 'success',\n gifted: 'warning',\n\n // Generic\n inactive: 'secondary',\n error: 'destructive',\n failed: 'destructive',\n completed: 'success',\n};\n\n/** Statuses that represent a live/active state get a calm opacity pulse on the dot. */\nconst liveStatuses = new Set(['live', 'published', 'active', 'in_progress']);\n\nconst STATUS_LABEL_KEYS: Record<string, string> = {\n draft: 'coolandlovely.status.draft',\n pending_review: 'coolandlovely.status.pendingReview',\n published: 'coolandlovely.status.published',\n suspended: 'coolandlovely.status.suspended',\n archived: 'coolandlovely.status.archived',\n scheduled: 'coolandlovely.status.scheduled',\n live: 'coolandlovely.status.live',\n ended: 'coolandlovely.status.ended',\n active: 'coolandlovely.status.active',\n out_of_stock: 'coolandlovely.status.outOfStock',\n retired: 'coolandlovely.status.retired',\n proposed: 'coolandlovely.status.proposed',\n accepted: 'coolandlovely.status.accepted',\n in_progress: 'coolandlovely.status.inProgress',\n declined: 'coolandlovely.status.declined',\n cancelled: 'coolandlovely.status.cancelled',\n public: 'coolandlovely.status.public',\n followers: 'coolandlovely.status.followers',\n private: 'coolandlovely.status.private',\n owned: 'coolandlovely.status.owned',\n wishlist: 'coolandlovely.status.wishlist',\n purchased_on_platform: 'coolandlovely.status.purchasedOnPlatform',\n gifted: 'coolandlovely.status.gifted',\n inactive: 'coolandlovely.status.inactive',\n error: 'coolandlovely.status.error',\n failed: 'coolandlovely.status.failed',\n completed: 'coolandlovely.status.completed',\n};\n\nfunction formatStatusLabel(status: string): string {\n return status.replace(/_/g, ' ').replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\nexport const StatusBadge: FC<StatusBadgeProps> = ({ status, className }) => {\n const tr = useTr();\n const key = status.toLowerCase();\n const variant = statusVariantMap[key] || 'secondary';\n const isLive = liveStatuses.has(key);\n const labelKey = STATUS_LABEL_KEYS[key];\n const label = labelKey ? tr(labelKey, formatStatusLabel(status)) : formatStatusLabel(status);\n\n return (\n <span\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium',\n variantStyles[variant],\n className\n )}\n >\n <span\n aria-hidden=\"true\"\n className={cn(\n 'h-1.5 w-1.5 rounded-full',\n dotStyles[variant],\n isLive && 'motion-safe:animate-vc-glow-pulse'\n )}\n />\n {label}\n </span>\n );\n};\n"],"mappings":";;;;;AAmBA,IAAM,IAA8C;CAClD,SAAS;CACT,SAAS;CACT,aAAa;CACb,WAAW;CACX,MAAM;CACN,SAAS;CACV,EAEK,IAA0C;CAC9C,SAAS;CACT,SAAS;CACT,aAAa;CACb,WAAW;CACX,MAAM;CACN,SAAS;CACV,EAEK,IAAiD;CAErD,OAAO;CACP,gBAAgB;CAChB,WAAW;CACX,WAAW;CACX,UAAU;CAGV,WAAW;CACX,MAAM;CACN,OAAO;CAGP,QAAQ;CACR,cAAc;CACd,SAAS;CAGT,UAAU;CACV,UAAU;CACV,aAAa;CACb,UAAU;CACV,WAAW;CAGX,QAAQ;CACR,WAAW;CACX,SAAS;CAGT,OAAO;CACP,UAAU;CACV,uBAAuB;CACvB,QAAQ;CAGR,UAAU;CACV,OAAO;CACP,QAAQ;CACR,WAAW;CACZ,EAGK,IAAe,IAAI,IAAI;CAAC;CAAQ;CAAa;CAAU;CAAc,CAAC,EAEtE,IAA4C;CAChD,OAAO;CACP,gBAAgB;CAChB,WAAW;CACX,WAAW;CACX,UAAU;CACV,WAAW;CACX,MAAM;CACN,OAAO;CACP,QAAQ;CACR,cAAc;CACd,SAAS;CACT,UAAU;CACV,UAAU;CACV,aAAa;CACb,UAAU;CACV,WAAW;CACX,QAAQ;CACR,WAAW;CACX,SAAS;CACT,OAAO;CACP,UAAU;CACV,uBAAuB;CACvB,QAAQ;CACR,UAAU;CACV,OAAO;CACP,QAAQ;CACR,WAAW;CACZ;AAED,SAAS,EAAkB,GAAwB;AACjD,QAAO,EAAO,QAAQ,MAAM,IAAI,CAAC,QAAQ,UAAU,MAAS,EAAK,aAAa,CAAC;;AAGjF,IAAa,KAAqC,EAAE,WAAQ,mBAAgB;CAC1E,IAAM,IAAK,GAAO,EACZ,IAAM,EAAO,aAAa,EAC1B,IAAU,EAAiB,MAAQ,aACnC,IAAS,EAAa,IAAI,EAAI,EAC9B,IAAW,EAAkB,IAC7B,IAAQ,IAAW,EAAG,GAAU,EAAkB,EAAO,CAAC,GAAG,EAAkB,EAAO;AAE5F,QACE,kBAAC,QAAD;EACE,WAAW,EACT,mFACA,EAAc,IACd,EACD;YALH,CAOE,kBAAC,QAAD;GACE,eAAY;GACZ,WAAW,EACT,4BACA,EAAU,IACV,KAAU,oCACX;GACD,CAAA,EACD,EACI"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VisibilityChip.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/components/VisibilityChip.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"VisibilityChip.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/components/VisibilityChip.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAMhC,UAAU,mBAAmB;IAC3B,iFAAiF;IACjF,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAQD,eAAO,MAAM,cAAc,EAAE,EAAE,CAAC,mBAAmB,CAkBlD,CAAC"}
|
|
@@ -1,32 +1,37 @@
|
|
|
1
1
|
import { cn as e } from "../utils/cn.js";
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
2
|
+
import { useTr as t } from "../hooks/useTr.js";
|
|
3
|
+
import "../hooks/index.js";
|
|
4
|
+
import { titleCase as n } from "../utils/formatters.js";
|
|
5
|
+
import { Globe as r, Lock as i, Users as a } from "lucide-react";
|
|
6
|
+
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
5
7
|
//#region src/coolandlovely/components/VisibilityChip.tsx
|
|
6
|
-
var
|
|
8
|
+
var c = {
|
|
7
9
|
public: {
|
|
8
|
-
icon:
|
|
9
|
-
label: "Public"
|
|
10
|
+
icon: r,
|
|
11
|
+
label: "Public",
|
|
12
|
+
labelKey: "coolandlovely.visibility.public"
|
|
10
13
|
},
|
|
11
14
|
followers: {
|
|
12
|
-
icon:
|
|
13
|
-
label: "Followers"
|
|
15
|
+
icon: a,
|
|
16
|
+
label: "Followers",
|
|
17
|
+
labelKey: "coolandlovely.visibility.followers"
|
|
14
18
|
},
|
|
15
19
|
private: {
|
|
16
|
-
icon:
|
|
17
|
-
label: "Private"
|
|
20
|
+
icon: i,
|
|
21
|
+
label: "Private",
|
|
22
|
+
labelKey: "coolandlovely.visibility.private"
|
|
18
23
|
}
|
|
19
|
-
},
|
|
20
|
-
let
|
|
21
|
-
return /* @__PURE__ */
|
|
22
|
-
className: e("inline-flex items-center gap-1 rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary",
|
|
23
|
-
children: [/* @__PURE__ */
|
|
24
|
+
}, l = ({ visibility: r, className: a }) => {
|
|
25
|
+
let l = t(), u = c[r.trim().toLowerCase()], d = u?.icon ?? i, f = u ? l(u.labelKey, u.label) : n(r);
|
|
26
|
+
return /* @__PURE__ */ s("span", {
|
|
27
|
+
className: e("inline-flex items-center gap-1 rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary", a),
|
|
28
|
+
children: [/* @__PURE__ */ o(d, {
|
|
24
29
|
className: "h-3.5 w-3.5",
|
|
25
30
|
"aria-hidden": "true"
|
|
26
|
-
}),
|
|
31
|
+
}), f]
|
|
27
32
|
});
|
|
28
33
|
};
|
|
29
34
|
//#endregion
|
|
30
|
-
export {
|
|
35
|
+
export { l as VisibilityChip };
|
|
31
36
|
|
|
32
37
|
//# sourceMappingURL=VisibilityChip.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VisibilityChip.js","names":[],"sources":["../../../src/coolandlovely/components/VisibilityChip.tsx"],"sourcesContent":["/**\n * VisibilityChip — a small icon + label chip for a look/lookbook/profile\n * visibility (PRIVATE / FOLLOWERS / PUBLIC).\n * @module coolandlovely/components\n *\n * Token-only. The lock/users/globe glyph makes the visibility scannable at a\n * glance on lookbook cards, the lookbook detail header and the style profile.\n */\n\nimport type { FC } from 'react';\nimport { Globe, Lock, Users } from 'lucide-react';\nimport { cn } from '../utils/cn';\nimport { titleCase } from '../utils/formatters';\n\ninterface VisibilityChipProps {\n /** A `CooVisibility` value (PUBLIC / FOLLOWERS / PRIVATE) — case-insensitive. */\n visibility: string;\n className?: string;\n}\n\nconst CONFIG: Record<string, { icon: typeof Globe; label: string }> = {\n public: { icon: Globe, label: 'Public' },\n followers: { icon: Users, label: 'Followers' },\n private: { icon: Lock, label: 'Private' },\n};\n\nexport const VisibilityChip: FC<VisibilityChipProps> = ({ visibility, className }) => {\n const key = visibility.trim().toLowerCase();\n const config = CONFIG[key];\n const Icon = config?.icon ?? Lock;\n const label = config
|
|
1
|
+
{"version":3,"file":"VisibilityChip.js","names":[],"sources":["../../../src/coolandlovely/components/VisibilityChip.tsx"],"sourcesContent":["/**\n * VisibilityChip — a small icon + label chip for a look/lookbook/profile\n * visibility (PRIVATE / FOLLOWERS / PUBLIC).\n * @module coolandlovely/components\n *\n * Token-only. The lock/users/globe glyph makes the visibility scannable at a\n * glance on lookbook cards, the lookbook detail header and the style profile.\n */\n\nimport type { FC } from 'react';\nimport { Globe, Lock, Users } from 'lucide-react';\nimport { cn } from '../utils/cn';\nimport { titleCase } from '../utils/formatters';\nimport { useTr } from '../hooks';\n\ninterface VisibilityChipProps {\n /** A `CooVisibility` value (PUBLIC / FOLLOWERS / PRIVATE) — case-insensitive. */\n visibility: string;\n className?: string;\n}\n\nconst CONFIG: Record<string, { icon: typeof Globe; label: string; labelKey: string }> = {\n public: { icon: Globe, label: 'Public', labelKey: 'coolandlovely.visibility.public' },\n followers: { icon: Users, label: 'Followers', labelKey: 'coolandlovely.visibility.followers' },\n private: { icon: Lock, label: 'Private', labelKey: 'coolandlovely.visibility.private' },\n};\n\nexport const VisibilityChip: FC<VisibilityChipProps> = ({ visibility, className }) => {\n const tr = useTr();\n const key = visibility.trim().toLowerCase();\n const config = CONFIG[key];\n const Icon = config?.icon ?? Lock;\n const label = config ? tr(config.labelKey, config.label) : titleCase(visibility);\n\n return (\n <span\n className={cn(\n 'inline-flex items-center gap-1 rounded-full bg-bg-sunken px-2 py-0.5 text-xs font-medium text-text-secondary',\n className\n )}\n >\n <Icon className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n {label}\n </span>\n );\n};\n"],"mappings":";;;;;;;AAqBA,IAAM,IAAkF;CACtF,QAAQ;EAAE,MAAM;EAAO,OAAO;EAAU,UAAU;EAAmC;CACrF,WAAW;EAAE,MAAM;EAAO,OAAO;EAAa,UAAU;EAAsC;CAC9F,SAAS;EAAE,MAAM;EAAM,OAAO;EAAW,UAAU;EAAoC;CACxF,EAEY,KAA2C,EAAE,eAAY,mBAAgB;CACpF,IAAM,IAAK,GAAO,EAEZ,IAAS,EADH,EAAW,MAAM,CAAC,aAAa,GAErC,IAAO,GAAQ,QAAQ,GACvB,IAAQ,IAAS,EAAG,EAAO,UAAU,EAAO,MAAM,GAAG,EAAU,EAAW;AAEhF,QACE,kBAAC,QAAD;EACE,WAAW,EACT,gHACA,EACD;YAJH,CAME,kBAAC,GAAD;GAAM,WAAU;GAAc,eAAY;GAAS,CAAA,EAClD,EACI"}
|
|
@@ -14,6 +14,7 @@ export { LoadingView, ErrorView } from './StateViews';
|
|
|
14
14
|
export { FieldShell, TextField, TextAreaField, SelectField, ToggleField } from './Field';
|
|
15
15
|
export { ActorName } from './ActorName';
|
|
16
16
|
export { Comments } from './Comments';
|
|
17
|
+
export { ActivityTrail } from './ActivityTrail';
|
|
17
18
|
export { FollowButton } from './FollowButton';
|
|
18
19
|
export { AddToLookbookButton } from './AddToLookbookButton';
|
|
19
20
|
export { LookCard } from './LookCard';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/components/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/components/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -8,4 +8,8 @@ export { uploadImageToFiles, useFileUrl, COO_FILE_FOLDERS } from './useFiles';
|
|
|
8
8
|
export type { UploadedImage, CooFileFolder } from './useFiles';
|
|
9
9
|
export { useEntityComments, useAddComment } from './useComments';
|
|
10
10
|
export type { EntityCommentView, EntityCommentsResult } from './useComments';
|
|
11
|
+
export { useEntityActivity } from './useActivity';
|
|
12
|
+
export type { CooActivityEntry } from './useActivity';
|
|
13
|
+
export { useAssistantEntityName } from './useAssistantEntity';
|
|
14
|
+
export { useTr } from './useTr';
|
|
11
15
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/hooks/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEL,SAAS,EACT,QAAQ,EACR,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,eAAe,EAEf,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EAEpB,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EAEnB,QAAQ,EACR,iBAAiB,EACjB,OAAO,EACP,aAAa,EACb,aAAa,EACb,cAAc,EACd,WAAW,EACX,aAAa,EACb,WAAW,EACX,aAAa,EACb,aAAa,EAEb,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,0BAA0B,EAC1B,sBAAsB,EAEtB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,EAClB,qBAAqB,EAErB,iBAAiB,EACjB,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EAErB,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EAEjB,cAAc,EACd,SAAS,EACT,WAAW,EACX,cAAc,EACd,cAAc,EAEd,mBAAmB,EACnB,cAAc,EAEd,eAAe,EACf,cAAc,EACd,sBAAsB,EACtB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,GAChB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9E,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG/D,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACjE,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/hooks/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEL,SAAS,EACT,QAAQ,EACR,cAAc,EACd,cAAc,EACd,kBAAkB,EAClB,eAAe,EAEf,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EAEpB,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EAEnB,QAAQ,EACR,iBAAiB,EACjB,OAAO,EACP,aAAa,EACb,aAAa,EACb,cAAc,EACd,WAAW,EACX,aAAa,EACb,WAAW,EACX,aAAa,EACb,aAAa,EAEb,iBAAiB,EACjB,gBAAgB,EAChB,sBAAsB,EACtB,sBAAsB,EACtB,0BAA0B,EAC1B,sBAAsB,EAEtB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,EAClB,qBAAqB,EAErB,iBAAiB,EACjB,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EAErB,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EAEjB,cAAc,EACd,SAAS,EACT,WAAW,EACX,cAAc,EACd,cAAc,EAEd,mBAAmB,EACnB,cAAc,EAEd,eAAe,EACf,cAAc,EACd,sBAAsB,EACtB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,GAChB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9E,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG/D,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACjE,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAG7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAG9D,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Audit-trail hooks — activity via wspace-activity-svc (NO new table).
|
|
3
|
+
* @module coolandlovely/hooks
|
|
4
|
+
*
|
|
5
|
+
* CoolAndLovely does NOT own an audit table. Every `coo*` mutation is already
|
|
6
|
+
* recorded by the svc's mutation-audit plugin
|
|
7
|
+
* (`wspace-coolandlovely-svc/src/plugins/mutation-audit-plugin.ts`) through
|
|
8
|
+
* be-sdk `trackOperation`, which writes an `ActivityLog` row on
|
|
9
|
+
* wspace-activity-svc carrying:
|
|
10
|
+
*
|
|
11
|
+
* action — the plugin's `eventName`, e.g. `coolandlovely.brand_transitioned`
|
|
12
|
+
* description — `"<action> <resourceType>: <fieldName>"`
|
|
13
|
+
* resourceType — e.g. `coolandlovely-brand`
|
|
14
|
+
* resourceId — the affected record's id
|
|
15
|
+
* userId — the acting actor
|
|
16
|
+
*
|
|
17
|
+
* This hook is purely the read surface over those rows (`getActivities`,
|
|
18
|
+
* federated on the workspace supergraph). Nothing is synthesised: when the
|
|
19
|
+
* service has no rows for a record, callers render an empty state.
|
|
20
|
+
*/
|
|
21
|
+
/** A single audit entry as surfaced in the MFE (scalar-only projection). */
|
|
22
|
+
export interface CooActivityEntry {
|
|
23
|
+
id: string;
|
|
24
|
+
action: string;
|
|
25
|
+
description: string | null;
|
|
26
|
+
resourceType: string | null;
|
|
27
|
+
resourceId: string | null;
|
|
28
|
+
userId: string;
|
|
29
|
+
timestamp: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Audit entries for one record, newest first.
|
|
33
|
+
*
|
|
34
|
+
* `getActivities` is `@rbac(action: "read", resource: "activity-log",
|
|
35
|
+
* scopeType: "wspace")` — a member without that permission gets an error from
|
|
36
|
+
* the gateway, which callers surface honestly rather than hiding.
|
|
37
|
+
*/
|
|
38
|
+
export declare const useEntityActivity: (resourceType: string, resourceId: string | undefined, limit?: number) => import('@tanstack/react-query').UseQueryResult<NoInfer<CooActivityEntry[]>, Error>;
|
|
39
|
+
//# sourceMappingURL=useActivity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useActivity.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/hooks/useActivity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AASH,4EAA4E;AAC5E,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAqCD;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAC5B,cAAc,MAAM,EACpB,YAAY,MAAM,GAAG,SAAS,EAC9B,cAAU,uFAiBX,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useCoolAndLovely as e } from "../context/CoolAndLovelyContext.js";
|
|
2
|
+
import "../context/index.js";
|
|
3
|
+
import { useQuery as t } from "@tanstack/react-query";
|
|
4
|
+
import { graphqlFetch as n } from "@burdenoff/fe-libs/shared/graphql";
|
|
5
|
+
//#region src/coolandlovely/hooks/useActivity.ts
|
|
6
|
+
var r = "coolandlovely-activity", i = "\n query CooEntityActivity($filter: ActivityLogFilter) {\n getActivities(filter: $filter) {\n id\n action\n description\n resourceType\n resourceId\n userId\n timestamp\n }\n }\n", a = async (e, t, r) => {
|
|
7
|
+
let i = await n({
|
|
8
|
+
gateway: "workspace",
|
|
9
|
+
baseUrl: r,
|
|
10
|
+
query: e,
|
|
11
|
+
variables: t,
|
|
12
|
+
workspaceToken: !0
|
|
13
|
+
});
|
|
14
|
+
if (i.errors?.length) throw Error(i.errors[0]?.message ?? "Activity request failed");
|
|
15
|
+
if (!i.data) throw Error("Activity response did not include data");
|
|
16
|
+
return i.data;
|
|
17
|
+
}, o = (n, o, s = 20) => {
|
|
18
|
+
let { apiGatewayUrl: c, workspaceId: l } = e();
|
|
19
|
+
return t({
|
|
20
|
+
queryKey: [
|
|
21
|
+
r,
|
|
22
|
+
n,
|
|
23
|
+
o,
|
|
24
|
+
s
|
|
25
|
+
],
|
|
26
|
+
enabled: !!o && !!l,
|
|
27
|
+
queryFn: async () => [...(await a(i, { filter: {
|
|
28
|
+
workspaceId: l,
|
|
29
|
+
resourceType: n,
|
|
30
|
+
resourceId: o,
|
|
31
|
+
limit: s
|
|
32
|
+
} }, c)).getActivities].sort((e, t) => new Date(t.timestamp).getTime() - new Date(e.timestamp).getTime())
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
//#endregion
|
|
36
|
+
export { o as useEntityActivity };
|
|
37
|
+
|
|
38
|
+
//# sourceMappingURL=useActivity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useActivity.js","names":[],"sources":["../../../src/coolandlovely/hooks/useActivity.ts"],"sourcesContent":["/**\n * Audit-trail hooks — activity via wspace-activity-svc (NO new table).\n * @module coolandlovely/hooks\n *\n * CoolAndLovely does NOT own an audit table. Every `coo*` mutation is already\n * recorded by the svc's mutation-audit plugin\n * (`wspace-coolandlovely-svc/src/plugins/mutation-audit-plugin.ts`) through\n * be-sdk `trackOperation`, which writes an `ActivityLog` row on\n * wspace-activity-svc carrying:\n *\n * action — the plugin's `eventName`, e.g. `coolandlovely.brand_transitioned`\n * description — `\"<action> <resourceType>: <fieldName>\"`\n * resourceType — e.g. `coolandlovely-brand`\n * resourceId — the affected record's id\n * userId — the acting actor\n *\n * This hook is purely the read surface over those rows (`getActivities`,\n * federated on the workspace supergraph). Nothing is synthesised: when the\n * service has no rows for a record, callers render an empty state.\n */\n\nimport { useQuery } from '@tanstack/react-query';\nimport { graphqlFetch } from '@burdenoff/fe-libs/shared/graphql';\n\nimport { useCoolAndLovely } from '../context';\n\nconst QK = 'coolandlovely-activity';\n\n/** A single audit entry as surfaced in the MFE (scalar-only projection). */\nexport interface CooActivityEntry {\n id: string;\n action: string;\n description: string | null;\n resourceType: string | null;\n resourceId: string | null;\n userId: string;\n timestamp: string;\n}\n\nconst GET_ACTIVITIES = `\n query CooEntityActivity($filter: ActivityLogFilter) {\n getActivities(filter: $filter) {\n id\n action\n description\n resourceType\n resourceId\n userId\n timestamp\n }\n }\n`;\n\nconst activityFetch = async <TData>(\n query: string,\n variables: Record<string, unknown>,\n baseUrl?: string\n): Promise<TData> => {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n baseUrl,\n query,\n variables,\n workspaceToken: true,\n });\n if (response.errors?.length) {\n throw new Error(response.errors[0]?.message ?? 'Activity request failed');\n }\n if (!response.data) {\n throw new Error('Activity response did not include data');\n }\n return response.data;\n};\n\n/**\n * Audit entries for one record, newest first.\n *\n * `getActivities` is `@rbac(action: \"read\", resource: \"activity-log\",\n * scopeType: \"wspace\")` — a member without that permission gets an error from\n * the gateway, which callers surface honestly rather than hiding.\n */\nexport const useEntityActivity = (\n resourceType: string,\n resourceId: string | undefined,\n limit = 20\n) => {\n const { apiGatewayUrl, workspaceId } = useCoolAndLovely();\n return useQuery({\n queryKey: [QK, resourceType, resourceId, limit],\n enabled: Boolean(resourceId) && Boolean(workspaceId),\n queryFn: async (): Promise<CooActivityEntry[]> => {\n const data = await activityFetch<{ getActivities: CooActivityEntry[] }>(\n GET_ACTIVITIES,\n { filter: { workspaceId, resourceType, resourceId, limit } },\n apiGatewayUrl\n );\n return [...data.getActivities].sort(\n (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()\n );\n },\n });\n};\n"],"mappings":";;;;;AA0BA,IAAM,IAAK,0BAaL,IAAiB,iOAcjB,IAAgB,OACpB,GACA,GACA,MACmB;CACnB,IAAM,IAAW,MAAM,EAAoB;EACzC,SAAS;EACT;EACA;EACA;EACA,gBAAgB;EACjB,CAAC;AACF,KAAI,EAAS,QAAQ,OACnB,OAAU,MAAM,EAAS,OAAO,IAAI,WAAW,0BAA0B;AAE3E,KAAI,CAAC,EAAS,KACZ,OAAU,MAAM,yCAAyC;AAE3D,QAAO,EAAS;GAUL,KACX,GACA,GACA,IAAQ,OACL;CACH,IAAM,EAAE,kBAAe,mBAAgB,GAAkB;AACzD,QAAO,EAAS;EACd,UAAU;GAAC;GAAI;GAAc;GAAY;GAAM;EAC/C,SAAS,EAAQ,KAAe,EAAQ;EACxC,SAAS,YAMA,CAAC,IALK,MAAM,EACjB,GACA,EAAE,QAAQ;GAAE;GAAa;GAAc;GAAY;GAAO,EAAE,EAC5D,EACD,EACe,cAAc,CAAC,MAC5B,GAAG,MAAM,IAAI,KAAK,EAAE,UAAU,CAAC,SAAS,GAAG,IAAI,KAAK,EAAE,UAAU,CAAC,SAAS,CAC5E;EAEJ,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assistant screen-context hook.
|
|
3
|
+
* @module coolandlovely/hooks
|
|
4
|
+
*
|
|
5
|
+
* The floating assistant already receives `entityType` / `entityId`, both
|
|
6
|
+
* resolved from the URL. Neither tells the model WHAT the shopper is looking
|
|
7
|
+
* at, so "publish this storefront" or "what collections is this in" forces the
|
|
8
|
+
* assistant to echo a UUID back at a human.
|
|
9
|
+
*
|
|
10
|
+
* `entityName` is one of the agent's allowed context keys
|
|
11
|
+
* (`~/products/wspace/sandbox/ai-assistant/src/context-loader.ts`), but nothing
|
|
12
|
+
* in this product ever sent it. Detail pages call this hook with the name from
|
|
13
|
+
* their own loaded record — no extra request, no invented label — and it is
|
|
14
|
+
* withdrawn again on unmount.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Publish the current entity's display name to the assistant page context.
|
|
18
|
+
*
|
|
19
|
+
* Safe to call before the record has loaded: a missing id or name simply
|
|
20
|
+
* publishes nothing, so the assistant falls back to the id-only context it
|
|
21
|
+
* gets today rather than receiving a placeholder.
|
|
22
|
+
*/
|
|
23
|
+
export declare function useAssistantEntityName(entityId: string | undefined, entityName: string | null | undefined): void;
|
|
24
|
+
//# sourceMappingURL=useAssistantEntity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAssistantEntity.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/hooks/useAssistantEntity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACpC,IAAI,CAMN"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { clearActiveEntityName as e, setActiveEntityName as t } from "../../utils/pageContext.js";
|
|
2
|
+
import { useEffect as n } from "react";
|
|
3
|
+
//#region src/coolandlovely/hooks/useAssistantEntity.ts
|
|
4
|
+
function r(r, i) {
|
|
5
|
+
n(() => {
|
|
6
|
+
if (!(!r || !i)) return t(r, i), () => e(r);
|
|
7
|
+
}, [r, i]);
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { r as useAssistantEntityName };
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=useAssistantEntity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAssistantEntity.js","names":[],"sources":["../../../src/coolandlovely/hooks/useAssistantEntity.ts"],"sourcesContent":["/**\n * Assistant screen-context hook.\n * @module coolandlovely/hooks\n *\n * The floating assistant already receives `entityType` / `entityId`, both\n * resolved from the URL. Neither tells the model WHAT the shopper is looking\n * at, so \"publish this storefront\" or \"what collections is this in\" forces the\n * assistant to echo a UUID back at a human.\n *\n * `entityName` is one of the agent's allowed context keys\n * (`~/products/wspace/sandbox/ai-assistant/src/context-loader.ts`), but nothing\n * in this product ever sent it. Detail pages call this hook with the name from\n * their own loaded record — no extra request, no invented label — and it is\n * withdrawn again on unmount.\n */\n\nimport { useEffect } from 'react';\n\nimport { clearActiveEntityName, setActiveEntityName } from '../../utils/pageContext';\n\n/**\n * Publish the current entity's display name to the assistant page context.\n *\n * Safe to call before the record has loaded: a missing id or name simply\n * publishes nothing, so the assistant falls back to the id-only context it\n * gets today rather than receiving a placeholder.\n */\nexport function useAssistantEntityName(\n entityId: string | undefined,\n entityName: string | null | undefined\n): void {\n useEffect(() => {\n if (!entityId || !entityName) return;\n setActiveEntityName(entityId, entityName);\n return () => clearActiveEntityName(entityId);\n }, [entityId, entityName]);\n}\n"],"mappings":";;;AA2BA,SAAgB,EACd,GACA,GACM;AACN,SAAgB;AACV,SAAC,KAAY,CAAC,GAElB,QADA,EAAoB,GAAU,EAAW,QAC5B,EAAsB,EAAS;IAC3C,CAAC,GAAU,EAAW,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTr.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/hooks/useTr.ts"],"names":[],"mappings":"AAkBA,wBAAgB,KAAK,IAAI,CACvB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KACrC,MAAM,CAcV"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useCallback as e } from "react";
|
|
2
|
+
import { useI18n as t } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
3
|
+
//#region src/coolandlovely/hooks/useTr.ts
|
|
4
|
+
function n() {
|
|
5
|
+
let { t: n } = t();
|
|
6
|
+
return e((e, t, r) => {
|
|
7
|
+
let i = n(e), a = i === e ? t : i;
|
|
8
|
+
return r ? Object.entries(r).reduce((e, [t, n]) => e.replace(RegExp(`\\{\\{${t}\\}\\}`, "g"), String(n)), a) : a;
|
|
9
|
+
}, [n]);
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { n as useTr };
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=useTr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTr.js","names":[],"sources":["../../../src/coolandlovely/hooks/useTr.ts"],"sourcesContent":["/**\n * useTr — translation hook with fallback semantics.\n *\n * Wraps `useI18n().t()` so that when a key has no translation (i.e. the\n * provider returns the key itself), the caller's English fallback is used\n * instead. This keeps consumer call sites consistent and avoids leaking\n * untranslated keys into the UI.\n *\n * Supports optional interpolation params using `{{key}}` placeholders.\n *\n * @example\n * const tr = useTr();\n * return <h1>{tr('coolandlovely.dashboard.title', 'Dashboard')}</h1>;\n * return <p>{tr('coolandlovely.delete.confirm', 'Delete {{count}} items?', { count: 5 })}</p>;\n */\nimport { useCallback } from 'react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\n\nexport function useTr(): (\n key: string,\n fallback: string,\n params?: Record<string, string | number>\n) => string {\n const { t } = useI18n();\n return useCallback(\n (key: string, fallback: string, params?: Record<string, string | number>): string => {\n const translated = t(key);\n const raw = translated === key ? fallback : translated;\n if (!params) return raw;\n return Object.entries(params).reduce(\n (str, [k, v]) => str.replace(new RegExp(`\\\\{\\\\{${k}\\\\}\\\\}`, 'g'), String(v)),\n raw\n );\n },\n [t]\n );\n}\n"],"mappings":";;;AAkBA,SAAgB,IAIJ;CACV,IAAM,EAAE,SAAM,GAAS;AACvB,QAAO,GACJ,GAAa,GAAkB,MAAqD;EACnF,IAAM,IAAa,EAAE,EAAI,EACnB,IAAM,MAAe,IAAM,IAAW;AAE5C,SADK,IACE,OAAO,QAAQ,EAAO,CAAC,QAC3B,GAAK,CAAC,GAAG,OAAO,EAAI,QAAY,OAAO,SAAS,EAAE,SAAS,IAAI,EAAE,OAAO,EAAE,CAAC,EAC5E,EACD,GAJmB;IAMtB,CAAC,EAAE,CACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HomePage.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/pages/HomePage.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"HomePage.d.ts","sourceRoot":"","sources":["../../../src/coolandlovely/pages/HomePage.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAoMH,wBAAgB,QAAQ,gCA8VvB"}
|