@burdenoff/microfe-coolandlovely 2026.1101.8 → 2026.1102.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -0
- package/dist/coolandlovely/CoolAndLovelyRoot.d.ts.map +1 -1
- package/dist/coolandlovely/CoolAndLovelyRoot.js +8 -0
- package/dist/coolandlovely/CoolAndLovelyRoot.js.map +1 -1
- package/dist/coolandlovely/CoolAndLovelyRoutes.d.ts.map +1 -1
- package/dist/coolandlovely/CoolAndLovelyRoutes.js +20 -16
- package/dist/coolandlovely/CoolAndLovelyRoutes.js.map +1 -1
- package/dist/coolandlovely/components/WardrobeItemCard.d.ts +2 -1
- package/dist/coolandlovely/components/WardrobeItemCard.d.ts.map +1 -1
- package/dist/coolandlovely/components/WardrobeItemCard.js +4 -3
- package/dist/coolandlovely/components/WardrobeItemCard.js.map +1 -1
- package/dist/coolandlovely/components/prices/BestPriceBadge.d.ts +7 -0
- package/dist/coolandlovely/components/prices/BestPriceBadge.d.ts.map +1 -0
- package/dist/coolandlovely/components/prices/BestPriceBadge.js +22 -0
- package/dist/coolandlovely/components/prices/BestPriceBadge.js.map +1 -0
- package/dist/coolandlovely/components/prices/LookbookPriceBoard.d.ts +10 -0
- package/dist/coolandlovely/components/prices/LookbookPriceBoard.d.ts.map +1 -0
- package/dist/coolandlovely/components/prices/LookbookPriceBoard.js +120 -0
- package/dist/coolandlovely/components/prices/LookbookPriceBoard.js.map +1 -0
- package/dist/coolandlovely/components/prices/PriceComparison.d.ts +5 -0
- package/dist/coolandlovely/components/prices/PriceComparison.d.ts.map +1 -0
- package/dist/coolandlovely/components/prices/PriceComparison.js +95 -0
- package/dist/coolandlovely/components/prices/PriceComparison.js.map +1 -0
- package/dist/coolandlovely/components/prices/PriceCurrencySelect.d.ts +6 -0
- package/dist/coolandlovely/components/prices/PriceCurrencySelect.d.ts.map +1 -0
- package/dist/coolandlovely/components/prices/PriceCurrencySelect.js +38 -0
- package/dist/coolandlovely/components/prices/PriceCurrencySelect.js.map +1 -0
- package/dist/coolandlovely/components/prices/PricePanel.d.ts +6 -0
- package/dist/coolandlovely/components/prices/PricePanel.d.ts.map +1 -0
- package/dist/coolandlovely/components/prices/PricePanel.js +105 -0
- package/dist/coolandlovely/components/prices/PricePanel.js.map +1 -0
- package/dist/coolandlovely/components/prices/PriceWatchDisclosure.d.ts +2 -0
- package/dist/coolandlovely/components/prices/PriceWatchDisclosure.d.ts.map +1 -0
- package/dist/coolandlovely/components/prices/PriceWatchDisclosure.js +28 -0
- package/dist/coolandlovely/components/prices/PriceWatchDisclosure.js.map +1 -0
- package/dist/coolandlovely/components/prices/PriceWatchForm.d.ts +5 -0
- package/dist/coolandlovely/components/prices/PriceWatchForm.d.ts.map +1 -0
- package/dist/coolandlovely/components/prices/PriceWatchForm.js +89 -0
- package/dist/coolandlovely/components/prices/PriceWatchForm.js.map +1 -0
- package/dist/coolandlovely/components/prices/PriceWatches.d.ts +3 -0
- package/dist/coolandlovely/components/prices/PriceWatches.d.ts.map +1 -0
- package/dist/coolandlovely/components/prices/PriceWatches.js +189 -0
- package/dist/coolandlovely/components/prices/PriceWatches.js.map +1 -0
- package/dist/coolandlovely/components/prices/RetailerOfferLink.d.ts +6 -0
- package/dist/coolandlovely/components/prices/RetailerOfferLink.d.ts.map +1 -0
- package/dist/coolandlovely/components/prices/RetailerOfferLink.js +28 -0
- package/dist/coolandlovely/components/prices/RetailerOfferLink.js.map +1 -0
- package/dist/coolandlovely/components/prices/money.d.ts +6 -0
- package/dist/coolandlovely/components/prices/money.d.ts.map +1 -0
- package/dist/coolandlovely/components/prices/money.js +42 -0
- package/dist/coolandlovely/components/prices/money.js.map +1 -0
- package/dist/coolandlovely/hooks/useContextNavigation.d.ts +3 -0
- package/dist/coolandlovely/hooks/useContextNavigation.d.ts.map +1 -0
- package/dist/coolandlovely/hooks/useContextNavigation.js +31 -0
- package/dist/coolandlovely/hooks/useContextNavigation.js.map +1 -0
- package/dist/coolandlovely/hooks/useCoolAndLovelyApi.d.ts.map +1 -1
- package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js +1 -1
- package/dist/coolandlovely/hooks/useCoolAndLovelyApi.js.map +1 -1
- package/dist/coolandlovely/hooks/useCreatorMarketplace.d.ts +118 -0
- package/dist/coolandlovely/hooks/useCreatorMarketplace.d.ts.map +1 -0
- package/dist/coolandlovely/hooks/useCreatorMarketplace.js +120 -0
- package/dist/coolandlovely/hooks/useCreatorMarketplace.js.map +1 -0
- package/dist/coolandlovely/hooks/usePriceApi.d.ts +57 -0
- package/dist/coolandlovely/hooks/usePriceApi.d.ts.map +1 -0
- package/dist/coolandlovely/hooks/usePriceApi.js +111 -0
- package/dist/coolandlovely/hooks/usePriceApi.js.map +1 -0
- package/dist/coolandlovely/pages/collaborations/CollaborationDetailPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/collaborations/CollaborationDetailPage.js +139 -121
- package/dist/coolandlovely/pages/collaborations/CollaborationDetailPage.js.map +1 -1
- package/dist/coolandlovely/pages/collaborations/CollaborationFormPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/collaborations/CollaborationFormPage.js +140 -137
- package/dist/coolandlovely/pages/collaborations/CollaborationFormPage.js.map +1 -1
- package/dist/coolandlovely/pages/collaborations/CollaborationsListPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/collaborations/CollaborationsListPage.js +104 -95
- package/dist/coolandlovely/pages/collaborations/CollaborationsListPage.js.map +1 -1
- package/dist/coolandlovely/pages/commerce/CreatorEarningsPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/commerce/CreatorEarningsPage.js +49 -40
- package/dist/coolandlovely/pages/commerce/CreatorEarningsPage.js.map +1 -1
- package/dist/coolandlovely/pages/items/StoreListedPieceView.d.ts.map +1 -1
- package/dist/coolandlovely/pages/items/StoreListedPieceView.js +130 -123
- package/dist/coolandlovely/pages/items/StoreListedPieceView.js.map +1 -1
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.js +241 -230
- package/dist/coolandlovely/pages/items/StyleItemDetailPage.js.map +1 -1
- package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.js +64 -119
- package/dist/coolandlovely/pages/lookbooks/LookbookDetailPage.js.map +1 -1
- package/dist/coolandlovely/pages/marketplace/CreatorMarketplacePage.d.ts +2 -0
- package/dist/coolandlovely/pages/marketplace/CreatorMarketplacePage.d.ts.map +1 -0
- package/dist/coolandlovely/pages/marketplace/CreatorMarketplacePage.js +714 -0
- package/dist/coolandlovely/pages/marketplace/CreatorMarketplacePage.js.map +1 -0
- package/dist/coolandlovely/pages/profile/StyleProfilePage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/profile/StyleProfilePage.js +214 -209
- package/dist/coolandlovely/pages/profile/StyleProfilePage.js.map +1 -1
- package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.d.ts.map +1 -1
- package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.js +83 -49
- package/dist/coolandlovely/pages/wardrobe/WardrobeListPage.js.map +1 -1
- package/dist/coolandlovely/types/index.d.ts +5 -0
- package/dist/coolandlovely/types/index.d.ts.map +1 -1
- package/dist/generated/wspace-operations.d.ts +931 -2
- package/dist/generated/wspace-operations.d.ts.map +1 -1
- package/dist/generated/wspace-operations.js +221 -1
- package/dist/generated/wspace-operations.js.map +1 -1
- package/dist/generated/wspace-types.d.ts +539 -1
- package/dist/generated/wspace-types.d.ts.map +1 -1
- package/dist/generated/wspace-types.js +14 -0
- package/dist/generated/wspace-types.js.map +1 -0
- package/package.json +4 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PriceComparison.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/components/prices/PriceComparison.tsx"],"names":[],"mappings":"AAKA,wBAAgB,eAAe,CAAC,EAC9B,WAAW,EACX,QAAQ,GACT,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB,+BAmFA"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { usePriceDetail as e } from "../../hooks/usePriceApi.js";
|
|
2
|
+
import { formatRetailerPrice as t } from "./money.js";
|
|
3
|
+
import { RetailerOfferLink as n } from "./RetailerOfferLink.js";
|
|
4
|
+
import { useState as r } from "react";
|
|
5
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
6
|
+
//#region src/coolandlovely/components/prices/PriceComparison.tsx
|
|
7
|
+
function o({ styleItemId: o, currency: s }) {
|
|
8
|
+
let [c] = r(() => {
|
|
9
|
+
let e = /* @__PURE__ */ new Date();
|
|
10
|
+
return {
|
|
11
|
+
end: e.toISOString(),
|
|
12
|
+
start: (/* @__PURE__ */ new Date(e.getTime() - 30 * 864e5)).toISOString()
|
|
13
|
+
};
|
|
14
|
+
}), l = e(o, s, c.start, c.end, !0);
|
|
15
|
+
return l.isPending ? /* @__PURE__ */ i("p", {
|
|
16
|
+
role: "status",
|
|
17
|
+
className: "text-sm text-text-secondary",
|
|
18
|
+
children: "Loading comparison…"
|
|
19
|
+
}) : l.isError ? /* @__PURE__ */ a("p", {
|
|
20
|
+
role: "alert",
|
|
21
|
+
className: "text-sm text-status-error-text",
|
|
22
|
+
children: [
|
|
23
|
+
"Comparison could not be loaded.",
|
|
24
|
+
" ",
|
|
25
|
+
/* @__PURE__ */ i("button", {
|
|
26
|
+
type: "button",
|
|
27
|
+
className: "underline",
|
|
28
|
+
onClick: () => void l.refetch(),
|
|
29
|
+
children: "Retry comparison"
|
|
30
|
+
})
|
|
31
|
+
]
|
|
32
|
+
}) : /* @__PURE__ */ a("div", {
|
|
33
|
+
className: "space-y-4",
|
|
34
|
+
children: [
|
|
35
|
+
!l.data?.cooComparePrices.length && /* @__PURE__ */ i("p", {
|
|
36
|
+
className: "text-sm text-text-secondary",
|
|
37
|
+
children: "No current retailer offers in this currency."
|
|
38
|
+
}),
|
|
39
|
+
/* @__PURE__ */ i("ul", {
|
|
40
|
+
className: "space-y-2",
|
|
41
|
+
children: l.data?.cooComparePrices.map((e) => /* @__PURE__ */ a("li", {
|
|
42
|
+
className: "flex flex-wrap items-center justify-between gap-2 rounded-lg border border-border-seam p-3",
|
|
43
|
+
children: [/* @__PURE__ */ a("div", { children: [/* @__PURE__ */ i("p", {
|
|
44
|
+
className: "font-medium text-text-primary",
|
|
45
|
+
children: e.retailerName
|
|
46
|
+
}), /* @__PURE__ */ a("p", {
|
|
47
|
+
className: "text-xs text-text-secondary",
|
|
48
|
+
children: ["Observed ", new Date(e.observedAt).toLocaleString()]
|
|
49
|
+
})] }), /* @__PURE__ */ i(n, {
|
|
50
|
+
url: e.productUrl,
|
|
51
|
+
priceMinor: e.priceMinor,
|
|
52
|
+
currency: e.currency
|
|
53
|
+
})]
|
|
54
|
+
}, e.id))
|
|
55
|
+
}),
|
|
56
|
+
/* @__PURE__ */ i("h3", {
|
|
57
|
+
className: "font-semibold text-text-primary",
|
|
58
|
+
children: "Observed daily minimum · last 30 days"
|
|
59
|
+
}),
|
|
60
|
+
/* @__PURE__ */ i("p", {
|
|
61
|
+
className: "text-xs text-text-secondary",
|
|
62
|
+
children: "Only recorded in-stock observations are shown. Missing days are not estimates; this does not include taxes or delivery charges."
|
|
63
|
+
}),
|
|
64
|
+
l.data?.cooPriceHistory.length ? /* @__PURE__ */ i("div", {
|
|
65
|
+
className: "max-h-60 overflow-auto",
|
|
66
|
+
children: /* @__PURE__ */ a("table", {
|
|
67
|
+
className: "w-full text-left text-sm",
|
|
68
|
+
children: [/* @__PURE__ */ i("thead", { children: /* @__PURE__ */ a("tr", { children: [/* @__PURE__ */ i("th", {
|
|
69
|
+
className: "p-2 text-text-secondary",
|
|
70
|
+
scope: "col",
|
|
71
|
+
children: "UTC day"
|
|
72
|
+
}), /* @__PURE__ */ i("th", {
|
|
73
|
+
className: "p-2 text-text-secondary",
|
|
74
|
+
scope: "col",
|
|
75
|
+
children: "Lowest observed"
|
|
76
|
+
})] }) }), /* @__PURE__ */ i("tbody", { children: l.data.cooPriceHistory.map((e) => /* @__PURE__ */ a("tr", { children: [/* @__PURE__ */ i("th", {
|
|
77
|
+
className: "p-2 font-normal text-text-primary",
|
|
78
|
+
scope: "row",
|
|
79
|
+
children: e.day
|
|
80
|
+
}), /* @__PURE__ */ i("td", {
|
|
81
|
+
className: "p-2 text-text-primary",
|
|
82
|
+
children: t(e.lowestPriceMinor, s)
|
|
83
|
+
})] }, e.day)) })]
|
|
84
|
+
})
|
|
85
|
+
}) : /* @__PURE__ */ i("p", {
|
|
86
|
+
className: "text-sm text-text-secondary",
|
|
87
|
+
children: "No observed history in this period."
|
|
88
|
+
})
|
|
89
|
+
]
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
export { o as PriceComparison };
|
|
94
|
+
|
|
95
|
+
//# sourceMappingURL=PriceComparison.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PriceComparison.js","names":[],"sources":["../../../../src/coolandlovely/components/prices/PriceComparison.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { usePriceDetail } from '../../hooks/usePriceApi';\nimport { formatRetailerPrice } from './money';\nimport { RetailerOfferLink } from './RetailerOfferLink';\n\nexport function PriceComparison({\n styleItemId,\n currency,\n}: {\n styleItemId: string;\n currency: string;\n}) {\n const [period] = useState(() => {\n const end = new Date();\n return { end: end.toISOString(), start: new Date(end.getTime() - 30 * 86400000).toISOString() };\n });\n const query = usePriceDetail(styleItemId, currency, period.start, period.end, true);\n if (query.isPending)\n return (\n <p role=\"status\" className=\"text-sm text-text-secondary\">\n Loading comparison…\n </p>\n );\n if (query.isError)\n return (\n <p role=\"alert\" className=\"text-sm text-status-error-text\">\n Comparison could not be loaded.{' '}\n <button type=\"button\" className=\"underline\" onClick={() => void query.refetch()}>\n Retry comparison\n </button>\n </p>\n );\n return (\n <div className=\"space-y-4\">\n {!query.data?.cooComparePrices.length && (\n <p className=\"text-sm text-text-secondary\">No current retailer offers in this currency.</p>\n )}\n <ul className=\"space-y-2\">\n {query.data?.cooComparePrices.map((offer) => (\n <li\n key={offer.id}\n className=\"flex flex-wrap items-center justify-between gap-2 rounded-lg border border-border-seam p-3\"\n >\n <div>\n <p className=\"font-medium text-text-primary\">{offer.retailerName}</p>\n <p className=\"text-xs text-text-secondary\">\n Observed {new Date(offer.observedAt).toLocaleString()}\n </p>\n </div>\n <RetailerOfferLink\n url={offer.productUrl}\n priceMinor={offer.priceMinor}\n currency={offer.currency}\n />\n </li>\n ))}\n </ul>\n <h3 className=\"font-semibold text-text-primary\">Observed daily minimum · last 30 days</h3>\n <p className=\"text-xs text-text-secondary\">\n Only recorded in-stock observations are shown. Missing days are not estimates; this does not\n include taxes or delivery charges.\n </p>\n {query.data?.cooPriceHistory.length ? (\n <div className=\"max-h-60 overflow-auto\">\n <table className=\"w-full text-left text-sm\">\n <thead>\n <tr>\n <th className=\"p-2 text-text-secondary\" scope=\"col\">\n UTC day\n </th>\n <th className=\"p-2 text-text-secondary\" scope=\"col\">\n Lowest observed\n </th>\n </tr>\n </thead>\n <tbody>\n {query.data.cooPriceHistory.map((day) => (\n <tr key={day.day}>\n <th className=\"p-2 font-normal text-text-primary\" scope=\"row\">\n {day.day}\n </th>\n <td className=\"p-2 text-text-primary\">\n {formatRetailerPrice(day.lowestPriceMinor, currency)}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n ) : (\n <p className=\"text-sm text-text-secondary\">No observed history in this period.</p>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;AAKA,SAAgB,EAAgB,EAC9B,gBACA,eAIC;CACD,IAAM,CAAC,KAAU,QAAe;EAC9B,IAAM,oBAAM,IAAI,KAAK;EACrB,OAAO;GAAE,KAAK,EAAI,YAAY;GAAG,wBAAO,IAAI,KAAK,EAAI,QAAQ,IAAI,KAAK,KAAQ,EAAA,CAAE,YAAY;EAAE;CAChG,CAAC,GACK,IAAQ,EAAe,GAAa,GAAU,EAAO,OAAO,EAAO,KAAK,EAAI;CAgBlF,OAfI,EAAM,YAEN,kBAAC,KAAD;EAAG,MAAK;EAAS,WAAU;YAA8B;CAEtD,CAAA,IAEH,EAAM,UAEN,kBAAC,KAAD;EAAG,MAAK;EAAQ,WAAU;YAA1B;GAA2D;GACzB;GAChC,kBAAC,UAAD;IAAQ,MAAK;IAAS,WAAU;IAAY,eAAe,KAAK,EAAM,QAAQ;cAAG;GAEzE,CAAA;EACP;MAGL,kBAAC,OAAD;EAAK,WAAU;YAAf;GACG,CAAC,EAAM,MAAM,iBAAiB,UAC7B,kBAAC,KAAD;IAAG,WAAU;cAA8B;GAA+C,CAAA;GAE5F,kBAAC,MAAD;IAAI,WAAU;cACX,EAAM,MAAM,iBAAiB,KAAK,MACjC,kBAAC,MAAD;KAEE,WAAU;eAFZ,CAIE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;MAAG,WAAU;gBAAiC,EAAM;KAAgB,CAAA,GACpE,kBAAC,KAAD;MAAG,WAAU;gBAAb,CAA2C,aAC/B,IAAI,KAAK,EAAM,UAAU,CAAC,CAAC,eAAe,CACnD;OACA,EAAA,CAAA,GACL,kBAAC,GAAD;MACE,KAAK,EAAM;MACX,YAAY,EAAM;MAClB,UAAU,EAAM;KACjB,CAAA,CACC;OAdG,EAAM,EAcT,CACL;GACC,CAAA;GACJ,kBAAC,MAAD;IAAI,WAAU;cAAkC;GAAyC,CAAA;GACzF,kBAAC,KAAD;IAAG,WAAU;cAA8B;GAGxC,CAAA;GACF,EAAM,MAAM,gBAAgB,SAC3B,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,SAAD;KAAO,WAAU;eAAjB,CACE,kBAAC,SAAD,EAAA,UACE,kBAAC,MAAD,EAAA,UAAA,CACE,kBAAC,MAAD;MAAI,WAAU;MAA0B,OAAM;gBAAM;KAEhD,CAAA,GACJ,kBAAC,MAAD;MAAI,WAAU;MAA0B,OAAM;gBAAM;KAEhD,CAAA,CACF,EAAA,CAAA,EACC,CAAA,GACP,kBAAC,SAAD,EAAA,UACG,EAAM,KAAK,gBAAgB,KAAK,MAC/B,kBAAC,MAAD,EAAA,UAAA,CACE,kBAAC,MAAD;MAAI,WAAU;MAAoC,OAAM;gBACrD,EAAI;KACH,CAAA,GACJ,kBAAC,MAAD;MAAI,WAAU;gBACX,EAAoB,EAAI,kBAAkB,CAAQ;KACjD,CAAA,CACF,EAAA,GAPK,EAAI,GAOT,CACL,EACI,CAAA,CACF;;GACJ,CAAA,IAEL,kBAAC,KAAD;IAAG,WAAU;cAA8B;GAAsC,CAAA;EAEhF;;AAET"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PriceCurrencySelect.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/components/prices/PriceCurrencySelect.tsx"],"names":[],"mappings":"AAEA,wBAAgB,mBAAmB,CAAC,EAClC,KAAK,EACL,QAAQ,EACR,UAAe,GAChB,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB,+BAwBA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useId as e } from "react";
|
|
2
|
+
import { jsx as t, jsxs as n } from "react/jsx-runtime";
|
|
3
|
+
//#region src/coolandlovely/components/prices/PriceCurrencySelect.tsx
|
|
4
|
+
function r({ value: r, onChange: i, currencies: a = [] }) {
|
|
5
|
+
let o = e(), s = [.../* @__PURE__ */ new Set([
|
|
6
|
+
r,
|
|
7
|
+
...a,
|
|
8
|
+
"USD",
|
|
9
|
+
"INR",
|
|
10
|
+
"EUR",
|
|
11
|
+
"GBP",
|
|
12
|
+
"JPY",
|
|
13
|
+
"BHD",
|
|
14
|
+
"CAD",
|
|
15
|
+
"AUD"
|
|
16
|
+
])];
|
|
17
|
+
return /* @__PURE__ */ n("div", {
|
|
18
|
+
className: "mb-3 flex flex-wrap items-center gap-2",
|
|
19
|
+
children: [/* @__PURE__ */ t("label", {
|
|
20
|
+
htmlFor: o,
|
|
21
|
+
className: "text-sm text-text-secondary",
|
|
22
|
+
children: "Retailer quote currency"
|
|
23
|
+
}), /* @__PURE__ */ t("select", {
|
|
24
|
+
id: o,
|
|
25
|
+
value: r,
|
|
26
|
+
onChange: (e) => i(e.target.value),
|
|
27
|
+
className: "rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary",
|
|
28
|
+
children: s.map((e) => /* @__PURE__ */ t("option", {
|
|
29
|
+
value: e,
|
|
30
|
+
children: e
|
|
31
|
+
}, e))
|
|
32
|
+
})]
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { r as PriceCurrencySelect };
|
|
37
|
+
|
|
38
|
+
//# sourceMappingURL=PriceCurrencySelect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PriceCurrencySelect.js","names":[],"sources":["../../../../src/coolandlovely/components/prices/PriceCurrencySelect.tsx"],"sourcesContent":["import { useId } from 'react';\n\nexport function PriceCurrencySelect({\n value,\n onChange,\n currencies = [],\n}: {\n value: string;\n onChange: (currency: string) => void;\n currencies?: string[];\n}) {\n const id = useId();\n const options = [\n ...new Set([value, ...currencies, 'USD', 'INR', 'EUR', 'GBP', 'JPY', 'BHD', 'CAD', 'AUD']),\n ];\n return (\n <div className=\"mb-3 flex flex-wrap items-center gap-2\">\n <label htmlFor={id} className=\"text-sm text-text-secondary\">\n Retailer quote currency\n </label>\n <select\n id={id}\n value={value}\n onChange={(event) => onChange(event.target.value)}\n className=\"rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n >\n {options.map((currency) => (\n <option key={currency} value={currency}>\n {currency}\n </option>\n ))}\n </select>\n </div>\n );\n}\n"],"mappings":";;;AAEA,SAAgB,EAAoB,EAClC,UACA,aACA,gBAAa,CAAC,KAKb;CACD,IAAM,IAAK,EAAM,GACX,IAAU,CACd,mBAAG,IAAI,IAAI;EAAC;EAAO,GAAG;EAAY;EAAO;EAAO;EAAO;EAAO;EAAO;EAAO;EAAO;CAAK,CAAC,CAC3F;CACA,OACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,SAAD;GAAO,SAAS;GAAI,WAAU;aAA8B;EAErD,CAAA,GACP,kBAAC,UAAD;GACM;GACG;GACP,WAAW,MAAU,EAAS,EAAM,OAAO,KAAK;GAChD,WAAU;aAET,EAAQ,KAAK,MACZ,kBAAC,UAAD;IAAuB,OAAO;cAC3B;GACK,GAFK,CAEL,CACT;EACK,CAAA,CACL;;AAET"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Parent keys by active security context and item so shopper input state cannot leak. */
|
|
2
|
+
export declare function PricePanel({ styleItemId, currency: initialCurrency, }: {
|
|
3
|
+
styleItemId: string;
|
|
4
|
+
currency: string;
|
|
5
|
+
}): import("react").JSX.Element;
|
|
6
|
+
//# sourceMappingURL=PricePanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PricePanel.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/components/prices/PricePanel.tsx"],"names":[],"mappings":"AASA,0FAA0F;AAC1F,wBAAgB,UAAU,CAAC,EACzB,WAAW,EACX,QAAQ,EAAE,eAAe,GAC1B,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB,+BAoEA"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { useBestPrices as e } from "../../hooks/usePriceApi.js";
|
|
2
|
+
import { formatRetailerPrice as t } from "./money.js";
|
|
3
|
+
import { PriceComparison as n } from "./PriceComparison.js";
|
|
4
|
+
import { PriceWatchForm as r } from "./PriceWatchForm.js";
|
|
5
|
+
import { useId as i, useState as a } from "react";
|
|
6
|
+
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
7
|
+
//#region src/coolandlovely/components/prices/PricePanel.tsx
|
|
8
|
+
var c = "rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken disabled:opacity-50";
|
|
9
|
+
function l({ styleItemId: l, currency: u }) {
|
|
10
|
+
let [d, f] = a(u), [p, m] = a(!1), h = i(), g = e([l], d), _ = g.data?.[0];
|
|
11
|
+
return /* @__PURE__ */ s("section", {
|
|
12
|
+
className: "space-y-4 rounded-xl border border-border-seam bg-bg-surface p-4",
|
|
13
|
+
"aria-label": "Retailer prices and alerts",
|
|
14
|
+
children: [
|
|
15
|
+
/* @__PURE__ */ s("div", {
|
|
16
|
+
className: "flex flex-wrap items-center justify-between gap-3",
|
|
17
|
+
children: [/* @__PURE__ */ o("h2", {
|
|
18
|
+
className: "text-lg font-semibold text-text-primary",
|
|
19
|
+
children: "Retailer prices"
|
|
20
|
+
}), /* @__PURE__ */ s("div", {
|
|
21
|
+
className: "flex items-center gap-2",
|
|
22
|
+
children: [/* @__PURE__ */ o("label", {
|
|
23
|
+
htmlFor: h,
|
|
24
|
+
className: "text-sm text-text-secondary",
|
|
25
|
+
children: "Currency"
|
|
26
|
+
}), /* @__PURE__ */ o("select", {
|
|
27
|
+
id: h,
|
|
28
|
+
className: "rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary",
|
|
29
|
+
value: d,
|
|
30
|
+
onChange: (e) => f(e.target.value),
|
|
31
|
+
children: [.../* @__PURE__ */ new Set([
|
|
32
|
+
u,
|
|
33
|
+
"USD",
|
|
34
|
+
"INR",
|
|
35
|
+
"EUR",
|
|
36
|
+
"GBP",
|
|
37
|
+
"JPY"
|
|
38
|
+
])].map((e) => /* @__PURE__ */ o("option", {
|
|
39
|
+
value: e,
|
|
40
|
+
children: e
|
|
41
|
+
}, e))
|
|
42
|
+
})]
|
|
43
|
+
})]
|
|
44
|
+
}),
|
|
45
|
+
/* @__PURE__ */ o("p", {
|
|
46
|
+
className: "text-sm text-text-secondary",
|
|
47
|
+
children: "Approved sources and exact product matches only. Prices are not converted. Confirm current price, shipping and stock at the retailer."
|
|
48
|
+
}),
|
|
49
|
+
g.isPending ? /* @__PURE__ */ o("p", {
|
|
50
|
+
role: "status",
|
|
51
|
+
className: "text-sm text-text-secondary",
|
|
52
|
+
children: "Checking current offers…"
|
|
53
|
+
}) : g.isError ? /* @__PURE__ */ s("p", {
|
|
54
|
+
role: "alert",
|
|
55
|
+
className: "text-sm text-status-error-text",
|
|
56
|
+
children: [
|
|
57
|
+
"Prices could not be loaded.",
|
|
58
|
+
" ",
|
|
59
|
+
/* @__PURE__ */ o("button", {
|
|
60
|
+
type: "button",
|
|
61
|
+
className: c,
|
|
62
|
+
onClick: () => void g.refetch(),
|
|
63
|
+
children: "Retry prices"
|
|
64
|
+
})
|
|
65
|
+
]
|
|
66
|
+
}) : _?.lowestPriceMinor == null ? /* @__PURE__ */ s("p", {
|
|
67
|
+
className: "text-sm text-text-secondary",
|
|
68
|
+
children: [
|
|
69
|
+
"No fresh in-stock retailer offers in ",
|
|
70
|
+
d,
|
|
71
|
+
"."
|
|
72
|
+
]
|
|
73
|
+
}) : /* @__PURE__ */ s("p", {
|
|
74
|
+
className: "font-semibold text-text-primary",
|
|
75
|
+
children: [
|
|
76
|
+
"From ",
|
|
77
|
+
t(_.lowestPriceMinor, _.currency),
|
|
78
|
+
" across",
|
|
79
|
+
" ",
|
|
80
|
+
_.offerCount,
|
|
81
|
+
" current offers"
|
|
82
|
+
]
|
|
83
|
+
}),
|
|
84
|
+
/* @__PURE__ */ o("button", {
|
|
85
|
+
type: "button",
|
|
86
|
+
className: c,
|
|
87
|
+
"aria-expanded": p,
|
|
88
|
+
onClick: () => m((e) => !e),
|
|
89
|
+
children: p ? "Hide comparison" : "Compare offers and history"
|
|
90
|
+
}),
|
|
91
|
+
p && /* @__PURE__ */ o(n, {
|
|
92
|
+
styleItemId: l,
|
|
93
|
+
currency: d
|
|
94
|
+
}),
|
|
95
|
+
/* @__PURE__ */ o(r, {
|
|
96
|
+
styleItemId: l,
|
|
97
|
+
currency: d
|
|
98
|
+
}, d)
|
|
99
|
+
]
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
//#endregion
|
|
103
|
+
export { l as PricePanel };
|
|
104
|
+
|
|
105
|
+
//# sourceMappingURL=PricePanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PricePanel.js","names":[],"sources":["../../../../src/coolandlovely/components/prices/PricePanel.tsx"],"sourcesContent":["import { useId, useState } from 'react';\nimport { useBestPrices } from '../../hooks/usePriceApi';\nimport { formatRetailerPrice } from './money';\nimport { PriceComparison } from './PriceComparison';\nimport { PriceWatchForm } from './PriceWatchForm';\n\nconst buttonClass =\n 'rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken disabled:opacity-50';\n\n/** Parent keys by active security context and item so shopper input state cannot leak. */\nexport function PricePanel({\n styleItemId,\n currency: initialCurrency,\n}: {\n styleItemId: string;\n currency: string;\n}) {\n const [currency, setCurrency] = useState(initialCurrency);\n const [expanded, setExpanded] = useState(false);\n const currencyId = useId();\n const best = useBestPrices([styleItemId], currency);\n const summary = best.data?.[0];\n return (\n <section\n className=\"space-y-4 rounded-xl border border-border-seam bg-bg-surface p-4\"\n aria-label=\"Retailer prices and alerts\"\n >\n <div className=\"flex flex-wrap items-center justify-between gap-3\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Retailer prices</h2>\n <div className=\"flex items-center gap-2\">\n <label htmlFor={currencyId} className=\"text-sm text-text-secondary\">\n Currency\n </label>\n <select\n id={currencyId}\n className=\"rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n value={currency}\n onChange={(event) => setCurrency(event.target.value)}\n >\n {[...new Set([initialCurrency, 'USD', 'INR', 'EUR', 'GBP', 'JPY'])].map((code) => (\n <option key={code} value={code}>\n {code}\n </option>\n ))}\n </select>\n </div>\n </div>\n <p className=\"text-sm text-text-secondary\">\n Approved sources and exact product matches only. Prices are not converted. Confirm current\n price, shipping and stock at the retailer.\n </p>\n {best.isPending ? (\n <p role=\"status\" className=\"text-sm text-text-secondary\">\n Checking current offers…\n </p>\n ) : best.isError ? (\n <p role=\"alert\" className=\"text-sm text-status-error-text\">\n Prices could not be loaded.{' '}\n <button type=\"button\" className={buttonClass} onClick={() => void best.refetch()}>\n Retry prices\n </button>\n </p>\n ) : summary?.lowestPriceMinor != null ? (\n <p className=\"font-semibold text-text-primary\">\n From {formatRetailerPrice(summary.lowestPriceMinor, summary.currency)} across{' '}\n {summary.offerCount} current offers\n </p>\n ) : (\n <p className=\"text-sm text-text-secondary\">\n No fresh in-stock retailer offers in {currency}.\n </p>\n )}\n <button\n type=\"button\"\n className={buttonClass}\n aria-expanded={expanded}\n onClick={() => setExpanded((value) => !value)}\n >\n {expanded ? 'Hide comparison' : 'Compare offers and history'}\n </button>\n {expanded && <PriceComparison styleItemId={styleItemId} currency={currency} />}\n <PriceWatchForm key={currency} styleItemId={styleItemId} currency={currency} />\n </section>\n );\n}\n"],"mappings":";;;;;;;AAMA,IAAM,IACJ;AAGF,SAAgB,EAAW,EACzB,gBACA,UAAU,KAIT;CACD,IAAM,CAAC,GAAU,KAAe,EAAS,CAAe,GAClD,CAAC,GAAU,KAAe,EAAS,EAAK,GACxC,IAAa,EAAM,GACnB,IAAO,EAAc,CAAC,CAAW,GAAG,CAAQ,GAC5C,IAAU,EAAK,OAAO;CAC5B,OACE,kBAAC,WAAD;EACE,WAAU;EACV,cAAW;YAFb;GAIE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAA0C;IAAmB,CAAA,GAC3E,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,SAAD;MAAO,SAAS;MAAY,WAAU;gBAA8B;KAE7D,CAAA,GACP,kBAAC,UAAD;MACE,IAAI;MACJ,WAAU;MACV,OAAO;MACP,WAAW,MAAU,EAAY,EAAM,OAAO,KAAK;gBAElD,CAAC,mBAAG,IAAI,IAAI;OAAC;OAAiB;OAAO;OAAO;OAAO;OAAO;MAAK,CAAC,CAAC,CAAC,CAAC,KAAK,MACvE,kBAAC,UAAD;OAAmB,OAAO;iBACvB;MACK,GAFK,CAEL,CACT;KACK,CAAA,CACL;MACF;;GACL,kBAAC,KAAD;IAAG,WAAU;cAA8B;GAGxC,CAAA;GACF,EAAK,YACJ,kBAAC,KAAD;IAAG,MAAK;IAAS,WAAU;cAA8B;GAEtD,CAAA,IACD,EAAK,UACP,kBAAC,KAAD;IAAG,MAAK;IAAQ,WAAU;cAA1B;KAA2D;KAC7B;KAC5B,kBAAC,UAAD;MAAQ,MAAK;MAAS,WAAW;MAAa,eAAe,KAAK,EAAK,QAAQ;gBAAG;KAE1E,CAAA;IACP;QACD,GAAS,oBAAoB,OAM/B,kBAAC,KAAD;IAAG,WAAU;cAAb;KAA2C;KACH;KAAS;IAC9C;QAPH,kBAAC,KAAD;IAAG,WAAU;cAAb;KAA+C;KACvC,EAAoB,EAAQ,kBAAkB,EAAQ,QAAQ;KAAE;KAAQ;KAC7E,EAAQ;KAAW;IACnB;;GAML,kBAAC,UAAD;IACE,MAAK;IACL,WAAW;IACX,iBAAe;IACf,eAAe,GAAa,MAAU,CAAC,CAAK;cAE3C,IAAW,oBAAoB;GAC1B,CAAA;GACP,KAAY,kBAAC,GAAD;IAA8B;IAAuB;GAAW,CAAA;GAC7E,kBAAC,GAAD;IAA4C;IAAuB;GAAW,GAAzD,CAAyD;EACvE;;AAEb"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PriceWatchDisclosure.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/components/prices/PriceWatchDisclosure.tsx"],"names":[],"mappings":"AAMA,wBAAgB,oBAAoB,gCAyBnC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Suspense as e, lazy as t, useState as n } from "react";
|
|
2
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
3
|
+
//#region src/coolandlovely/components/prices/PriceWatchDisclosure.tsx
|
|
4
|
+
var a = t(() => import("./PriceWatches.js").then((e) => ({ default: e.PriceWatches })));
|
|
5
|
+
function o() {
|
|
6
|
+
let [t, o] = n(!1);
|
|
7
|
+
return /* @__PURE__ */ i("div", {
|
|
8
|
+
className: "my-6 space-y-3",
|
|
9
|
+
children: [/* @__PURE__ */ r("button", {
|
|
10
|
+
type: "button",
|
|
11
|
+
"aria-expanded": t,
|
|
12
|
+
className: "rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken",
|
|
13
|
+
onClick: () => o((e) => !e),
|
|
14
|
+
children: "Manage my price watches"
|
|
15
|
+
}), t && /* @__PURE__ */ r(e, {
|
|
16
|
+
fallback: /* @__PURE__ */ r("p", {
|
|
17
|
+
role: "status",
|
|
18
|
+
className: "text-sm text-text-secondary",
|
|
19
|
+
children: "Loading price watches…"
|
|
20
|
+
}),
|
|
21
|
+
children: /* @__PURE__ */ r(a, {})
|
|
22
|
+
})]
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { o as PriceWatchDisclosure };
|
|
27
|
+
|
|
28
|
+
//# sourceMappingURL=PriceWatchDisclosure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PriceWatchDisclosure.js","names":[],"sources":["../../../../src/coolandlovely/components/prices/PriceWatchDisclosure.tsx"],"sourcesContent":["import { lazy, Suspense, useState } from 'react';\n\nconst PriceWatches = lazy(() =>\n import('./PriceWatches').then((module) => ({ default: module.PriceWatches }))\n);\n\nexport function PriceWatchDisclosure() {\n const [expanded, setExpanded] = useState(false);\n return (\n <div className=\"my-6 space-y-3\">\n <button\n type=\"button\"\n aria-expanded={expanded}\n className=\"rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken\"\n onClick={() => setExpanded((value) => !value)}\n >\n Manage my price watches\n </button>\n {expanded && (\n <Suspense\n fallback={\n <p role=\"status\" className=\"text-sm text-text-secondary\">\n Loading price watches…\n </p>\n }\n >\n <PriceWatches />\n </Suspense>\n )}\n </div>\n );\n}\n"],"mappings":";;;AAEA,IAAM,IAAe,QACnB,OAAO,oBAAiB,CAAC,MAAM,OAAY,EAAE,SAAS,EAAO,aAAa,EAAE,CAC9E;AAEA,SAAgB,IAAuB;CACrC,IAAM,CAAC,GAAU,KAAe,EAAS,EAAK;CAC9C,OACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CACE,kBAAC,UAAD;GACE,MAAK;GACL,iBAAe;GACf,WAAU;GACV,eAAe,GAAa,MAAU,CAAC,CAAK;aAC7C;EAEO,CAAA,GACP,KACC,kBAAC,GAAD;GACE,UACE,kBAAC,KAAD;IAAG,MAAK;IAAS,WAAU;cAA8B;GAEtD,CAAA;aAGL,kBAAC,GAAD,CAAe,CAAA;EACP,CAAA,CAET;;AAET"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PriceWatchForm.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/components/prices/PriceWatchForm.tsx"],"names":[],"mappings":"AAQA,wBAAgB,cAAc,CAAC,EAC7B,WAAW,EACX,QAAQ,GACT,EAAE;IACD,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB,+BA2EA"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { usePriceWatchAction as e } from "../../hooks/usePriceApi.js";
|
|
2
|
+
import { retailerTargetExample as t, retailerTargetMinor as n } from "./money.js";
|
|
3
|
+
import { CooPriceAlertKind as r } from "../../../generated/wspace-types.js";
|
|
4
|
+
import { useId as i, useState as a } from "react";
|
|
5
|
+
import { jsx as o, jsxs as s } from "react/jsx-runtime";
|
|
6
|
+
//#region src/coolandlovely/components/prices/PriceWatchForm.tsx
|
|
7
|
+
var c = "rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken disabled:opacity-50";
|
|
8
|
+
function l({ styleItemId: l, currency: u }) {
|
|
9
|
+
let [d, f] = a(""), [p, m] = a(""), [h, g] = a(""), _ = i(), v = e(), y = async (e) => {
|
|
10
|
+
g(""), m("");
|
|
11
|
+
try {
|
|
12
|
+
let t = e === r.PriceDrop && d ? n(d, u) : null;
|
|
13
|
+
await v.mutateAsync({
|
|
14
|
+
kind: "save",
|
|
15
|
+
input: {
|
|
16
|
+
styleItemId: l,
|
|
17
|
+
currency: u,
|
|
18
|
+
kind: e,
|
|
19
|
+
targetPriceMinor: t
|
|
20
|
+
}
|
|
21
|
+
}), m(e === r.PriceDrop ? "Price watch saved. Monitoring starts after an initial check." : "Stock watch saved. You will be notified when fresh reports show a return from out of stock.");
|
|
22
|
+
} catch (e) {
|
|
23
|
+
g(e instanceof Error ? e.message : "The price watch could not be saved.");
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
return /* @__PURE__ */ s("div", {
|
|
27
|
+
className: "space-y-3 border-t border-border-seam pt-4",
|
|
28
|
+
children: [
|
|
29
|
+
/* @__PURE__ */ o("h3", {
|
|
30
|
+
className: "font-semibold text-text-primary",
|
|
31
|
+
children: "Watch this piece"
|
|
32
|
+
}),
|
|
33
|
+
/* @__PURE__ */ o("p", {
|
|
34
|
+
className: "text-sm text-text-secondary",
|
|
35
|
+
children: "New watches start with an initial check. Alerts need fresh retailer data and apply to future changes."
|
|
36
|
+
}),
|
|
37
|
+
/* @__PURE__ */ s("div", {
|
|
38
|
+
className: "flex flex-wrap items-end gap-2",
|
|
39
|
+
children: [
|
|
40
|
+
/* @__PURE__ */ s("label", {
|
|
41
|
+
className: "flex flex-col gap-1 text-sm text-text-secondary",
|
|
42
|
+
htmlFor: _,
|
|
43
|
+
children: [
|
|
44
|
+
"Future target in ",
|
|
45
|
+
u,
|
|
46
|
+
" (optional)",
|
|
47
|
+
/* @__PURE__ */ o("input", {
|
|
48
|
+
id: _,
|
|
49
|
+
inputMode: "decimal",
|
|
50
|
+
className: "rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary",
|
|
51
|
+
value: d,
|
|
52
|
+
onChange: (e) => f(e.target.value),
|
|
53
|
+
placeholder: t(u)
|
|
54
|
+
})
|
|
55
|
+
]
|
|
56
|
+
}),
|
|
57
|
+
/* @__PURE__ */ o("button", {
|
|
58
|
+
type: "button",
|
|
59
|
+
className: c,
|
|
60
|
+
disabled: v.isPending,
|
|
61
|
+
onClick: () => void y(r.PriceDrop),
|
|
62
|
+
children: "Watch price drops"
|
|
63
|
+
}),
|
|
64
|
+
/* @__PURE__ */ o("button", {
|
|
65
|
+
type: "button",
|
|
66
|
+
className: c,
|
|
67
|
+
disabled: v.isPending,
|
|
68
|
+
onClick: () => void y(r.BackInStock),
|
|
69
|
+
children: "Watch restocks"
|
|
70
|
+
})
|
|
71
|
+
]
|
|
72
|
+
}),
|
|
73
|
+
p && /* @__PURE__ */ o("p", {
|
|
74
|
+
role: "status",
|
|
75
|
+
className: "text-sm text-status-success-text",
|
|
76
|
+
children: p
|
|
77
|
+
}),
|
|
78
|
+
h && /* @__PURE__ */ o("p", {
|
|
79
|
+
role: "alert",
|
|
80
|
+
className: "text-sm text-status-error-text",
|
|
81
|
+
children: h
|
|
82
|
+
})
|
|
83
|
+
]
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
//#endregion
|
|
87
|
+
export { l as PriceWatchForm };
|
|
88
|
+
|
|
89
|
+
//# sourceMappingURL=PriceWatchForm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PriceWatchForm.js","names":[],"sources":["../../../../src/coolandlovely/components/prices/PriceWatchForm.tsx"],"sourcesContent":["import { useId, useState } from 'react';\nimport { CooPriceAlertKind } from '../../../generated/wspace-types';\nimport { usePriceWatchAction } from '../../hooks/usePriceApi';\nimport { retailerTargetExample, retailerTargetMinor } from './money';\n\nconst buttonClass =\n 'rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary hover:bg-bg-sunken disabled:opacity-50';\n\nexport function PriceWatchForm({\n styleItemId,\n currency,\n}: {\n styleItemId: string;\n currency: string;\n}) {\n const [target, setTarget] = useState('');\n const [message, setMessage] = useState('');\n const [inputError, setInputError] = useState('');\n const targetId = useId();\n const action = usePriceWatchAction();\n const save = async (kind: CooPriceAlertKind) => {\n setInputError('');\n setMessage('');\n try {\n const targetPriceMinor =\n kind === CooPriceAlertKind.PriceDrop && target\n ? retailerTargetMinor(target, currency)\n : null;\n await action.mutateAsync({\n kind: 'save',\n input: { styleItemId, currency, kind, targetPriceMinor },\n });\n setMessage(\n kind === CooPriceAlertKind.PriceDrop\n ? 'Price watch saved. Monitoring starts after an initial check.'\n : 'Stock watch saved. You will be notified when fresh reports show a return from out of stock.'\n );\n } catch (error) {\n setInputError(error instanceof Error ? error.message : 'The price watch could not be saved.');\n }\n };\n return (\n <div className=\"space-y-3 border-t border-border-seam pt-4\">\n <h3 className=\"font-semibold text-text-primary\">Watch this piece</h3>\n <p className=\"text-sm text-text-secondary\">\n New watches start with an initial check. Alerts need fresh retailer data and apply to future\n changes.\n </p>\n <div className=\"flex flex-wrap items-end gap-2\">\n <label className=\"flex flex-col gap-1 text-sm text-text-secondary\" htmlFor={targetId}>\n Future target in {currency} (optional)\n <input\n id={targetId}\n inputMode=\"decimal\"\n className=\"rounded-lg border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary\"\n value={target}\n onChange={(event) => setTarget(event.target.value)}\n placeholder={retailerTargetExample(currency)}\n />\n </label>\n <button\n type=\"button\"\n className={buttonClass}\n disabled={action.isPending}\n onClick={() => void save(CooPriceAlertKind.PriceDrop)}\n >\n Watch price drops\n </button>\n <button\n type=\"button\"\n className={buttonClass}\n disabled={action.isPending}\n onClick={() => void save(CooPriceAlertKind.BackInStock)}\n >\n Watch restocks\n </button>\n </div>\n {message && (\n <p role=\"status\" className=\"text-sm text-status-success-text\">\n {message}\n </p>\n )}\n {inputError && (\n <p role=\"alert\" className=\"text-sm text-status-error-text\">\n {inputError}\n </p>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;AAKA,IAAM,IACJ;AAEF,SAAgB,EAAe,EAC7B,gBACA,eAIC;CACD,IAAM,CAAC,GAAQ,KAAa,EAAS,EAAE,GACjC,CAAC,GAAS,KAAc,EAAS,EAAE,GACnC,CAAC,GAAY,KAAiB,EAAS,EAAE,GACzC,IAAW,EAAM,GACjB,IAAS,EAAoB,GAC7B,IAAO,OAAO,MAA4B;EAE9C,AADA,EAAc,EAAE,GAChB,EAAW,EAAE;EACb,IAAI;GACF,IAAM,IACJ,MAAS,EAAkB,aAAa,IACpC,EAAoB,GAAQ,CAAQ,IACpC;GAKN,AAJA,MAAM,EAAO,YAAY;IACvB,MAAM;IACN,OAAO;KAAE;KAAa;KAAU;KAAM;IAAiB;GACzD,CAAC,GACD,EACE,MAAS,EAAkB,YACvB,iEACA,6FACN;EACF,SAAS,GAAO;GACd,EAAc,aAAiB,QAAQ,EAAM,UAAU,qCAAqC;EAC9F;CACF;CACA,OACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,MAAD;IAAI,WAAU;cAAkC;GAAoB,CAAA;GACpE,kBAAC,KAAD;IAAG,WAAU;cAA8B;GAGxC,CAAA;GACH,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,SAAD;MAAO,WAAU;MAAkD,SAAS;gBAA5E;OAAsF;OAClE;OAAS;OAC3B,kBAAC,SAAD;QACE,IAAI;QACJ,WAAU;QACV,WAAU;QACV,OAAO;QACP,WAAW,MAAU,EAAU,EAAM,OAAO,KAAK;QACjD,aAAa,EAAsB,CAAQ;OAC5C,CAAA;MACI;;KACP,kBAAC,UAAD;MACE,MAAK;MACL,WAAW;MACX,UAAU,EAAO;MACjB,eAAe,KAAK,EAAK,EAAkB,SAAS;gBACrD;KAEO,CAAA;KACR,kBAAC,UAAD;MACE,MAAK;MACL,WAAW;MACX,UAAU,EAAO;MACjB,eAAe,KAAK,EAAK,EAAkB,WAAW;gBACvD;KAEO,CAAA;IACL;;GACJ,KACC,kBAAC,KAAD;IAAG,MAAK;IAAS,WAAU;cACxB;GACA,CAAA;GAEJ,KACC,kBAAC,KAAD;IAAG,MAAK;IAAQ,WAAU;cACvB;GACA,CAAA;EAEF;;AAET"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PriceWatches.d.ts","sourceRoot":"","sources":["../../../../src/coolandlovely/components/prices/PriceWatches.tsx"],"names":[],"mappings":"AAgFA,gGAAgG;AAChG,wBAAgB,YAAY,gCAiH3B"}
|