@resira/ui 0.4.3 → 0.4.5
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/index.cjs +97 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +114 -1
- package/dist/index.d.ts +114 -1
- package/dist/index.js +96 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -652,6 +652,101 @@ function useCheckoutSession(token) {
|
|
|
652
652
|
}, [client, token]);
|
|
653
653
|
return { session, loading, error, errorCode };
|
|
654
654
|
}
|
|
655
|
+
function formatPriceCentsUtil(cents, currency) {
|
|
656
|
+
return new Intl.NumberFormat("default", { style: "currency", currency }).format(cents / 100);
|
|
657
|
+
}
|
|
658
|
+
function formatDurationUtil(minutes) {
|
|
659
|
+
if (minutes < 60) return `${minutes} min`;
|
|
660
|
+
const h = Math.floor(minutes / 60);
|
|
661
|
+
const m = minutes % 60;
|
|
662
|
+
return m > 0 ? `${h}h ${m}m` : `${h}h`;
|
|
663
|
+
}
|
|
664
|
+
function enrichProduct(product) {
|
|
665
|
+
const currency = product.currency ?? "EUR";
|
|
666
|
+
const options = [];
|
|
667
|
+
if (product.durationPricing?.length) {
|
|
668
|
+
for (const dp of product.durationPricing) {
|
|
669
|
+
options.push({
|
|
670
|
+
durationMinutes: dp.durationMinutes,
|
|
671
|
+
durationLabel: formatDurationUtil(dp.durationMinutes),
|
|
672
|
+
priceCents: dp.priceCents,
|
|
673
|
+
priceFormatted: formatPriceCentsUtil(dp.priceCents, currency)
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
} else {
|
|
677
|
+
options.push({
|
|
678
|
+
durationMinutes: product.durationMinutes,
|
|
679
|
+
durationLabel: formatDurationUtil(product.durationMinutes),
|
|
680
|
+
priceCents: product.priceCents,
|
|
681
|
+
priceFormatted: formatPriceCentsUtil(product.priceCents, currency)
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
const lowestPriceCents = Math.min(...options.map((o) => o.priceCents));
|
|
685
|
+
return {
|
|
686
|
+
id: product.id,
|
|
687
|
+
name: product.name,
|
|
688
|
+
description: product.description,
|
|
689
|
+
imageUrl: product.imageUrl,
|
|
690
|
+
currency,
|
|
691
|
+
active: product.active,
|
|
692
|
+
pricingModel: product.pricingModel,
|
|
693
|
+
priceCents: product.priceCents,
|
|
694
|
+
priceFormatted: formatPriceCentsUtil(product.priceCents, currency),
|
|
695
|
+
lowestPriceCents,
|
|
696
|
+
lowestPriceFormatted: formatPriceCentsUtil(lowestPriceCents, currency),
|
|
697
|
+
hasMultipleOptions: options.length > 1,
|
|
698
|
+
durationMinutes: product.durationMinutes,
|
|
699
|
+
durationLabel: formatDurationUtil(product.durationMinutes),
|
|
700
|
+
options,
|
|
701
|
+
maxPartySize: product.maxPartySize,
|
|
702
|
+
equipmentIds: product.equipmentIds,
|
|
703
|
+
equipmentNames: product.equipmentNames,
|
|
704
|
+
serviceColor: product.serviceColor,
|
|
705
|
+
sortOrder: product.sortOrder,
|
|
706
|
+
raw: product
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
function useServices() {
|
|
710
|
+
const { client } = useResira();
|
|
711
|
+
const [services, setServices] = react.useState([]);
|
|
712
|
+
const [loading, setLoading] = react.useState(true);
|
|
713
|
+
const [error, setError] = react.useState(null);
|
|
714
|
+
const [fetchCount, setFetchCount] = react.useState(0);
|
|
715
|
+
react.useEffect(() => {
|
|
716
|
+
let cancelled = false;
|
|
717
|
+
setLoading(true);
|
|
718
|
+
setError(null);
|
|
719
|
+
async function load() {
|
|
720
|
+
try {
|
|
721
|
+
const data = await client.listProducts();
|
|
722
|
+
if (!cancelled) {
|
|
723
|
+
setServices((data.products ?? []).map(enrichProduct));
|
|
724
|
+
}
|
|
725
|
+
} catch (err) {
|
|
726
|
+
if (!cancelled) {
|
|
727
|
+
setError(err instanceof Error ? err.message : "Failed to load services");
|
|
728
|
+
}
|
|
729
|
+
} finally {
|
|
730
|
+
if (!cancelled) setLoading(false);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
load();
|
|
734
|
+
return () => {
|
|
735
|
+
cancelled = true;
|
|
736
|
+
};
|
|
737
|
+
}, [client, fetchCount]);
|
|
738
|
+
const refetch = react.useCallback(() => setFetchCount((c) => c + 1), []);
|
|
739
|
+
return { services, loading, error, refetch };
|
|
740
|
+
}
|
|
741
|
+
async function fetchServices(apiKey, opts) {
|
|
742
|
+
const { Resira: Resira2 } = await import('@resira/sdk');
|
|
743
|
+
const client = new Resira2({
|
|
744
|
+
apiKey,
|
|
745
|
+
...opts?.baseUrl ? { baseUrl: opts.baseUrl } : {}
|
|
746
|
+
});
|
|
747
|
+
const data = await client.listProducts();
|
|
748
|
+
return (data.products ?? []).map(enrichProduct);
|
|
749
|
+
}
|
|
655
750
|
var defaultSize = 20;
|
|
656
751
|
function CalendarIcon({ size = defaultSize, className }) {
|
|
657
752
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -4260,6 +4355,7 @@ exports.UsersIcon = UsersIcon;
|
|
|
4260
4355
|
exports.ViewfinderIcon = ViewfinderIcon;
|
|
4261
4356
|
exports.WaiverConsent = WaiverConsent;
|
|
4262
4357
|
exports.XIcon = XIcon;
|
|
4358
|
+
exports.fetchServices = fetchServices;
|
|
4263
4359
|
exports.resolveTheme = resolveTheme;
|
|
4264
4360
|
exports.themeToCSS = themeToCSS;
|
|
4265
4361
|
exports.useAvailability = useAvailability;
|
|
@@ -4271,6 +4367,7 @@ exports.useProducts = useProducts;
|
|
|
4271
4367
|
exports.useReservation = useReservation;
|
|
4272
4368
|
exports.useResira = useResira;
|
|
4273
4369
|
exports.useResources = useResources;
|
|
4370
|
+
exports.useServices = useServices;
|
|
4274
4371
|
exports.validateGuestForm = validateGuestForm;
|
|
4275
4372
|
//# sourceMappingURL=index.cjs.map
|
|
4276
4373
|
//# sourceMappingURL=index.cjs.map
|