@ticketboothapp/booking 1.2.178 → 1.2.179
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/package.json
CHANGED
|
@@ -160,7 +160,14 @@ export function AddOnsSection({
|
|
|
160
160
|
const price = (addOn.price ?? 0) + (variant.priceAdjustment ?? 0);
|
|
161
161
|
return (
|
|
162
162
|
<div key={variant.id} className="flex flex-wrap items-center gap-3 p-3 bg-stone-50 rounded-lg">
|
|
163
|
-
<span className="
|
|
163
|
+
<span className="min-w-0 flex-1">
|
|
164
|
+
<span className="block text-sm text-stone-800">{variant.label}</span>
|
|
165
|
+
{variant.description?.trim() ? (
|
|
166
|
+
<span className="mt-0.5 block text-xs leading-snug text-stone-500">
|
|
167
|
+
{variant.description.trim()}
|
|
168
|
+
</span>
|
|
169
|
+
) : null}
|
|
170
|
+
</span>
|
|
164
171
|
<span className="text-sm text-stone-500 shrink-0">
|
|
165
172
|
{suppressPrices ? '—' : `${formatCurrencyAmount(price, currency, locale as 'en' | 'fr')} ea`}
|
|
166
173
|
</span>
|
|
@@ -260,7 +267,14 @@ export function AddOnsSection({
|
|
|
260
267
|
: 'border-stone-200 bg-stone-50 hover:border-stone-300'
|
|
261
268
|
}`}
|
|
262
269
|
>
|
|
263
|
-
<span className="
|
|
270
|
+
<span className="min-w-0 flex-1">
|
|
271
|
+
<span className="block text-sm font-medium text-stone-800">{variant.label}</span>
|
|
272
|
+
{variant.description?.trim() ? (
|
|
273
|
+
<span className="mt-0.5 block text-xs font-normal leading-snug text-stone-500">
|
|
274
|
+
{variant.description.trim()}
|
|
275
|
+
</span>
|
|
276
|
+
) : null}
|
|
277
|
+
</span>
|
|
264
278
|
<span className="text-sm text-stone-500">
|
|
265
279
|
{suppressPrices ? '—' : `+${formatCurrencyAmount(price, currency, locale as 'en' | 'fr')}`}
|
|
266
280
|
</span>
|
|
@@ -45,7 +45,7 @@ export function canUseMealDrinkSelector(addOn: AddOn): boolean {
|
|
|
45
45
|
* into step1 (meal types) and step2 (drink types) for a 2-step selection UI.
|
|
46
46
|
*/
|
|
47
47
|
function parseTwoStepVariants(variants: AddOnVariant[]): {
|
|
48
|
-
step1Options: { id: string; label: string }[];
|
|
48
|
+
step1Options: { id: string; label: string; description?: string }[];
|
|
49
49
|
step2Options: { id: string; label: string }[];
|
|
50
50
|
getVariantId: (step1Id: string, step2Id: string) => string | null;
|
|
51
51
|
} | null {
|
|
@@ -55,6 +55,7 @@ function parseTwoStepVariants(variants: AddOnVariant[]): {
|
|
|
55
55
|
const step1Options: { id: string; label: string }[] = [];
|
|
56
56
|
const step2Options: { id: string; label: string }[] = [];
|
|
57
57
|
const variantByKey = new Map<string, string>();
|
|
58
|
+
const step1Descriptions = new Map<string, string[]>();
|
|
58
59
|
|
|
59
60
|
for (const v of variants) {
|
|
60
61
|
const labelParts = v.label.split(/\s+\+\s+/);
|
|
@@ -76,6 +77,10 @@ function parseTwoStepVariants(variants: AddOnVariant[]): {
|
|
|
76
77
|
if (!step1Options.some((o) => o.id === step1Id)) {
|
|
77
78
|
step1Options.push({ id: step1Id, label: step1Label });
|
|
78
79
|
}
|
|
80
|
+
step1Descriptions.set(step1Id, [
|
|
81
|
+
...(step1Descriptions.get(step1Id) ?? []),
|
|
82
|
+
v.description?.trim() ?? '',
|
|
83
|
+
]);
|
|
79
84
|
if (!step2Options.some((o) => o.id === step2Id)) {
|
|
80
85
|
step2Options.push({ id: step2Id, label: step2Label });
|
|
81
86
|
}
|
|
@@ -85,9 +90,17 @@ function parseTwoStepVariants(variants: AddOnVariant[]): {
|
|
|
85
90
|
const getVariantId = (s1: string, s2: string) => variantByKey.get(`${s1}:${s2}`) ?? null;
|
|
86
91
|
|
|
87
92
|
if (step1Options.length < 2 || step2Options.length < 2) return null;
|
|
93
|
+
const describedStep1Options = step1Options.map((option) => {
|
|
94
|
+
const descriptions = step1Descriptions.get(option.id) ?? [];
|
|
95
|
+
const uniqueDescriptions = [...new Set(descriptions.filter(Boolean))];
|
|
96
|
+
const description = descriptions.length > 0 && descriptions.every(Boolean) && uniqueDescriptions.length === 1
|
|
97
|
+
? uniqueDescriptions[0]
|
|
98
|
+
: undefined;
|
|
99
|
+
return { ...option, description };
|
|
100
|
+
});
|
|
88
101
|
// Sort step2 so "water" comes first when reducing meals (cap water at total, rest to other)
|
|
89
102
|
const sortedStep2 = [...step2Options].sort((a, b) => (a.id === 'water' ? -1 : b.id === 'water' ? 1 : 0));
|
|
90
|
-
return { step1Options, step2Options: sortedStep2, getVariantId };
|
|
103
|
+
return { step1Options: describedStep1Options, step2Options: sortedStep2, getVariantId };
|
|
91
104
|
}
|
|
92
105
|
|
|
93
106
|
/**
|
|
@@ -243,7 +256,14 @@ export function MealDrinkAddOnSelector({
|
|
|
243
256
|
const canDecrementTotal = totalStep1 > minimumTotal;
|
|
244
257
|
return (
|
|
245
258
|
<div key={opt.id} className="flex flex-wrap items-center gap-3 p-3 bg-stone-50 rounded-lg">
|
|
246
|
-
<span className="
|
|
259
|
+
<span className="min-w-0 flex-1">
|
|
260
|
+
<span className="block font-medium text-stone-800">{opt.label}</span>
|
|
261
|
+
{opt.description ? (
|
|
262
|
+
<span className="mt-0.5 block text-xs font-normal leading-snug text-stone-500">
|
|
263
|
+
{opt.description}
|
|
264
|
+
</span>
|
|
265
|
+
) : null}
|
|
266
|
+
</span>
|
|
247
267
|
<span className="text-sm text-stone-500 shrink-0">
|
|
248
268
|
{suppressPrices ? '—' : `${formatCurrencyAmount(price, currency, locale)} ea`}
|
|
249
269
|
</span>
|