@escapenavigator/hooks 2.2.8 → 2.2.9
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.
|
@@ -135,10 +135,14 @@ export type PlayersAndVariationPickerProps = {
|
|
|
135
135
|
hidePriceHints?: boolean;
|
|
136
136
|
/**
|
|
137
137
|
* Опция «Определимся на месте» (questroom.playersSelectMode=OPTIONAL).
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
138
|
+
* Выбрана по умолчанию. Пока flex выбран, ни одно число не подсвечено,
|
|
139
|
+
* ценовые подсказки скрыты: хост рендерит «базовую стоимость от» сам.
|
|
140
|
+
*
|
|
141
|
+
* Простой состав (только число человек) — чип стоит в одном ряду с
|
|
142
|
+
* числами, клик по числу снимает flex. Сложный (взрослые, дети,
|
|
143
|
+
* льготы) — пара чипов «Определимся на месте» / «Уже определились»:
|
|
144
|
+
* степперы видны только когда состав уже выбран, иначе заполненные
|
|
145
|
+
* строки спорят с «решим на месте».
|
|
142
146
|
*/
|
|
143
147
|
flexPlayersOption?: {
|
|
144
148
|
selected: boolean;
|
|
@@ -59,6 +59,29 @@ const react_i18next_1 = require("react-i18next");
|
|
|
59
59
|
const use_players_and_variation_picker_1 = require("../use-players-and-variation-picker");
|
|
60
60
|
const sync_composition_1 = require("./sync-composition");
|
|
61
61
|
const ticket_row_1 = require("./ticket-row");
|
|
62
|
+
/**
|
|
63
|
+
* Подпись второго чипа сложного состава, пока ключа нет в каталоге переводов.
|
|
64
|
+
* Тон рядом с `decideOnSite` того же языка. Неизвестный язык — английский,
|
|
65
|
+
* как `fallbackLng` виджета.
|
|
66
|
+
*/
|
|
67
|
+
const playersAlreadyDecidedFallback = {
|
|
68
|
+
ru: 'Уже определились',
|
|
69
|
+
en: 'Already decided',
|
|
70
|
+
sv: 'Redan bestämt',
|
|
71
|
+
de: 'Schon entschieden',
|
|
72
|
+
pl: 'Już ustaliliśmy',
|
|
73
|
+
es: 'Ya lo sabemos',
|
|
74
|
+
fr: 'Déjà décidé',
|
|
75
|
+
nl: 'Al besloten',
|
|
76
|
+
da: 'Allerede afgjort',
|
|
77
|
+
fi: 'Jo päätetty',
|
|
78
|
+
};
|
|
79
|
+
const playersAlreadyDecidedLabel = (translate, language) => {
|
|
80
|
+
const lng = (language || 'en').toLowerCase().split('-')[0];
|
|
81
|
+
return translate('prices:playersAlreadyDecided', {
|
|
82
|
+
defaultValue: playersAlreadyDecidedFallback[lng] || playersAlreadyDecidedFallback.en,
|
|
83
|
+
});
|
|
84
|
+
};
|
|
62
85
|
/**
|
|
63
86
|
* Единый пикер «вариация + состав», который используют админские модалки
|
|
64
87
|
* заказа, виджет и пакет orders.
|
|
@@ -75,7 +98,7 @@ const PlayersAndVariationPicker = ({ slot, currentTariffId, currentDuration, loa
|
|
|
75
98
|
* `useTranslation()` без нужных namespace'ов, а в CRM `prices` грузится
|
|
76
99
|
* лениво. Декларируем их здесь — i18next догрузит бандлы и перерендерит.
|
|
77
100
|
*/
|
|
78
|
-
const { ready: translationsReady } = (0, react_i18next_1.useTranslation)(['prices', 'common'], {
|
|
101
|
+
const { ready: translationsReady, i18n } = (0, react_i18next_1.useTranslation)(['prices', 'common'], {
|
|
79
102
|
useSuspense: false,
|
|
80
103
|
});
|
|
81
104
|
const { loading: pickerLoading, options: pickerOptions, selectedOptionId, selectedVariation, buildVariationChange, selectVariation, details, } = (0, use_players_and_variation_picker_1.usePlayersAndVariationPicker)({
|
|
@@ -242,6 +265,20 @@ const PlayersAndVariationPicker = ({ slot, currentTariffId, currentDuration, loa
|
|
|
242
265
|
}
|
|
243
266
|
flexPlayersOption === null || flexPlayersOption === void 0 ? void 0 : flexPlayersOption.onSelect(true);
|
|
244
267
|
};
|
|
268
|
+
/**
|
|
269
|
+
* Сложный состав: гость явно сказал, что число уже известно.
|
|
270
|
+
* Пока «на месте», степперы скрыты и крутить их было негде. Пустой
|
|
271
|
+
* состав (ещё никто не выбран) открываем минимальной группой — той же,
|
|
272
|
+
* по которой уже показана цена «от». Набранное раньше число не трогаем.
|
|
273
|
+
*/
|
|
274
|
+
const handleSelectDecided = () => {
|
|
275
|
+
if (!flexSelected)
|
|
276
|
+
return;
|
|
277
|
+
if (totalHeads === 0 && effectiveMin > 0 && baseCategoryKey) {
|
|
278
|
+
applyComposition(Object.assign(Object.assign({}, _composition), { [baseCategoryKey]: effectiveMin }));
|
|
279
|
+
}
|
|
280
|
+
flexPlayersOption === null || flexPlayersOption === void 0 ? void 0 : flexPlayersOption.onSelect(false);
|
|
281
|
+
};
|
|
245
282
|
/**
|
|
246
283
|
* Единственная автоправка состава: смена вариации сузила сетку, и состав
|
|
247
284
|
* торчит выше нового потолка — иначе на бэке `price[N]` = undefined →
|
|
@@ -419,29 +456,32 @@ const PlayersAndVariationPicker = ({ slot, currentTariffId, currentDuration, loa
|
|
|
419
456
|
? categoryTitle(baseCategory)
|
|
420
457
|
: t('prices:choosePlayersAmount')),
|
|
421
458
|
!hasExtraRows && !flexSelected && !!tariff[pricingHeads] && (react_1.default.createElement(typography_1.Typography.Text, { view: 'title', color: 'secondary' }, (0, format_amount_1.formatAmount)(tariff[pricingHeads], currency)))),
|
|
422
|
-
|
|
459
|
+
hasExtraRows && flexPlayersOption ? (react_1.default.createElement(flex_1.Flex, { gap: 'xs', wrap: true, justify: 'start' },
|
|
460
|
+
react_1.default.createElement(tag_1.Tag, { key: 'flex-players', text: flexPlayersOption.label, onClick: handleSelectFlex, view: flexSelected ? 'primary-inverted' : 'primary' }),
|
|
461
|
+
react_1.default.createElement(tag_1.Tag, { key: 'players-decided', text: playersAlreadyDecidedLabel(t, i18n.resolvedLanguage || i18n.language), onClick: handleSelectDecided, view: flexSelected ? 'primary' : 'primary-inverted' }))) : ((!!flexPlayersOption || !hasExtraRows) && (react_1.default.createElement(flex_1.Flex, { gap: 'xs', wrap: true, justify: 'start' },
|
|
423
462
|
!!flexPlayersOption && (react_1.default.createElement(tag_1.Tag, { key: 'flex-players', text: flexPlayersOption.label, onClick: handleSelectFlex, view: flexSelected ? 'primary-inverted' : 'primary' })),
|
|
424
463
|
!hasExtraRows &&
|
|
425
464
|
baseLevelOptions.map((level) => (react_1.default.createElement(tag_1.Tag, { key: `level-${level}`, text: `${level}`, onClick: () => handleSelectLevel(level), view: !flexSelected && pricingHeads === level
|
|
426
465
|
? 'primary-inverted'
|
|
427
|
-
: 'primary' }))))),
|
|
428
|
-
(hasExtraRows ?
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
?
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
466
|
+
: 'primary' })))))),
|
|
467
|
+
(hasExtraRows ? !flexSelected : true) &&
|
|
468
|
+
(hasExtraRows ? categories : addOnCategories).map((category) => {
|
|
469
|
+
var _a, _b;
|
|
470
|
+
const value = Math.max(0, _composition[category.key] || 0);
|
|
471
|
+
const rowMax = (_a = maxByCategory[category.key]) !== null && _a !== void 0 ? _a : value;
|
|
472
|
+
const plusLimitHint = value >= rowMax
|
|
473
|
+
? capacityReached
|
|
474
|
+
? t('prices:capacityReached', {
|
|
475
|
+
count: capacityMax,
|
|
476
|
+
defaultValue: 'Максимум {{count}} участников',
|
|
477
|
+
})
|
|
478
|
+
: t('prices:pricingMaxReached', {
|
|
479
|
+
count: pricingMax,
|
|
480
|
+
defaultValue: 'Максимум {{count}} участников по этому тарифу',
|
|
481
|
+
})
|
|
482
|
+
: undefined;
|
|
483
|
+
return (react_1.default.createElement(ticket_row_1.TicketRow, { key: category.key, title: categoryTitle(category), priceHint: categoryPriceHint(category), description: ((_b = category.description) === null || _b === void 0 ? void 0 : _b.trim()) || undefined, value: value, min: 0, max: rowMax, minusLabel: t('prices:minus', { defaultValue: 'На одного меньше' }), plusLabel: t('prices:plus', { defaultValue: 'На одного больше' }), plusDisabledHint: plusLimitHint, onChange: (next) => handleChangeCategory(category.key, next) }));
|
|
484
|
+
})),
|
|
445
485
|
!hidePriceHints && !flexSelected && bookable && (react_1.default.createElement(flex_columns_1.FlexColumns, { columns: 1, gr: 4, gc: 0 }, priceSummary)),
|
|
446
486
|
hidePriceHints && !flexSelected && bookable && (react_1.default.createElement("div", { style: {
|
|
447
487
|
display: 'flex',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@escapenavigator/hooks",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.9",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -32,5 +32,5 @@
|
|
|
32
32
|
"ts-jest": "^29.1.1",
|
|
33
33
|
"typescript": "^5.6"
|
|
34
34
|
},
|
|
35
|
-
"gitHead": "
|
|
35
|
+
"gitHead": "8331e15dfa6ac28921249548f4df2c702669de37"
|
|
36
36
|
}
|