@burdenoff/microfe-coolandlovely 2026.1024.2 → 2026.1024.4
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/CoolAndLovelyRoot.d.ts +5 -0
- package/dist/coolandlovely/CoolAndLovelyRoot.d.ts.map +1 -0
- package/dist/coolandlovely/CoolAndLovelyRoot.js +92 -68
- package/dist/coolandlovely/CoolAndLovelyRoot.js.map +1 -1
- package/dist/coolandlovely/CoolAndLovelyRoutes.d.ts +4 -0
- package/dist/coolandlovely/CoolAndLovelyRoutes.d.ts.map +1 -0
- package/dist/coolandlovely/CoolAndLovelyRoutes.js +25 -9
- package/dist/coolandlovely/CoolAndLovelyRoutes.js.map +1 -1
- package/dist/coolandlovely/components/ActivityTrail.d.ts +24 -0
- package/dist/coolandlovely/components/ActivityTrail.d.ts.map +1 -0
- package/dist/coolandlovely/components/ActorName.d.ts +14 -0
- package/dist/coolandlovely/components/ActorName.d.ts.map +1 -0
- package/dist/coolandlovely/components/AddToCartPanel.d.ts +10 -0
- package/dist/coolandlovely/components/AddToCartPanel.d.ts.map +1 -0
- package/dist/coolandlovely/components/AddToCartPanel.js +97 -0
- package/dist/coolandlovely/components/AddToCartPanel.js.map +1 -0
- package/dist/coolandlovely/components/AddToLookbookButton.d.ts +10 -0
- package/dist/coolandlovely/components/AddToLookbookButton.d.ts.map +1 -0
- package/dist/coolandlovely/components/BrandCard.d.ts +11 -0
- package/dist/coolandlovely/components/BrandCard.d.ts.map +1 -0
- package/dist/coolandlovely/components/BrandCover.d.ts +17 -0
- package/dist/coolandlovely/components/BrandCover.d.ts.map +1 -0
- package/dist/coolandlovely/components/BrandCreatorAvatars.d.ts +14 -0
- package/dist/coolandlovely/components/BrandCreatorAvatars.d.ts.map +1 -0
- package/dist/coolandlovely/components/CollectionCard.d.ts +11 -0
- package/dist/coolandlovely/components/CollectionCard.d.ts.map +1 -0
- package/dist/coolandlovely/components/ColourSwatchRow.d.ts +11 -0
- package/dist/coolandlovely/components/ColourSwatchRow.d.ts.map +1 -0
- package/dist/coolandlovely/components/Comments.d.ts +14 -0
- package/dist/coolandlovely/components/Comments.d.ts.map +1 -0
- package/dist/coolandlovely/components/EmptyState.d.ts +14 -0
- package/dist/coolandlovely/components/EmptyState.d.ts.map +1 -0
- package/dist/coolandlovely/components/FeedbackWidget.d.ts +4 -0
- package/dist/coolandlovely/components/FeedbackWidget.d.ts.map +1 -0
- package/dist/coolandlovely/components/Field.d.ts +71 -0
- package/dist/coolandlovely/components/Field.d.ts.map +1 -0
- package/dist/coolandlovely/components/FileImage.d.ts +10 -0
- package/dist/coolandlovely/components/FileImage.d.ts.map +1 -0
- package/dist/coolandlovely/components/FollowButton.d.ts +11 -0
- package/dist/coolandlovely/components/FollowButton.d.ts.map +1 -0
- package/dist/coolandlovely/components/ImageUploadField.d.ts +21 -0
- package/dist/coolandlovely/components/ImageUploadField.d.ts.map +1 -0
- package/dist/coolandlovely/components/LookCard.d.ts +19 -0
- package/dist/coolandlovely/components/LookCard.d.ts.map +1 -0
- package/dist/coolandlovely/components/LookbookCard.d.ts +11 -0
- package/dist/coolandlovely/components/LookbookCard.d.ts.map +1 -0
- package/dist/coolandlovely/components/MetricsCard.d.ts +23 -0
- package/dist/coolandlovely/components/MetricsCard.d.ts.map +1 -0
- package/dist/coolandlovely/components/PageLayout.d.ts +17 -0
- package/dist/coolandlovely/components/PageLayout.d.ts.map +1 -0
- package/dist/coolandlovely/components/PayForOrder.d.ts +11 -0
- package/dist/coolandlovely/components/PayForOrder.d.ts.map +1 -0
- package/dist/coolandlovely/components/PayForOrder.js +118 -0
- package/dist/coolandlovely/components/PayForOrder.js.map +1 -0
- package/dist/coolandlovely/components/ShopItemCard.d.ts +15 -0
- package/dist/coolandlovely/components/ShopItemCard.d.ts.map +1 -0
- package/dist/coolandlovely/components/StateViews.d.ts +16 -0
- package/dist/coolandlovely/components/StateViews.d.ts.map +1 -0
- package/dist/coolandlovely/components/StatusBadge.d.ts +9 -0
- package/dist/coolandlovely/components/StatusBadge.d.ts.map +1 -0
- package/dist/coolandlovely/components/StatusBadge.js +4 -0
- package/dist/coolandlovely/components/StatusBadge.js.map +1 -1
- package/dist/coolandlovely/components/StepTracker.d.ts +12 -0
- package/dist/coolandlovely/components/StepTracker.d.ts.map +1 -0
- package/dist/coolandlovely/components/TagList.d.ts +12 -0
- package/dist/coolandlovely/components/TagList.d.ts.map +1 -0
- package/dist/coolandlovely/components/Thumbnail.d.ts +23 -0
- package/dist/coolandlovely/components/Thumbnail.d.ts.map +1 -0
- package/dist/coolandlovely/components/VisibilityChip.d.ts +10 -0
- package/dist/coolandlovely/components/VisibilityChip.d.ts.map +1 -0
- package/dist/coolandlovely/components/WardrobeItemCard.d.ts +14 -0
- package/dist/coolandlovely/components/WardrobeItemCard.d.ts.map +1 -0
- package/dist/coolandlovely/components/index.d.ts +32 -0
- package/dist/coolandlovely/components/index.d.ts.map +1 -0
- package/dist/coolandlovely/context/CoolAndLovelyContext.d.ts +16 -0
- package/dist/coolandlovely/context/CoolAndLovelyContext.d.ts.map +1 -0
- package/dist/coolandlovely/context/index.d.ts +6 -0
- package/dist/coolandlovely/context/index.d.ts.map +1 -0
- package/dist/coolandlovely/hooks/index.d.ts +15 -0
- package/dist/coolandlovely/hooks/index.d.ts.map +1 -0
- package/dist/coolandlovely/hooks/useActivity.d.ts +39 -0
- package/dist/coolandlovely/hooks/useActivity.d.ts.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/useComments.d.ts +37 -0
- package/dist/coolandlovely/hooks/useComments.d.ts.map +1 -0
- package/dist/coolandlovely/hooks/useCommerceApi.d.ts +27 -0
- package/dist/coolandlovely/hooks/useCommerceApi.d.ts.map +1 -0
- package/dist/coolandlovely/hooks/useCommerceApi.js +121 -0
- package/dist/coolandlovely/hooks/useCommerceApi.js.map +1 -0
- package/dist/coolandlovely/hooks/useCoolAndLovelyApi.d.ts +178 -0
- package/dist/coolandlovely/hooks/useCoolAndLovelyApi.d.ts.map +1 -0
- package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js +1 -1
- package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js.map +1 -1
- package/dist/coolandlovely/hooks/useFiles.d.ts +62 -0
- package/dist/coolandlovely/hooks/useFiles.d.ts.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/index.d.ts +11 -0
- package/dist/coolandlovely/index.d.ts.map +1 -0
- package/dist/coolandlovely/pages/HomePage.d.ts +10 -0
- package/dist/coolandlovely/pages/HomePage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/admin/AdminBrandsPage.d.ts +9 -0
- package/dist/coolandlovely/pages/admin/AdminBrandsPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/admin/AdminCollaborationsPage.d.ts +9 -0
- package/dist/coolandlovely/pages/admin/AdminCollaborationsPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/admin/AdminFeaturedItemsPage.d.ts +9 -0
- package/dist/coolandlovely/pages/admin/AdminFeaturedItemsPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/admin/index.d.ts +8 -0
- package/dist/coolandlovely/pages/admin/index.d.ts.map +1 -0
- package/dist/coolandlovely/pages/brands/BrandDetailPage.d.ts +9 -0
- package/dist/coolandlovely/pages/brands/BrandDetailPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/brands/BrandFormPage.d.ts +9 -0
- package/dist/coolandlovely/pages/brands/BrandFormPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/brands/BrandsListPage.d.ts +9 -0
- package/dist/coolandlovely/pages/brands/BrandsListPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/collaborations/CollaborationDetailPage.d.ts +9 -0
- package/dist/coolandlovely/pages/collaborations/CollaborationDetailPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/collaborations/CollaborationFormPage.d.ts +11 -0
- package/dist/coolandlovely/pages/collaborations/CollaborationFormPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/collaborations/CollaborationsListPage.d.ts +9 -0
- package/dist/coolandlovely/pages/collaborations/CollaborationsListPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/collections/CollectionDetailPage.d.ts +9 -0
- package/dist/coolandlovely/pages/collections/CollectionDetailPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/collections/CollectionFormPage.d.ts +9 -0
- package/dist/coolandlovely/pages/collections/CollectionFormPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/collections/CollectionsListPage.d.ts +8 -0
- package/dist/coolandlovely/pages/collections/CollectionsListPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/commerce/CartPage.d.ts +10 -0
- package/dist/coolandlovely/pages/commerce/CartPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/commerce/CartPage.js +283 -0
- package/dist/coolandlovely/pages/commerce/CartPage.js.map +1 -0
- package/dist/coolandlovely/pages/commerce/CreatorEarningsPage.d.ts +11 -0
- package/dist/coolandlovely/pages/commerce/CreatorEarningsPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/commerce/CreatorEarningsPage.js +185 -0
- package/dist/coolandlovely/pages/commerce/CreatorEarningsPage.js.map +1 -0
- package/dist/coolandlovely/pages/commerce/OrdersPage.d.ts +11 -0
- package/dist/coolandlovely/pages/commerce/OrdersPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/commerce/OrdersPage.js +280 -0
- package/dist/coolandlovely/pages/commerce/OrdersPage.js.map +1 -0
- package/dist/coolandlovely/pages/discover/DiscoverPage.d.ts +14 -0
- package/dist/coolandlovely/pages/discover/DiscoverPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.d.ts +9 -0
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.js +114 -106
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.js.map +1 -1
- package/dist/coolandlovely/pages/items/StyleItemFormPage.d.ts +10 -0
- package/dist/coolandlovely/pages/items/StyleItemFormPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/items/StyleItemFormPage.js +130 -104
- package/dist/coolandlovely/pages/items/StyleItemFormPage.js.map +1 -1
- package/dist/coolandlovely/pages/items/StyleItemsListPage.d.ts +9 -0
- package/dist/coolandlovely/pages/items/StyleItemsListPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.d.ts +12 -0
- package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.d.ts +10 -0
- package/dist/coolandlovely/pages/lookbooks/LookbooksListPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/looks/LookDetailPage.d.ts +11 -0
- package/dist/coolandlovely/pages/looks/LookDetailPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/looks/LookDetailPage.js +1 -1
- package/dist/coolandlovely/pages/looks/LookDetailPage.js.map +1 -1
- package/dist/coolandlovely/pages/looks/LookFormPage.d.ts +10 -0
- package/dist/coolandlovely/pages/looks/LookFormPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/looks/LooksListPage.d.ts +9 -0
- package/dist/coolandlovely/pages/looks/LooksListPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/profile/StyleProfilePage.d.ts +17 -0
- package/dist/coolandlovely/pages/profile/StyleProfilePage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/trends/TrendsPage.d.ts +11 -0
- package/dist/coolandlovely/pages/trends/TrendsPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/wardrobe/WardrobeFormPage.d.ts +10 -0
- package/dist/coolandlovely/pages/wardrobe/WardrobeFormPage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.d.ts +12 -0
- package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.d.ts.map +1 -0
- package/dist/coolandlovely/store/coolandlovelyStore.d.ts +56 -0
- package/dist/coolandlovely/store/coolandlovelyStore.d.ts.map +1 -0
- package/dist/coolandlovely/store/index.d.ts +6 -0
- package/dist/coolandlovely/store/index.d.ts.map +1 -0
- package/dist/coolandlovely/types/commerce.d.ts +137 -0
- package/dist/coolandlovely/types/commerce.d.ts.map +1 -0
- package/dist/coolandlovely/types/index.d.ts +529 -0
- package/dist/coolandlovely/types/index.d.ts.map +1 -0
- package/dist/coolandlovely/utils/cn.d.ts +4 -0
- package/dist/coolandlovely/utils/cn.d.ts.map +1 -0
- package/dist/coolandlovely/utils/formatters.d.ts +101 -0
- package/dist/coolandlovely/utils/formatters.d.ts.map +1 -0
- package/dist/coolandlovely/utils/icons.d.ts +6 -0
- package/dist/coolandlovely/utils/icons.d.ts.map +1 -0
- package/dist/coolandlovely/utils/index.d.ts +10 -0
- package/dist/coolandlovely/utils/index.d.ts.map +1 -0
- package/dist/coolandlovely/utils/navigation.d.ts +20 -0
- package/dist/coolandlovely/utils/navigation.d.ts.map +1 -0
- package/dist/coolandlovely/utils/paymentProviders.d.ts +74 -0
- package/dist/coolandlovely/utils/paymentProviders.d.ts.map +1 -0
- package/dist/coolandlovely/utils/paymentProviders.js +42 -0
- package/dist/coolandlovely/utils/paymentProviders.js.map +1 -0
- package/dist/coolandlovely/utils/sparkline.d.ts +31 -0
- package/dist/coolandlovely/utils/sparkline.d.ts.map +1 -0
- package/dist/generated/global-operations.d.ts +2 -0
- package/dist/generated/global-operations.d.ts.map +1 -0
- package/dist/generated/global-types.d.ts +23527 -0
- package/dist/generated/global-types.d.ts.map +1 -0
- package/dist/generated/wspace-operations.d.ts +2 -0
- package/dist/generated/wspace-operations.d.ts.map +1 -0
- package/dist/generated/wspace-types.d.ts +57851 -0
- package/dist/generated/wspace-types.d.ts.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/services/createSandboxAssistantTransport.d.ts +24 -0
- package/dist/services/createSandboxAssistantTransport.d.ts.map +1 -0
- package/dist/stories/BrandCard.stories.d.ts +10 -0
- package/dist/stories/BrandCard.stories.d.ts.map +1 -0
- package/dist/stories/CollectionCard.stories.d.ts +10 -0
- package/dist/stories/CollectionCard.stories.d.ts.map +1 -0
- package/dist/stories/DiscoverPage.stories.d.ts +11 -0
- package/dist/stories/DiscoverPage.stories.d.ts.map +1 -0
- package/dist/stories/FeedbackWidget.stories.d.ts +9 -0
- package/dist/stories/FeedbackWidget.stories.d.ts.map +1 -0
- package/dist/stories/LookCard.stories.d.ts +10 -0
- package/dist/stories/LookCard.stories.d.ts.map +1 -0
- package/dist/stories/LookbookCard.stories.d.ts +10 -0
- package/dist/stories/LookbookCard.stories.d.ts.map +1 -0
- package/dist/stories/MetricsCard.stories.d.ts +10 -0
- package/dist/stories/MetricsCard.stories.d.ts.map +1 -0
- package/dist/stories/ShopItemCard.stories.d.ts +9 -0
- package/dist/stories/ShopItemCard.stories.d.ts.map +1 -0
- package/dist/stories/StatusBadge.stories.d.ts +11 -0
- package/dist/stories/StatusBadge.stories.d.ts.map +1 -0
- package/dist/stories/VisibilityChip.stories.d.ts +10 -0
- package/dist/stories/VisibilityChip.stories.d.ts.map +1 -0
- package/dist/stories/WardrobeItemCard.stories.d.ts +11 -0
- package/dist/stories/WardrobeItemCard.stories.d.ts.map +1 -0
- package/dist/stories/__fixtures__/coolandlovely.d.ts +15 -0
- package/dist/stories/__fixtures__/coolandlovely.d.ts.map +1 -0
- package/dist/utils/pageContext.d.ts +58 -0
- package/dist/utils/pageContext.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collection Detail Page
|
|
3
|
+
* @module coolandlovely/pages/collections
|
|
4
|
+
*
|
|
5
|
+
* Single collection (`cooCollection`) with publish (`cooPublishCollection`),
|
|
6
|
+
* edit, its brand link and member items.
|
|
7
|
+
*/
|
|
8
|
+
export declare function CollectionDetailPage(): import("react").JSX.Element;
|
|
9
|
+
//# sourceMappingURL=CollectionDetailPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CollectionDetailPage.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/pages/collections/CollectionDetailPage.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAqBH,wBAAgB,oBAAoB,gCAkPnC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collection Create / Edit Page
|
|
3
|
+
* @module coolandlovely/pages/collections
|
|
4
|
+
*
|
|
5
|
+
* Drives `cooCreateCollection` (new) and `cooUpdateCollection` (edit).
|
|
6
|
+
* Brand selection is required on create and locked on edit.
|
|
7
|
+
*/
|
|
8
|
+
export declare function CollectionFormPage(): import("react").JSX.Element;
|
|
9
|
+
//# sourceMappingURL=CollectionFormPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CollectionFormPage.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/pages/collections/CollectionFormPage.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAqDH,wBAAgB,kBAAkB,gCA6OjC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collections List Page
|
|
3
|
+
* @module coolandlovely/pages/collections
|
|
4
|
+
*
|
|
5
|
+
* Lists seasonal collections (`cooListCollections`) with status filter.
|
|
6
|
+
*/
|
|
7
|
+
export declare function CollectionsListPage(): import("react").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=CollectionsListPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CollectionsListPage.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/pages/collections/CollectionsListPage.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAmBH,wBAAgB,mBAAmB,gCA2FlC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cart Page (BOFF-3370)
|
|
3
|
+
* @module coolandlovely/pages/commerce
|
|
4
|
+
*
|
|
5
|
+
* The shopper's cart (`cooMyCart`), quantity edits, and checkout. Checkout snapshots the cart
|
|
6
|
+
* into an order (`cooCheckout`), then the shopper pays through the provider global-billing
|
|
7
|
+
* chose; the order is only marked paid once the backend re-reads billing's record.
|
|
8
|
+
*/
|
|
9
|
+
export declare function CartPage(): import("react").JSX.Element;
|
|
10
|
+
//# sourceMappingURL=CartPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CartPage.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/pages/commerce/CartPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA0BH,wBAAgB,QAAQ,gCAgRvB"}
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { useCoolAndLovely as e } from "../../context/CoolAndLovelyContext.js";
|
|
2
|
+
import { PageLayout as t } from "../../components/PageLayout.js";
|
|
3
|
+
import { useTr as n } from "../../hooks/useTr.js";
|
|
4
|
+
import "../../hooks/index.js";
|
|
5
|
+
import { ErrorView as r, LoadingView as i } from "../../components/StateViews.js";
|
|
6
|
+
import { Thumbnail as a } from "../../components/Thumbnail.js";
|
|
7
|
+
import { formatPrice as o } from "../../utils/formatters.js";
|
|
8
|
+
import { EmptyState as s } from "../../components/EmptyState.js";
|
|
9
|
+
import { TextAreaField as c, TextField as l } from "../../components/Field.js";
|
|
10
|
+
import { PayForOrder as u } from "../../components/PayForOrder.js";
|
|
11
|
+
import { useCheckout as d, useMyCart as f, useRemoveCartItem as p, useSyncOrderPayment as m, useUpdateCartItem as h } from "../../hooks/useCommerceApi.js";
|
|
12
|
+
import { useState as g } from "react";
|
|
13
|
+
import { ArrowLeft as _, Loader2 as v, Minus as y, Plus as b, ShoppingBag as x, Sparkles as S, Trash2 as C } from "lucide-react";
|
|
14
|
+
import { jsx as w, jsxs as T } from "react/jsx-runtime";
|
|
15
|
+
import { GlassCard as E } from "@burdenoff/fe-libs/ui";
|
|
16
|
+
//#region src/coolandlovely/pages/commerce/CartPage.tsx
|
|
17
|
+
var D = 10;
|
|
18
|
+
function O() {
|
|
19
|
+
let O = n(), { navigateTo: k } = e(), A = f(), j = h(), M = p(), N = d(), P = m(), [F, I] = g(""), [L, R] = g(""), [z, B] = g(""), [V, H] = g(null), U = O("coolandlovely.cart.title", "Your cart");
|
|
20
|
+
if (A.isLoading) return /* @__PURE__ */ w(t, {
|
|
21
|
+
title: U,
|
|
22
|
+
children: /* @__PURE__ */ w(i, { label: O("coolandlovely.cart.loading", "Loading your cart…") })
|
|
23
|
+
});
|
|
24
|
+
if (A.isError || !A.data) return /* @__PURE__ */ w(t, {
|
|
25
|
+
title: U,
|
|
26
|
+
children: /* @__PURE__ */ w(r, { onRetry: () => void A.refetch() })
|
|
27
|
+
});
|
|
28
|
+
if (V) return /* @__PURE__ */ w(t, {
|
|
29
|
+
title: O("coolandlovely.checkout.payTitle", "Pay for your order"),
|
|
30
|
+
description: V.order.orderNumber,
|
|
31
|
+
children: /* @__PURE__ */ w("div", {
|
|
32
|
+
className: "mx-auto max-w-lg space-y-4",
|
|
33
|
+
children: /* @__PURE__ */ T(E, {
|
|
34
|
+
treatment: "glass",
|
|
35
|
+
className: "space-y-4 p-6",
|
|
36
|
+
children: [
|
|
37
|
+
/* @__PURE__ */ T("dl", {
|
|
38
|
+
className: "space-y-2 text-sm",
|
|
39
|
+
children: [
|
|
40
|
+
/* @__PURE__ */ T("div", {
|
|
41
|
+
className: "flex justify-between",
|
|
42
|
+
children: [/* @__PURE__ */ w("dt", {
|
|
43
|
+
className: "text-text-secondary",
|
|
44
|
+
children: O("coolandlovely.checkout.subtotal", "Subtotal")
|
|
45
|
+
}), /* @__PURE__ */ w("dd", {
|
|
46
|
+
className: "tabular-nums text-text-primary",
|
|
47
|
+
children: o(V.subtotal, V.currency)
|
|
48
|
+
})]
|
|
49
|
+
}),
|
|
50
|
+
/* @__PURE__ */ T("div", {
|
|
51
|
+
className: "flex justify-between",
|
|
52
|
+
children: [/* @__PURE__ */ w("dt", {
|
|
53
|
+
className: "text-text-secondary",
|
|
54
|
+
children: O("coolandlovely.checkout.tax", "Tax")
|
|
55
|
+
}), /* @__PURE__ */ w("dd", {
|
|
56
|
+
className: "tabular-nums text-text-primary",
|
|
57
|
+
children: o(V.taxAmount, V.currency)
|
|
58
|
+
})]
|
|
59
|
+
}),
|
|
60
|
+
/* @__PURE__ */ T("div", {
|
|
61
|
+
className: "flex justify-between border-t border-border-seam pt-2 text-base font-semibold",
|
|
62
|
+
children: [/* @__PURE__ */ w("dt", {
|
|
63
|
+
className: "text-text-primary",
|
|
64
|
+
children: O("coolandlovely.checkout.total", "Total")
|
|
65
|
+
}), /* @__PURE__ */ w("dd", {
|
|
66
|
+
className: "tabular-nums text-text-primary",
|
|
67
|
+
"data-testid": "checkout-total",
|
|
68
|
+
children: o(V.total, V.currency)
|
|
69
|
+
})]
|
|
70
|
+
})
|
|
71
|
+
]
|
|
72
|
+
}),
|
|
73
|
+
/* @__PURE__ */ w(u, {
|
|
74
|
+
checkout: V,
|
|
75
|
+
onSettle: async () => {
|
|
76
|
+
await P.mutateAsync(V.order.id).catch(() => void 0), k(`/orders/${V.order.id}`);
|
|
77
|
+
}
|
|
78
|
+
}),
|
|
79
|
+
/* @__PURE__ */ w("button", {
|
|
80
|
+
type: "button",
|
|
81
|
+
onClick: () => k(`/orders/${V.order.id}`),
|
|
82
|
+
className: "w-full text-center text-sm font-medium text-text-secondary hover:underline",
|
|
83
|
+
children: O("coolandlovely.checkout.payLater", "Pay later from My Orders")
|
|
84
|
+
})
|
|
85
|
+
]
|
|
86
|
+
})
|
|
87
|
+
})
|
|
88
|
+
});
|
|
89
|
+
let W = A.data, G = j.isPending || M.isPending, K = W.canCheckout && F.trim() !== "" && L.trim() !== "";
|
|
90
|
+
return /* @__PURE__ */ w(t, {
|
|
91
|
+
title: U,
|
|
92
|
+
description: O("coolandlovely.cart.description", "Pieces you are about to buy."),
|
|
93
|
+
actions: /* @__PURE__ */ T("button", {
|
|
94
|
+
type: "button",
|
|
95
|
+
onClick: () => k("/items"),
|
|
96
|
+
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",
|
|
97
|
+
children: [
|
|
98
|
+
/* @__PURE__ */ w(_, { className: "h-4 w-4" }),
|
|
99
|
+
" ",
|
|
100
|
+
O("coolandlovely.cart.keepShopping", "Keep shopping")
|
|
101
|
+
]
|
|
102
|
+
}),
|
|
103
|
+
children: W.items.length === 0 ? /* @__PURE__ */ w(s, {
|
|
104
|
+
icon: /* @__PURE__ */ w(x, { className: "h-8 w-8" }),
|
|
105
|
+
title: O("coolandlovely.cart.emptyTitle", "Your cart is empty"),
|
|
106
|
+
description: O("coolandlovely.cart.emptyDescription", "Add pieces from the catalogue or from a look."),
|
|
107
|
+
action: /* @__PURE__ */ w("button", {
|
|
108
|
+
type: "button",
|
|
109
|
+
onClick: () => k("/items"),
|
|
110
|
+
className: "rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text",
|
|
111
|
+
children: O("coolandlovely.cart.browse", "Browse pieces")
|
|
112
|
+
})
|
|
113
|
+
}) : /* @__PURE__ */ T("div", {
|
|
114
|
+
className: "grid grid-cols-1 gap-6 lg:grid-cols-3",
|
|
115
|
+
children: [/* @__PURE__ */ T("div", {
|
|
116
|
+
className: "space-y-3 lg:col-span-2",
|
|
117
|
+
"data-testid": "cart-lines",
|
|
118
|
+
children: [W.items.map((e) => /* @__PURE__ */ T(E, {
|
|
119
|
+
treatment: "plain",
|
|
120
|
+
className: "flex items-center gap-4 p-4",
|
|
121
|
+
children: [
|
|
122
|
+
/* @__PURE__ */ w(a, {
|
|
123
|
+
icon: /* @__PURE__ */ w(x, { className: "h-5 w-5" }),
|
|
124
|
+
seed: e.styleItemId,
|
|
125
|
+
fileId: e.styleItem?.image?.id,
|
|
126
|
+
alt: e.styleItem?.name ?? "",
|
|
127
|
+
className: "h-16 w-16 shrink-0"
|
|
128
|
+
}),
|
|
129
|
+
/* @__PURE__ */ T("div", {
|
|
130
|
+
className: "min-w-0 flex-1",
|
|
131
|
+
children: [
|
|
132
|
+
/* @__PURE__ */ w("button", {
|
|
133
|
+
type: "button",
|
|
134
|
+
onClick: () => k(`/items/${e.styleItemId}`),
|
|
135
|
+
className: "truncate text-left text-sm font-medium text-text-primary hover:underline",
|
|
136
|
+
children: e.styleItem?.name ?? O("coolandlovely.cart.unknownPiece", "Catalogue piece")
|
|
137
|
+
}),
|
|
138
|
+
/* @__PURE__ */ w("p", {
|
|
139
|
+
className: "truncate text-xs text-text-secondary",
|
|
140
|
+
children: [
|
|
141
|
+
e.styleItem?.brand?.name,
|
|
142
|
+
e.size,
|
|
143
|
+
e.colour
|
|
144
|
+
].filter(Boolean).join(" · ")
|
|
145
|
+
}),
|
|
146
|
+
e.lookId && /* @__PURE__ */ T("p", {
|
|
147
|
+
className: "mt-0.5 inline-flex items-center gap-1 text-xs text-accent-primary",
|
|
148
|
+
children: [
|
|
149
|
+
/* @__PURE__ */ w(S, { className: "h-3 w-3" }),
|
|
150
|
+
" ",
|
|
151
|
+
O("coolandlovely.cart.fromLook", "From a look")
|
|
152
|
+
]
|
|
153
|
+
}),
|
|
154
|
+
!e.isPurchasable && /* @__PURE__ */ w("p", {
|
|
155
|
+
className: "mt-0.5 text-xs text-status-error-text",
|
|
156
|
+
children: O("coolandlovely.cart.unavailable", "No longer available")
|
|
157
|
+
})
|
|
158
|
+
]
|
|
159
|
+
}),
|
|
160
|
+
/* @__PURE__ */ T("div", {
|
|
161
|
+
className: "flex items-center gap-1",
|
|
162
|
+
children: [
|
|
163
|
+
/* @__PURE__ */ w("button", {
|
|
164
|
+
type: "button",
|
|
165
|
+
"aria-label": O("coolandlovely.cart.decrease", "Decrease quantity"),
|
|
166
|
+
disabled: G,
|
|
167
|
+
onClick: () => j.mutate({
|
|
168
|
+
id: e.id,
|
|
169
|
+
quantity: e.quantity - 1
|
|
170
|
+
}),
|
|
171
|
+
className: "rounded-md border border-border-seam p-1.5 text-text-primary hover:bg-bg-sunken disabled:opacity-50",
|
|
172
|
+
children: /* @__PURE__ */ w(y, { className: "h-3.5 w-3.5" })
|
|
173
|
+
}),
|
|
174
|
+
/* @__PURE__ */ w("span", {
|
|
175
|
+
className: "w-6 text-center text-sm tabular-nums text-text-primary",
|
|
176
|
+
"data-testid": "cart-line-quantity",
|
|
177
|
+
children: e.quantity
|
|
178
|
+
}),
|
|
179
|
+
/* @__PURE__ */ w("button", {
|
|
180
|
+
type: "button",
|
|
181
|
+
"aria-label": O("coolandlovely.cart.increase", "Increase quantity"),
|
|
182
|
+
disabled: G || e.quantity >= D,
|
|
183
|
+
onClick: () => j.mutate({
|
|
184
|
+
id: e.id,
|
|
185
|
+
quantity: e.quantity + 1
|
|
186
|
+
}),
|
|
187
|
+
className: "rounded-md border border-border-seam p-1.5 text-text-primary hover:bg-bg-sunken disabled:opacity-50",
|
|
188
|
+
children: /* @__PURE__ */ w(b, { className: "h-3.5 w-3.5" })
|
|
189
|
+
})
|
|
190
|
+
]
|
|
191
|
+
}),
|
|
192
|
+
/* @__PURE__ */ w("p", {
|
|
193
|
+
className: "w-24 text-right text-sm font-semibold tabular-nums text-text-primary",
|
|
194
|
+
children: o(e.lineTotal, e.currency)
|
|
195
|
+
}),
|
|
196
|
+
/* @__PURE__ */ w("button", {
|
|
197
|
+
type: "button",
|
|
198
|
+
"aria-label": O("coolandlovely.cart.remove", "Remove from cart"),
|
|
199
|
+
disabled: G,
|
|
200
|
+
onClick: () => M.mutate({ id: e.id }),
|
|
201
|
+
className: "rounded-md p-1.5 text-status-error-text hover:bg-status-error-bg-subtle disabled:opacity-50",
|
|
202
|
+
children: /* @__PURE__ */ w(C, { className: "h-4 w-4" })
|
|
203
|
+
})
|
|
204
|
+
]
|
|
205
|
+
}, e.id)), (j.error || M.error) && /* @__PURE__ */ w("p", {
|
|
206
|
+
className: "text-sm text-status-error-text",
|
|
207
|
+
children: (j.error ?? M.error)?.message
|
|
208
|
+
})]
|
|
209
|
+
}), /* @__PURE__ */ T(E, {
|
|
210
|
+
treatment: "glass",
|
|
211
|
+
className: "h-fit space-y-4 p-6",
|
|
212
|
+
children: [
|
|
213
|
+
/* @__PURE__ */ T("div", {
|
|
214
|
+
className: "flex items-baseline justify-between",
|
|
215
|
+
children: [/* @__PURE__ */ w("span", {
|
|
216
|
+
className: "text-sm text-text-secondary",
|
|
217
|
+
children: O("coolandlovely.cart.subtotalItems", "Subtotal ({{count}} items)", { count: W.itemCount })
|
|
218
|
+
}), /* @__PURE__ */ w("span", {
|
|
219
|
+
className: "text-xl font-bold tabular-nums text-text-primary",
|
|
220
|
+
"data-testid": "cart-subtotal",
|
|
221
|
+
children: o(W.subtotal, W.currency ?? "USD")
|
|
222
|
+
})]
|
|
223
|
+
}),
|
|
224
|
+
/* @__PURE__ */ w("p", {
|
|
225
|
+
className: "text-xs text-text-secondary",
|
|
226
|
+
children: O("coolandlovely.cart.taxNote", "Tax is calculated when you place the order.")
|
|
227
|
+
}),
|
|
228
|
+
W.blockedReason && /* @__PURE__ */ w("p", {
|
|
229
|
+
className: "text-sm text-status-error-text",
|
|
230
|
+
children: W.blockedReason
|
|
231
|
+
}),
|
|
232
|
+
/* @__PURE__ */ T("div", {
|
|
233
|
+
className: "space-y-3 border-t border-border-seam pt-4",
|
|
234
|
+
children: [
|
|
235
|
+
/* @__PURE__ */ w(l, {
|
|
236
|
+
id: "coo-shipping-name",
|
|
237
|
+
label: O("coolandlovely.checkout.shippingName", "Full name"),
|
|
238
|
+
value: F,
|
|
239
|
+
onChange: I,
|
|
240
|
+
required: !0
|
|
241
|
+
}),
|
|
242
|
+
/* @__PURE__ */ w(c, {
|
|
243
|
+
id: "coo-shipping-address",
|
|
244
|
+
label: O("coolandlovely.checkout.shippingAddress", "Shipping address"),
|
|
245
|
+
value: L,
|
|
246
|
+
onChange: R,
|
|
247
|
+
rows: 3,
|
|
248
|
+
required: !0
|
|
249
|
+
}),
|
|
250
|
+
/* @__PURE__ */ w(l, {
|
|
251
|
+
id: "coo-buyer-note",
|
|
252
|
+
label: O("coolandlovely.checkout.note", "Note for the brand (optional)"),
|
|
253
|
+
value: z,
|
|
254
|
+
onChange: B
|
|
255
|
+
})
|
|
256
|
+
]
|
|
257
|
+
}),
|
|
258
|
+
N.error && /* @__PURE__ */ w("p", {
|
|
259
|
+
className: "text-sm text-status-error-text",
|
|
260
|
+
children: N.error.message
|
|
261
|
+
}),
|
|
262
|
+
/* @__PURE__ */ T("button", {
|
|
263
|
+
type: "button",
|
|
264
|
+
disabled: !K || N.isPending,
|
|
265
|
+
onClick: () => {
|
|
266
|
+
N.mutate({
|
|
267
|
+
shippingName: F.trim(),
|
|
268
|
+
shippingAddress: L.trim(),
|
|
269
|
+
buyerNote: z.trim() || null
|
|
270
|
+
}, { onSuccess: (e) => H(e) });
|
|
271
|
+
},
|
|
272
|
+
className: "inline-flex w-full items-center justify-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2.5 text-sm font-semibold text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-50",
|
|
273
|
+
children: [N.isPending && /* @__PURE__ */ w(v, { className: "h-4 w-4 animate-spin" }), O("coolandlovely.checkout.placeOrder", "Place order")]
|
|
274
|
+
})
|
|
275
|
+
]
|
|
276
|
+
})]
|
|
277
|
+
})
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
//#endregion
|
|
281
|
+
export { O as CartPage };
|
|
282
|
+
|
|
283
|
+
//# sourceMappingURL=CartPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CartPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/commerce/CartPage.tsx"],"sourcesContent":["/**\n * Cart Page (BOFF-3370)\n * @module coolandlovely/pages/commerce\n *\n * The shopper's cart (`cooMyCart`), quantity edits, and checkout. Checkout snapshots the cart\n * into an order (`cooCheckout`), then the shopper pays through the provider global-billing\n * chose; the order is only marked paid once the backend re-reads billing's record.\n */\n\nimport { useState } from 'react';\nimport { ArrowLeft, Loader2, Minus, Plus, ShoppingBag, Sparkles, Trash2 } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\n\nimport { EmptyState } from '../../components/EmptyState';\nimport { TextAreaField, TextField } from '../../components/Field';\nimport { PageLayout } from '../../components/PageLayout';\nimport { PayForOrder } from '../../components/PayForOrder';\nimport { ErrorView, LoadingView } from '../../components/StateViews';\nimport { Thumbnail } from '../../components/Thumbnail';\nimport { useCoolAndLovely } from '../../context/CoolAndLovelyContext';\nimport { useTr } from '../../hooks';\nimport {\n useCheckout,\n useMyCart,\n useRemoveCartItem,\n useSyncOrderPayment,\n useUpdateCartItem,\n} from '../../hooks/useCommerceApi';\nimport type { CooOrderCheckout } from '../../types';\nimport { formatPrice } from '../../utils/formatters';\n\nconst MAX_QUANTITY = 10;\n\nexport function CartPage() {\n const tr = useTr();\n const { navigateTo } = useCoolAndLovely();\n const cart = useMyCart();\n const updateItem = useUpdateCartItem();\n const removeItem = useRemoveCartItem();\n const checkout = useCheckout();\n const sync = useSyncOrderPayment();\n\n const [shippingName, setShippingName] = useState('');\n const [shippingAddress, setShippingAddress] = useState('');\n const [buyerNote, setBuyerNote] = useState('');\n const [session, setSession] = useState<CooOrderCheckout | null>(null);\n\n const title = tr('coolandlovely.cart.title', 'Your cart');\n\n if (cart.isLoading) {\n return (\n <PageLayout title={title}>\n <LoadingView label={tr('coolandlovely.cart.loading', 'Loading your cart…')} />\n </PageLayout>\n );\n }\n if (cart.isError || !cart.data) {\n return (\n <PageLayout title={title}>\n <ErrorView onRetry={() => void cart.refetch()} />\n </PageLayout>\n );\n }\n\n // After checkout: the order exists, the cart is empty, and the shopper pays.\n if (session) {\n const settle = async () => {\n await sync.mutateAsync(session.order.id).catch(() => undefined);\n navigateTo(`/orders/${session.order.id}`);\n };\n return (\n <PageLayout\n title={tr('coolandlovely.checkout.payTitle', 'Pay for your order')}\n description={session.order.orderNumber}\n >\n <div className=\"mx-auto max-w-lg space-y-4\">\n <GlassCard treatment=\"glass\" className=\"space-y-4 p-6\">\n <dl className=\"space-y-2 text-sm\">\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">\n {tr('coolandlovely.checkout.subtotal', 'Subtotal')}\n </dt>\n <dd className=\"tabular-nums text-text-primary\">\n {formatPrice(session.subtotal, session.currency)}\n </dd>\n </div>\n <div className=\"flex justify-between\">\n <dt className=\"text-text-secondary\">{tr('coolandlovely.checkout.tax', 'Tax')}</dt>\n <dd className=\"tabular-nums text-text-primary\">\n {formatPrice(session.taxAmount, session.currency)}\n </dd>\n </div>\n <div className=\"flex justify-between border-t border-border-seam pt-2 text-base font-semibold\">\n <dt className=\"text-text-primary\">{tr('coolandlovely.checkout.total', 'Total')}</dt>\n <dd className=\"tabular-nums text-text-primary\" data-testid=\"checkout-total\">\n {formatPrice(session.total, session.currency)}\n </dd>\n </div>\n </dl>\n <PayForOrder checkout={session} onSettle={settle} />\n <button\n type=\"button\"\n onClick={() => navigateTo(`/orders/${session.order.id}`)}\n className=\"w-full text-center text-sm font-medium text-text-secondary hover:underline\"\n >\n {tr('coolandlovely.checkout.payLater', 'Pay later from My Orders')}\n </button>\n </GlassCard>\n </div>\n </PageLayout>\n );\n }\n\n const data = cart.data;\n const busy = updateItem.isPending || removeItem.isPending;\n const canSubmit = data.canCheckout && shippingName.trim() !== '' && shippingAddress.trim() !== '';\n\n const submit = () => {\n checkout.mutate(\n {\n shippingName: shippingName.trim(),\n shippingAddress: shippingAddress.trim(),\n buyerNote: buyerNote.trim() || null,\n },\n { onSuccess: (result) => setSession(result) }\n );\n };\n\n return (\n <PageLayout\n title={title}\n description={tr('coolandlovely.cart.description', 'Pieces you are about to buy.')}\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/items')}\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\" /> {tr('coolandlovely.cart.keepShopping', 'Keep shopping')}\n </button>\n }\n >\n {data.items.length === 0 ? (\n <EmptyState\n icon={<ShoppingBag className=\"h-8 w-8\" />}\n title={tr('coolandlovely.cart.emptyTitle', 'Your cart is empty')}\n description={tr(\n 'coolandlovely.cart.emptyDescription',\n 'Add pieces from the catalogue or from a look.'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/items')}\n className=\"rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text\"\n >\n {tr('coolandlovely.cart.browse', 'Browse pieces')}\n </button>\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-3\">\n <div className=\"space-y-3 lg:col-span-2\" data-testid=\"cart-lines\">\n {data.items.map((line) => (\n <GlassCard key={line.id} treatment=\"plain\" className=\"flex items-center gap-4 p-4\">\n <Thumbnail\n icon={<ShoppingBag className=\"h-5 w-5\" />}\n seed={line.styleItemId}\n fileId={line.styleItem?.image?.id}\n alt={line.styleItem?.name ?? ''}\n className=\"h-16 w-16 shrink-0\"\n />\n <div className=\"min-w-0 flex-1\">\n <button\n type=\"button\"\n onClick={() => navigateTo(`/items/${line.styleItemId}`)}\n className=\"truncate text-left text-sm font-medium text-text-primary hover:underline\"\n >\n {line.styleItem?.name ??\n tr('coolandlovely.cart.unknownPiece', 'Catalogue piece')}\n </button>\n <p className=\"truncate text-xs text-text-secondary\">\n {[line.styleItem?.brand?.name, line.size, line.colour]\n .filter(Boolean)\n .join(' · ')}\n </p>\n {line.lookId && (\n <p className=\"mt-0.5 inline-flex items-center gap-1 text-xs text-accent-primary\">\n <Sparkles className=\"h-3 w-3\" />{' '}\n {tr('coolandlovely.cart.fromLook', 'From a look')}\n </p>\n )}\n {!line.isPurchasable && (\n <p className=\"mt-0.5 text-xs text-status-error-text\">\n {tr('coolandlovely.cart.unavailable', 'No longer available')}\n </p>\n )}\n </div>\n <div className=\"flex items-center gap-1\">\n <button\n type=\"button\"\n aria-label={tr('coolandlovely.cart.decrease', 'Decrease quantity')}\n disabled={busy}\n onClick={() => updateItem.mutate({ id: line.id, quantity: line.quantity - 1 })}\n className=\"rounded-md border border-border-seam p-1.5 text-text-primary hover:bg-bg-sunken disabled:opacity-50\"\n >\n <Minus className=\"h-3.5 w-3.5\" />\n </button>\n <span\n className=\"w-6 text-center text-sm tabular-nums text-text-primary\"\n data-testid=\"cart-line-quantity\"\n >\n {line.quantity}\n </span>\n <button\n type=\"button\"\n aria-label={tr('coolandlovely.cart.increase', 'Increase quantity')}\n disabled={busy || line.quantity >= MAX_QUANTITY}\n onClick={() => updateItem.mutate({ id: line.id, quantity: line.quantity + 1 })}\n className=\"rounded-md border border-border-seam p-1.5 text-text-primary hover:bg-bg-sunken disabled:opacity-50\"\n >\n <Plus className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n <p className=\"w-24 text-right text-sm font-semibold tabular-nums text-text-primary\">\n {formatPrice(line.lineTotal, line.currency)}\n </p>\n <button\n type=\"button\"\n aria-label={tr('coolandlovely.cart.remove', 'Remove from cart')}\n disabled={busy}\n onClick={() => removeItem.mutate({ id: line.id })}\n className=\"rounded-md p-1.5 text-status-error-text hover:bg-status-error-bg-subtle disabled:opacity-50\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </button>\n </GlassCard>\n ))}\n {(updateItem.error || removeItem.error) && (\n <p className=\"text-sm text-status-error-text\">\n {(updateItem.error ?? removeItem.error)?.message}\n </p>\n )}\n </div>\n\n <GlassCard treatment=\"glass\" className=\"h-fit space-y-4 p-6\">\n <div className=\"flex items-baseline justify-between\">\n <span className=\"text-sm text-text-secondary\">\n {tr('coolandlovely.cart.subtotalItems', 'Subtotal ({{count}} items)', {\n count: data.itemCount,\n })}\n </span>\n <span\n className=\"text-xl font-bold tabular-nums text-text-primary\"\n data-testid=\"cart-subtotal\"\n >\n {formatPrice(data.subtotal, data.currency ?? 'USD')}\n </span>\n </div>\n <p className=\"text-xs text-text-secondary\">\n {tr('coolandlovely.cart.taxNote', 'Tax is calculated when you place the order.')}\n </p>\n {data.blockedReason && (\n <p className=\"text-sm text-status-error-text\">{data.blockedReason}</p>\n )}\n <div className=\"space-y-3 border-t border-border-seam pt-4\">\n <TextField\n id=\"coo-shipping-name\"\n label={tr('coolandlovely.checkout.shippingName', 'Full name')}\n value={shippingName}\n onChange={setShippingName}\n required\n />\n <TextAreaField\n id=\"coo-shipping-address\"\n label={tr('coolandlovely.checkout.shippingAddress', 'Shipping address')}\n value={shippingAddress}\n onChange={setShippingAddress}\n rows={3}\n required\n />\n <TextField\n id=\"coo-buyer-note\"\n label={tr('coolandlovely.checkout.note', 'Note for the brand (optional)')}\n value={buyerNote}\n onChange={setBuyerNote}\n />\n </div>\n {checkout.error && (\n <p className=\"text-sm text-status-error-text\">{checkout.error.message}</p>\n )}\n <button\n type=\"button\"\n disabled={!canSubmit || checkout.isPending}\n onClick={submit}\n className=\"inline-flex w-full items-center justify-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2.5 text-sm font-semibold text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {checkout.isPending && <Loader2 className=\"h-4 w-4 animate-spin\" />}\n {tr('coolandlovely.checkout.placeOrder', 'Place order')}\n </button>\n </GlassCard>\n </div>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creator Earnings Page (BOFF-3370)
|
|
3
|
+
* @module coolandlovely/pages/commerce
|
|
4
|
+
*
|
|
5
|
+
* A creator's look commissions: every piece bought from one of their published looks earns
|
|
6
|
+
* them a commission once the order is paid. Balances come from global-billing's earnings
|
|
7
|
+
* ledger (`cooMyCreatorEarningsSummary`); a creator can ask for a payout of the available
|
|
8
|
+
* balance (`cooRequestCreatorPayout`), which billing queues for payout review.
|
|
9
|
+
*/
|
|
10
|
+
export declare function CreatorEarningsPage(): import("react").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=CreatorEarningsPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CreatorEarningsPage.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/pages/commerce/CreatorEarningsPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAoBH,wBAAgB,mBAAmB,gCAsLlC"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { PageLayout as e } from "../../components/PageLayout.js";
|
|
2
|
+
import { MetricsCard as t } from "../../components/MetricsCard.js";
|
|
3
|
+
import { useTr as n } from "../../hooks/useTr.js";
|
|
4
|
+
import "../../hooks/index.js";
|
|
5
|
+
import { StatusBadge as r } from "../../components/StatusBadge.js";
|
|
6
|
+
import { ErrorView as i, LoadingView as a } from "../../components/StateViews.js";
|
|
7
|
+
import { formatDate as o, formatPrice as s } from "../../utils/formatters.js";
|
|
8
|
+
import { EmptyState as c } from "../../components/EmptyState.js";
|
|
9
|
+
import { TextField as l } from "../../components/Field.js";
|
|
10
|
+
import { useMyCreatorEarnings as u, useMyCreatorEarningsSummary as d, useRequestCreatorPayout as f } from "../../hooks/useCommerceApi.js";
|
|
11
|
+
import { useState as p } from "react";
|
|
12
|
+
import { Loader2 as m, Wallet as h } from "lucide-react";
|
|
13
|
+
import { jsx as g, jsxs as _ } from "react/jsx-runtime";
|
|
14
|
+
import { GlassCard as v } from "@burdenoff/fe-libs/ui";
|
|
15
|
+
//#region src/coolandlovely/pages/commerce/CreatorEarningsPage.tsx
|
|
16
|
+
function y() {
|
|
17
|
+
let y = n(), b = d(), x = u(), S = f(), [C, w] = p(""), T = y("coolandlovely.earnings.title", "Creator earnings");
|
|
18
|
+
if (b.isLoading || x.isLoading) return /* @__PURE__ */ g(e, {
|
|
19
|
+
title: T,
|
|
20
|
+
children: /* @__PURE__ */ g(a, {})
|
|
21
|
+
});
|
|
22
|
+
if (b.isError || x.isError || !b.data || !x.data) return /* @__PURE__ */ g(e, {
|
|
23
|
+
title: T,
|
|
24
|
+
children: /* @__PURE__ */ g(i, { onRetry: () => {
|
|
25
|
+
b.refetch(), x.refetch();
|
|
26
|
+
} })
|
|
27
|
+
});
|
|
28
|
+
let E = b.data, D = E.currency ?? "USD", O = Number(C), k = E.currency !== null && O > 0 && O <= E.availableAmount;
|
|
29
|
+
return /* @__PURE__ */ _(e, {
|
|
30
|
+
title: T,
|
|
31
|
+
description: y("coolandlovely.earnings.description", "You earn {{rate}}% of every piece bought from your looks. Commissions become available {{days}} days after payment.", {
|
|
32
|
+
rate: Math.round(E.commissionRate * 100),
|
|
33
|
+
days: E.holdDays
|
|
34
|
+
}),
|
|
35
|
+
children: [
|
|
36
|
+
/* @__PURE__ */ _("div", {
|
|
37
|
+
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
|
|
38
|
+
"data-testid": "earnings-summary",
|
|
39
|
+
children: [
|
|
40
|
+
/* @__PURE__ */ g(t, {
|
|
41
|
+
icon: /* @__PURE__ */ g(h, { className: "h-5 w-5" }),
|
|
42
|
+
label: y("coolandlovely.earnings.available", "Available"),
|
|
43
|
+
value: s(E.availableAmount, D)
|
|
44
|
+
}),
|
|
45
|
+
/* @__PURE__ */ g(t, {
|
|
46
|
+
icon: /* @__PURE__ */ g(h, { className: "h-5 w-5" }),
|
|
47
|
+
label: y("coolandlovely.earnings.pending", "In return window"),
|
|
48
|
+
value: s(E.pendingAmount, D)
|
|
49
|
+
}),
|
|
50
|
+
/* @__PURE__ */ g(t, {
|
|
51
|
+
icon: /* @__PURE__ */ g(h, { className: "h-5 w-5" }),
|
|
52
|
+
label: y("coolandlovely.earnings.reserved", "Payout requested"),
|
|
53
|
+
value: s(E.reservedAmount, D)
|
|
54
|
+
}),
|
|
55
|
+
/* @__PURE__ */ g(t, {
|
|
56
|
+
icon: /* @__PURE__ */ g(h, { className: "h-5 w-5" }),
|
|
57
|
+
label: y("coolandlovely.earnings.paid", "Paid out"),
|
|
58
|
+
value: s(E.paidAmount, D)
|
|
59
|
+
})
|
|
60
|
+
]
|
|
61
|
+
}),
|
|
62
|
+
!E.billingAvailable && /* @__PURE__ */ g("p", {
|
|
63
|
+
className: "mt-3 text-sm text-status-warning-text",
|
|
64
|
+
children: y("coolandlovely.earnings.billingUnavailable", "Balances could not be confirmed with billing just now; the figures above come from your commission history.")
|
|
65
|
+
}),
|
|
66
|
+
/* @__PURE__ */ _("div", {
|
|
67
|
+
className: "mt-6 grid grid-cols-1 gap-6 lg:grid-cols-3",
|
|
68
|
+
children: [/* @__PURE__ */ _("section", {
|
|
69
|
+
className: "lg:col-span-2",
|
|
70
|
+
children: [/* @__PURE__ */ g("h3", {
|
|
71
|
+
className: "mb-3 text-lg font-semibold text-text-primary",
|
|
72
|
+
children: y("coolandlovely.earnings.history", "Commission history")
|
|
73
|
+
}), x.data.items.length === 0 ? /* @__PURE__ */ g(c, {
|
|
74
|
+
icon: /* @__PURE__ */ g(h, { className: "h-8 w-8" }),
|
|
75
|
+
title: y("coolandlovely.earnings.emptyTitle", "No commissions yet"),
|
|
76
|
+
description: y("coolandlovely.earnings.emptyDescription", "Publish looks with catalogue pieces. When someone buys from your look, the commission shows up here.")
|
|
77
|
+
}) : /* @__PURE__ */ g("div", {
|
|
78
|
+
className: "overflow-x-auto rounded-xl border border-border-seam",
|
|
79
|
+
children: /* @__PURE__ */ _("table", {
|
|
80
|
+
className: "w-full text-sm",
|
|
81
|
+
children: [/* @__PURE__ */ g("thead", {
|
|
82
|
+
className: "bg-bg-sunken text-left text-xs uppercase tracking-wide text-text-secondary",
|
|
83
|
+
children: /* @__PURE__ */ _("tr", { children: [
|
|
84
|
+
/* @__PURE__ */ g("th", {
|
|
85
|
+
className: "px-4 py-2",
|
|
86
|
+
children: y("coolandlovely.earnings.order", "Order")
|
|
87
|
+
}),
|
|
88
|
+
/* @__PURE__ */ g("th", {
|
|
89
|
+
className: "px-4 py-2 text-right",
|
|
90
|
+
children: y("coolandlovely.earnings.sale", "Sale")
|
|
91
|
+
}),
|
|
92
|
+
/* @__PURE__ */ g("th", {
|
|
93
|
+
className: "px-4 py-2 text-right",
|
|
94
|
+
children: y("coolandlovely.earnings.commission", "Commission")
|
|
95
|
+
}),
|
|
96
|
+
/* @__PURE__ */ g("th", {
|
|
97
|
+
className: "px-4 py-2",
|
|
98
|
+
children: y("coolandlovely.earnings.availableOn", "Available on")
|
|
99
|
+
}),
|
|
100
|
+
/* @__PURE__ */ g("th", {
|
|
101
|
+
className: "px-4 py-2",
|
|
102
|
+
children: y("coolandlovely.earnings.ledger", "Ledger")
|
|
103
|
+
})
|
|
104
|
+
] })
|
|
105
|
+
}), /* @__PURE__ */ g("tbody", { children: x.data.items.map((e) => /* @__PURE__ */ _("tr", {
|
|
106
|
+
className: "border-t border-border-seam",
|
|
107
|
+
children: [
|
|
108
|
+
/* @__PURE__ */ g("td", {
|
|
109
|
+
className: "px-4 py-2 font-mono text-text-primary",
|
|
110
|
+
children: e.orderNumber ?? "—"
|
|
111
|
+
}),
|
|
112
|
+
/* @__PURE__ */ g("td", {
|
|
113
|
+
className: "px-4 py-2 text-right tabular-nums text-text-secondary",
|
|
114
|
+
children: s(e.saleAmount, e.currency)
|
|
115
|
+
}),
|
|
116
|
+
/* @__PURE__ */ g("td", {
|
|
117
|
+
className: "px-4 py-2 text-right font-semibold tabular-nums text-text-primary",
|
|
118
|
+
children: s(e.amount, e.currency)
|
|
119
|
+
}),
|
|
120
|
+
/* @__PURE__ */ g("td", {
|
|
121
|
+
className: "px-4 py-2 text-text-secondary",
|
|
122
|
+
children: o(e.availableAt, {
|
|
123
|
+
hour: void 0,
|
|
124
|
+
minute: void 0
|
|
125
|
+
})
|
|
126
|
+
}),
|
|
127
|
+
/* @__PURE__ */ g("td", {
|
|
128
|
+
className: "px-4 py-2",
|
|
129
|
+
children: /* @__PURE__ */ g(r, { status: e.billingSyncStatus })
|
|
130
|
+
})
|
|
131
|
+
]
|
|
132
|
+
}, e.id)) })]
|
|
133
|
+
})
|
|
134
|
+
})]
|
|
135
|
+
}), /* @__PURE__ */ _(v, {
|
|
136
|
+
treatment: "glass",
|
|
137
|
+
className: "h-fit space-y-4 p-6",
|
|
138
|
+
children: [
|
|
139
|
+
/* @__PURE__ */ g("h3", {
|
|
140
|
+
className: "text-base font-semibold text-text-primary",
|
|
141
|
+
children: y("coolandlovely.earnings.requestTitle", "Request a payout")
|
|
142
|
+
}),
|
|
143
|
+
/* @__PURE__ */ g("p", {
|
|
144
|
+
className: "text-sm text-text-secondary",
|
|
145
|
+
children: y("coolandlovely.earnings.requestHint", "Payouts are reviewed by the platform and sent to the payout account on your billing profile.")
|
|
146
|
+
}),
|
|
147
|
+
/* @__PURE__ */ g(l, {
|
|
148
|
+
id: "coo-payout-amount",
|
|
149
|
+
type: "number",
|
|
150
|
+
label: y("coolandlovely.earnings.amount", "Amount ({{currency}})", { currency: D }),
|
|
151
|
+
value: C,
|
|
152
|
+
onChange: w,
|
|
153
|
+
hint: y("coolandlovely.earnings.maxHint", "Up to {{amount}}", { amount: s(E.availableAmount, D) })
|
|
154
|
+
}),
|
|
155
|
+
S.error && /* @__PURE__ */ g("p", {
|
|
156
|
+
className: "text-sm text-status-error-text",
|
|
157
|
+
children: S.error.message
|
|
158
|
+
}),
|
|
159
|
+
S.data && /* @__PURE__ */ g("p", {
|
|
160
|
+
className: "text-sm text-status-success-text",
|
|
161
|
+
children: y("coolandlovely.earnings.requested", "Payout of {{amount}} requested ({{status}}).", {
|
|
162
|
+
amount: s(S.data.requestedAmount, S.data.currency),
|
|
163
|
+
status: S.data.status
|
|
164
|
+
})
|
|
165
|
+
}),
|
|
166
|
+
/* @__PURE__ */ _("button", {
|
|
167
|
+
type: "button",
|
|
168
|
+
disabled: !k || S.isPending,
|
|
169
|
+
onClick: () => S.mutate({
|
|
170
|
+
amount: O,
|
|
171
|
+
currency: D
|
|
172
|
+
}, { onSuccess: () => w("") }),
|
|
173
|
+
className: "inline-flex w-full items-center justify-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2.5 text-sm font-semibold text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-50",
|
|
174
|
+
children: [S.isPending && /* @__PURE__ */ g(m, { className: "h-4 w-4 animate-spin" }), y("coolandlovely.earnings.requestButton", "Request payout")]
|
|
175
|
+
})
|
|
176
|
+
]
|
|
177
|
+
})]
|
|
178
|
+
})
|
|
179
|
+
]
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
//#endregion
|
|
183
|
+
export { y as CreatorEarningsPage };
|
|
184
|
+
|
|
185
|
+
//# sourceMappingURL=CreatorEarningsPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CreatorEarningsPage.js","names":[],"sources":["../../../../src/coolandlovely/pages/commerce/CreatorEarningsPage.tsx"],"sourcesContent":["/**\n * Creator Earnings Page (BOFF-3370)\n * @module coolandlovely/pages/commerce\n *\n * A creator's look commissions: every piece bought from one of their published looks earns\n * them a commission once the order is paid. Balances come from global-billing's earnings\n * ledger (`cooMyCreatorEarningsSummary`); a creator can ask for a payout of the available\n * balance (`cooRequestCreatorPayout`), which billing queues for payout review.\n */\n\nimport { useState } from 'react';\nimport { Loader2, Wallet } from 'lucide-react';\nimport { GlassCard } from '@burdenoff/fe-libs/ui';\n\nimport { EmptyState } from '../../components/EmptyState';\nimport { TextField } from '../../components/Field';\nimport { MetricsCard } from '../../components/MetricsCard';\nimport { PageLayout } from '../../components/PageLayout';\nimport { ErrorView, LoadingView } from '../../components/StateViews';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { useTr } from '../../hooks';\nimport {\n useMyCreatorEarnings,\n useMyCreatorEarningsSummary,\n useRequestCreatorPayout,\n} from '../../hooks/useCommerceApi';\nimport { formatDate, formatPrice } from '../../utils/formatters';\n\nexport function CreatorEarningsPage() {\n const tr = useTr();\n const summary = useMyCreatorEarningsSummary();\n const earnings = useMyCreatorEarnings();\n const payout = useRequestCreatorPayout();\n const [amount, setAmount] = useState('');\n const title = tr('coolandlovely.earnings.title', 'Creator earnings');\n\n if (summary.isLoading || earnings.isLoading) {\n return (\n <PageLayout title={title}>\n <LoadingView />\n </PageLayout>\n );\n }\n if (summary.isError || earnings.isError || !summary.data || !earnings.data) {\n return (\n <PageLayout title={title}>\n <ErrorView\n onRetry={() => {\n void summary.refetch();\n void earnings.refetch();\n }}\n />\n </PageLayout>\n );\n }\n\n const s = summary.data;\n const currency = s.currency ?? 'USD';\n const requested = Number(amount);\n const canRequest = s.currency !== null && requested > 0 && requested <= s.availableAmount;\n\n return (\n <PageLayout\n title={title}\n description={tr(\n 'coolandlovely.earnings.description',\n 'You earn {{rate}}% of every piece bought from your looks. Commissions become available {{days}} days after payment.',\n { rate: Math.round(s.commissionRate * 100), days: s.holdDays }\n )}\n >\n <div\n className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\"\n data-testid=\"earnings-summary\"\n >\n <MetricsCard\n icon={<Wallet className=\"h-5 w-5\" />}\n label={tr('coolandlovely.earnings.available', 'Available')}\n value={formatPrice(s.availableAmount, currency)}\n />\n <MetricsCard\n icon={<Wallet className=\"h-5 w-5\" />}\n label={tr('coolandlovely.earnings.pending', 'In return window')}\n value={formatPrice(s.pendingAmount, currency)}\n />\n <MetricsCard\n icon={<Wallet className=\"h-5 w-5\" />}\n label={tr('coolandlovely.earnings.reserved', 'Payout requested')}\n value={formatPrice(s.reservedAmount, currency)}\n />\n <MetricsCard\n icon={<Wallet className=\"h-5 w-5\" />}\n label={tr('coolandlovely.earnings.paid', 'Paid out')}\n value={formatPrice(s.paidAmount, currency)}\n />\n </div>\n {!s.billingAvailable && (\n <p className=\"mt-3 text-sm text-status-warning-text\">\n {tr(\n 'coolandlovely.earnings.billingUnavailable',\n 'Balances could not be confirmed with billing just now; the figures above come from your commission history.'\n )}\n </p>\n )}\n\n <div className=\"mt-6 grid grid-cols-1 gap-6 lg:grid-cols-3\">\n <section className=\"lg:col-span-2\">\n <h3 className=\"mb-3 text-lg font-semibold text-text-primary\">\n {tr('coolandlovely.earnings.history', 'Commission history')}\n </h3>\n {earnings.data.items.length === 0 ? (\n <EmptyState\n icon={<Wallet className=\"h-8 w-8\" />}\n title={tr('coolandlovely.earnings.emptyTitle', 'No commissions yet')}\n description={tr(\n 'coolandlovely.earnings.emptyDescription',\n 'Publish looks with catalogue pieces. When someone buys from your look, the commission shows up here.'\n )}\n />\n ) : (\n <div className=\"overflow-x-auto rounded-xl border border-border-seam\">\n <table className=\"w-full text-sm\">\n <thead className=\"bg-bg-sunken text-left text-xs uppercase tracking-wide text-text-secondary\">\n <tr>\n <th className=\"px-4 py-2\">{tr('coolandlovely.earnings.order', 'Order')}</th>\n <th className=\"px-4 py-2 text-right\">\n {tr('coolandlovely.earnings.sale', 'Sale')}\n </th>\n <th className=\"px-4 py-2 text-right\">\n {tr('coolandlovely.earnings.commission', 'Commission')}\n </th>\n <th className=\"px-4 py-2\">\n {tr('coolandlovely.earnings.availableOn', 'Available on')}\n </th>\n <th className=\"px-4 py-2\">{tr('coolandlovely.earnings.ledger', 'Ledger')}</th>\n </tr>\n </thead>\n <tbody>\n {earnings.data.items.map((earning) => (\n <tr key={earning.id} className=\"border-t border-border-seam\">\n <td className=\"px-4 py-2 font-mono text-text-primary\">\n {earning.orderNumber ?? '—'}\n </td>\n <td className=\"px-4 py-2 text-right tabular-nums text-text-secondary\">\n {formatPrice(earning.saleAmount, earning.currency)}\n </td>\n <td className=\"px-4 py-2 text-right font-semibold tabular-nums text-text-primary\">\n {formatPrice(earning.amount, earning.currency)}\n </td>\n <td className=\"px-4 py-2 text-text-secondary\">\n {formatDate(earning.availableAt, { hour: undefined, minute: undefined })}\n </td>\n <td className=\"px-4 py-2\">\n <StatusBadge status={earning.billingSyncStatus} />\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </section>\n\n <GlassCard treatment=\"glass\" className=\"h-fit space-y-4 p-6\">\n <h3 className=\"text-base font-semibold text-text-primary\">\n {tr('coolandlovely.earnings.requestTitle', 'Request a payout')}\n </h3>\n <p className=\"text-sm text-text-secondary\">\n {tr(\n 'coolandlovely.earnings.requestHint',\n 'Payouts are reviewed by the platform and sent to the payout account on your billing profile.'\n )}\n </p>\n <TextField\n id=\"coo-payout-amount\"\n type=\"number\"\n label={tr('coolandlovely.earnings.amount', 'Amount ({{currency}})', { currency })}\n value={amount}\n onChange={setAmount}\n hint={tr('coolandlovely.earnings.maxHint', 'Up to {{amount}}', {\n amount: formatPrice(s.availableAmount, currency),\n })}\n />\n {payout.error && <p className=\"text-sm text-status-error-text\">{payout.error.message}</p>}\n {payout.data && (\n <p className=\"text-sm text-status-success-text\">\n {tr(\n 'coolandlovely.earnings.requested',\n 'Payout of {{amount}} requested ({{status}}).',\n {\n amount: formatPrice(payout.data.requestedAmount, payout.data.currency),\n status: payout.data.status,\n }\n )}\n </p>\n )}\n <button\n type=\"button\"\n disabled={!canRequest || payout.isPending}\n onClick={() =>\n payout.mutate({ amount: requested, currency }, { onSuccess: () => setAmount('') })\n }\n className=\"inline-flex w-full items-center justify-center gap-2 rounded-lg bg-action-primary-bg px-4 py-2.5 text-sm font-semibold text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-50\"\n >\n {payout.isPending && <Loader2 className=\"h-4 w-4 animate-spin\" />}\n {tr('coolandlovely.earnings.requestButton', 'Request payout')}\n </button>\n </GlassCard>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* My Orders + Order detail (BOFF-3370)
|
|
3
|
+
* @module coolandlovely/pages/commerce
|
|
4
|
+
*
|
|
5
|
+
* The shopper's own orders (`cooMyOrders` / `cooMyOrder`). An unpaid order can be paid
|
|
6
|
+
* (`cooResumeOrderPayment` re-uses its billing order), re-checked against billing
|
|
7
|
+
* (`cooSyncOrderPayment`) or cancelled (`cooCancelOrder`).
|
|
8
|
+
*/
|
|
9
|
+
export declare function OrdersPage(): import("react").JSX.Element;
|
|
10
|
+
export declare function OrderDetailPage(): import("react").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=OrdersPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OrdersPage.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/pages/commerce/OrdersPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAgDH,wBAAgB,UAAU,gCAwEzB;AAED,wBAAgB,eAAe,gCAgL9B"}
|