ublo-lib 1.49.12 → 1.50.0

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.
Files changed (77) hide show
  1. package/es/common/components/admin-links/admin-links.d.ts.map +1 -1
  2. package/es/common/hooks/use-faq.d.ts.map +1 -1
  3. package/es/common/hooks/use-scroll-direction.d.ts.map +1 -1
  4. package/es/common/utils/cookies.d.ts.map +1 -1
  5. package/es/common/utils/copy.d.ts.map +1 -1
  6. package/es/common/utils/dates.d.ts.map +1 -1
  7. package/es/common/utils/fetcher.d.ts.map +1 -1
  8. package/es/common/utils/msem-widget.d.ts.map +1 -1
  9. package/es/common/utils/url-parameters.d.ts.map +1 -1
  10. package/es/esf/components/espace-prive/services/middleware.d.ts.map +1 -1
  11. package/es/future/components/event-analytics/instant-search.d.ts.map +1 -1
  12. package/es/future/components/msem-package/components/config.d.ts.map +1 -1
  13. package/es/future/components/msem-package/components/config.js +44 -18
  14. package/es/future/components/msem-package/components/filters.d.ts +5 -1
  15. package/es/future/components/msem-package/components/filters.d.ts.map +1 -1
  16. package/es/future/components/msem-package/components/filters.js +78 -15
  17. package/es/future/components/msem-package/components/filters.module.css +124 -20
  18. package/es/future/components/msem-package/components/global-settings.d.ts.map +1 -1
  19. package/es/future/components/msem-package/components/global-settings.js +2 -11
  20. package/es/future/components/msem-package/components/global-settings.module.css +2 -34
  21. package/es/future/components/msem-package/components/pax-settings.d.ts +9 -0
  22. package/es/future/components/msem-package/components/pax-settings.d.ts.map +1 -0
  23. package/es/future/components/msem-package/components/pax-settings.js +73 -0
  24. package/es/future/components/msem-package/components/pax-settings.module.css +48 -0
  25. package/es/future/components/msem-package/components/settings-ui.d.ts +23 -0
  26. package/es/future/components/msem-package/components/settings-ui.d.ts.map +1 -0
  27. package/es/future/components/msem-package/components/settings-ui.js +14 -0
  28. package/es/future/components/msem-package/components/settings-ui.module.css +152 -0
  29. package/es/future/components/msem-package/components/stay-settings.d.ts.map +1 -1
  30. package/es/future/components/msem-package/components/stay-settings.js +44 -25
  31. package/es/future/components/msem-package/components/stay-settings.module.css +21 -44
  32. package/es/future/components/msem-package/components/widget-dialog.d.ts.map +1 -1
  33. package/es/future/components/msem-package/components/widget-dialog.js +20 -12
  34. package/es/future/components/msem-package/components/widget-dialog.module.css +1 -22
  35. package/es/future/components/msem-package/components/widget.d.ts +3 -1
  36. package/es/future/components/msem-package/components/widget.d.ts.map +1 -1
  37. package/es/future/components/msem-package/components/widget.js +102 -36
  38. package/es/future/components/msem-package/components/widget.module.css +114 -51
  39. package/es/future/components/msem-package/components/widgets-settings.d.ts.map +1 -1
  40. package/es/future/components/msem-package/components/widgets-settings.js +22 -22
  41. package/es/future/components/msem-package/components/widgets-settings.module.css +95 -44
  42. package/es/future/components/msem-package/components/widgets.d.ts +3 -1
  43. package/es/future/components/msem-package/components/widgets.d.ts.map +1 -1
  44. package/es/future/components/msem-package/components/widgets.js +28 -13
  45. package/es/future/components/msem-package/core.d.ts.map +1 -1
  46. package/es/future/components/msem-package/core.js +13 -2
  47. package/es/future/components/msem-package/i18n/ca.json +17 -3
  48. package/es/future/components/msem-package/i18n/en.json +17 -3
  49. package/es/future/components/msem-package/i18n/es.json +17 -3
  50. package/es/future/components/msem-package/i18n/fr.json +17 -3
  51. package/es/future/components/msem-package/msem-package.module.css +29 -0
  52. package/es/future/components/msem-package/types.d.ts +12 -1
  53. package/es/future/components/msem-package/types.d.ts.map +1 -1
  54. package/es/future/components/msem-package/utils/api.d.ts.map +1 -1
  55. package/es/future/components/msem-package/utils/pax.d.ts +3 -0
  56. package/es/future/components/msem-package/utils/pax.d.ts.map +1 -0
  57. package/es/future/components/msem-package/utils/pax.js +9 -0
  58. package/es/future/components/msem-preset-editor/editors/easyrent-rental.d.ts.map +1 -1
  59. package/es/future/components/msem-preset-editor/editors/easyrent-rental.js +1 -1
  60. package/es/future/components/msem-preset-editor/editors/ski-rental.d.ts.map +1 -1
  61. package/es/future/components/msem-preset-editor/editors/ski-rental.js +1 -1
  62. package/es/future/components/msem-preset-editor/msem-preset-editor.d.ts.map +1 -1
  63. package/es/future/components/msem-preset-editor/msem-preset-editor.js +1 -0
  64. package/es/future/components/msem-preset-editor/services/url-params.d.ts.map +1 -1
  65. package/es/future/utils/url-parameters.d.ts.map +1 -1
  66. package/es/lbm/components/instant-search/widgets/access.d.ts.map +1 -1
  67. package/es/lbm/components/instant-search/widgets/activity.d.ts.map +1 -1
  68. package/es/lbm/components/instant-search/widgets/dawn-nights-openings.d.ts.map +1 -1
  69. package/es/lbm/components/instant-search/widgets/lift.d.ts.map +1 -1
  70. package/es/lbm/components/instant-search/widgets/lifts.d.ts.map +1 -1
  71. package/es/lbm/components/instant-search/widgets/openings.d.ts.map +1 -1
  72. package/es/lbm/components/instant-search/widgets/slope.d.ts.map +1 -1
  73. package/es/lbm/components/instant-search/widgets/slopes.d.ts.map +1 -1
  74. package/es/lbm/components/instant-search/widgets/snow.d.ts.map +1 -1
  75. package/es/lbm/components/instant-search/widgets/weather.d.ts.map +1 -1
  76. package/es/lbm/components/instant-search/widgets/webcam.d.ts.map +1 -1
  77. package/package.json +1 -1
@@ -0,0 +1,73 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import Input from "dt-design-system/es/input";
3
+ import Checkbox from "dt-design-system/es/checkbox";
4
+ import * as Icons from "dt-design-system/es/icons";
5
+ import { Card, Radio } from "./settings-ui";
6
+ import styles from "./pax-settings.module.css";
7
+ const toNum = (value) => {
8
+ const n = parseInt(value, 10);
9
+ return isNaN(n) ? undefined : n;
10
+ };
11
+ export default function PaxSettings({ config, setConfig }) {
12
+ const pax = config.pax;
13
+ const mode = pax?.mode ?? "unlimited";
14
+ const patchPax = (patch) => {
15
+ setConfig((prev) => ({
16
+ ...prev,
17
+ pax: { mode: prev.pax?.mode ?? "unlimited", ...prev.pax, ...patch },
18
+ }));
19
+ };
20
+ const toggleMode = (target) => () => {
21
+ const next = mode === target ? "unlimited" : target;
22
+ if (next === "unlimited") {
23
+ patchPax({
24
+ mode: "unlimited",
25
+ min: undefined,
26
+ max: undefined,
27
+ value: undefined,
28
+ hidden: undefined,
29
+ });
30
+ }
31
+ else if (next === "range") {
32
+ patchPax({ mode: "range", value: undefined });
33
+ }
34
+ else {
35
+ patchPax({ mode: "fixed", min: undefined, max: undefined });
36
+ }
37
+ };
38
+ const updateMin = (value) => patchPax({ min: toNum(value) });
39
+ const updateMax = (value) => patchPax({ max: toNum(value) });
40
+ const updateValue = (value) => patchPax({ value: toNum(value) });
41
+ const updateHidden = (hidden) => patchPax({ hidden });
42
+ return (_jsxs(Card, { icon: _jsx(Icons.Users, {}), title: "Nombre de personnes", badge: getBadge(pax), children: [_jsxs("div", { className: styles.modes, children: [_jsx(Radio, { checked: mode === "range", onClick: toggleMode("range"), children: "D\u00E9finir un nombre de personnes" }), _jsx(Radio, { checked: mode === "fixed", onClick: toggleMode("fixed"), children: "Fixer nombre personnes" })] }), mode === "range" && (_jsxs("div", { className: styles.fields, children: [_jsx(Input, { type: "number", label: "Minimum de personnes", value: pax?.min ?? "", onValueChange: updateMin, className: styles.field, min: 1 }), _jsx(Input, { type: "number", label: "Maximum de personnes", value: pax?.max ?? "", onValueChange: updateMax, className: styles.field, min: 1 })] })), mode === "fixed" && (_jsx("div", { className: styles.fields, children: _jsx(Input, { type: "number", label: "Nombre fixe de personnes", value: pax?.value ?? "", onValueChange: updateValue, className: styles.field, min: 1 }) })), mode !== "unlimited" && (_jsx("div", { className: styles.masquer, children: _jsx(Checkbox, { label: "Masquer le nombre de personnes", checked: pax?.hidden || false, onCheckedChange: updateHidden }) })), getExplanation(pax) && (_jsxs("p", { className: styles.note, children: [_jsx(Icons.Info, { className: styles.noteIcon }), getExplanation(pax)] }))] }));
43
+ }
44
+ function getExplanation(pax) {
45
+ const mode = pax?.mode ?? "unlimited";
46
+ if (mode === "unlimited")
47
+ return null;
48
+ if (mode === "fixed") {
49
+ return "Le nombre de personnes est fixe : il sera appliqué à chaque offre.";
50
+ }
51
+ if (pax?.hidden) {
52
+ return "Le nombre de personnes ne sera pas demandé au client au niveau du pack. Il sera demandé pour chaque offre, en respectant les limites définies";
53
+ }
54
+ return "Le client choisira le nombre de personnes au niveau du pack. Ce nombre sera ensuite repris à chaque offre.";
55
+ }
56
+ function getBadge(pax) {
57
+ if (!pax || pax.mode === "unlimited") {
58
+ return "Nombre de personnes : illimitées";
59
+ }
60
+ if (pax.mode === "fixed") {
61
+ if (pax.value == null)
62
+ return "Nombre de personnes";
63
+ return `De ${pax.value} personne${pax.value > 1 ? "s" : ""}`;
64
+ }
65
+ const { min, max } = pax;
66
+ if (min != null && max != null)
67
+ return `De ${min} à ${max} personnes`;
68
+ if (min != null)
69
+ return `À partir de ${min} personnes`;
70
+ if (max != null)
71
+ return `Jusqu'à ${max} personnes`;
72
+ return "Nombre de personnes";
73
+ }
@@ -0,0 +1,48 @@
1
+ .modes {
2
+ display: flex;
3
+ flex-wrap: wrap;
4
+ gap: 12px 28px;
5
+ }
6
+
7
+ .fields {
8
+ display: flex;
9
+ flex-wrap: wrap;
10
+ gap: 12px;
11
+ }
12
+
13
+ .field {
14
+ flex: 1 1 220px;
15
+ }
16
+
17
+ .masquer {
18
+ display: flex;
19
+ justify-content: flex-end;
20
+ }
21
+
22
+ /* Note explicative (comportement côté client) */
23
+ .note {
24
+ display: flex;
25
+ align-items: flex-start;
26
+ gap: 8px;
27
+ margin: 0;
28
+ padding: 10px 12px;
29
+ font-size: 13px;
30
+ line-height: 1.4;
31
+ color: var(--ds-grey-700, #262626);
32
+ background-color: var(--ds-grey-100, #f8f8f8);
33
+ border-radius: var(--ds-radius-200, 8px);
34
+ }
35
+
36
+ .noteIcon {
37
+ flex: 0 0 16px;
38
+ width: 16px;
39
+ height: 16px;
40
+ margin-top: 1px;
41
+ fill: var(--ds-grey-500, #7c7b7b);
42
+ }
43
+
44
+ @media (max-width: 600px) {
45
+ .masquer {
46
+ justify-content: flex-start;
47
+ }
48
+ }
@@ -0,0 +1,23 @@
1
+ import * as React from "react";
2
+ type CardProps = {
3
+ icon?: React.ReactNode;
4
+ title: React.ReactNode;
5
+ info?: string | React.ReactElement;
6
+ badge?: React.ReactNode;
7
+ className?: string;
8
+ children?: React.ReactNode;
9
+ };
10
+ export declare function Card({ icon, title, info, badge, className, children, }: CardProps): import("react/jsx-runtime").JSX.Element;
11
+ type RadioProps = {
12
+ checked: boolean;
13
+ onClick: () => void;
14
+ disabled?: boolean;
15
+ children: React.ReactNode;
16
+ className?: string;
17
+ };
18
+ export declare function Radio({ checked, onClick, disabled, children, className, }: RadioProps): import("react/jsx-runtime").JSX.Element;
19
+ export declare function Badge({ children }: {
20
+ children: React.ReactNode;
21
+ }): import("react/jsx-runtime").JSX.Element;
22
+ export {};
23
+ //# sourceMappingURL=settings-ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-ui.d.ts","sourceRoot":"","sources":["../../../../../src/future/components/msem-package/components/settings-ui.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,KAAK,SAAS,GAAG;IACf,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IAEvB,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,YAAY,CAAC;IACnC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC;AAGF,wBAAgB,IAAI,CAAC,EACnB,IAAI,EACJ,KAAK,EACL,IAAI,EACJ,KAAK,EACL,SAAS,EACT,QAAQ,GACT,EAAE,SAAS,2CA2BX;AAED,KAAK,UAAU,GAAG;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAMF,wBAAgB,KAAK,CAAC,EACpB,OAAO,EACP,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,SAAS,GACV,EAAE,UAAU,2CAcZ;AAGD,wBAAgB,KAAK,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,2CAEhE"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import Popover from "dt-design-system/es/popover";
3
+ import * as Icons from "dt-design-system/es/icons";
4
+ import styles from "./settings-ui.module.css";
5
+ const cx = (...classes) => classes.filter(Boolean).join(" ");
6
+ export function Card({ icon, title, info, badge, className, children, }) {
7
+ return (_jsxs("section", { className: cx(styles.card, className), children: [_jsxs("header", { className: styles.header, children: [icon && _jsx("span", { className: styles.headerIcon, children: icon }), _jsx("h3", { className: styles.headerTitle, children: title }), info != null && (_jsx(Popover, { className: styles.infoPopover, trigger: _jsx("button", { type: "button", className: styles.infoButton, "aria-label": "Information", children: _jsx(Icons.Info, {}) }), children: info })), badge != null && _jsx("span", { className: styles.badge, children: badge })] }), children != null && _jsx("div", { className: styles.body, children: children })] }));
8
+ }
9
+ export function Radio({ checked, onClick, disabled, children, className, }) {
10
+ return (_jsxs("button", { type: "button", role: "radio", "aria-checked": checked, disabled: disabled, onClick: onClick, className: cx(styles.radio, checked && styles.radioChecked, className), children: [_jsx("span", { className: styles.radioMark, "aria-hidden": true }), _jsx("span", { className: styles.radioLabel, children: children })] }));
11
+ }
12
+ export function Badge({ children }) {
13
+ return _jsx("span", { className: styles.badgeInline, children: children });
14
+ }
@@ -0,0 +1,152 @@
1
+ .card {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 16px;
5
+ padding: 16px 20px 20px;
6
+ background-color: var(--ds-grey-000, #fff);
7
+ border: 1px solid var(--ds-grey-200, #ededed);
8
+ border-radius: var(--ds-radius-200, 8px);
9
+ }
10
+
11
+ .header {
12
+ display: flex;
13
+ align-items: center;
14
+ gap: 8px;
15
+ }
16
+
17
+ .headerIcon {
18
+ display: inline-flex;
19
+ flex: 0 0 20px;
20
+ }
21
+
22
+ .headerIcon > svg {
23
+ width: 20px;
24
+ height: 20px;
25
+ fill: currentcolor;
26
+ }
27
+
28
+ .headerTitle {
29
+ margin: 0;
30
+ font-size: 16px;
31
+ font-weight: 700;
32
+ line-height: 1.2;
33
+ }
34
+
35
+ /* Bouton "i" d'aide contextuelle */
36
+ .infoButton {
37
+ display: inline-flex;
38
+ align-items: center;
39
+ justify-content: center;
40
+ padding: 0;
41
+ color: var(--ds-grey-500, #7c7b7b);
42
+ background: none;
43
+ border: 0;
44
+ cursor: pointer;
45
+ }
46
+
47
+ .infoPopover {
48
+ max-width: 280px;
49
+ font-size: 14px;
50
+ line-height: 1.4;
51
+ }
52
+
53
+ .infoButton > svg {
54
+ width: 18px;
55
+ height: 18px;
56
+ fill: currentcolor;
57
+ }
58
+
59
+ .infoButton:hover {
60
+ color: var(--ds-grey-700, #262626);
61
+ }
62
+
63
+ /* Badge résumé poussé à droite de l'en-tête */
64
+ .badge {
65
+ margin-left: auto;
66
+ padding: 6px 12px;
67
+ font-size: 13px;
68
+ font-weight: 500;
69
+ line-height: 1;
70
+ color: var(--ds-grey-700, #262626);
71
+ background-color: var(--ds-grey-100, #f8f8f8);
72
+ border-radius: var(--ds-radius-400, 20px);
73
+ white-space: nowrap;
74
+ }
75
+
76
+ .body {
77
+ display: flex;
78
+ flex-direction: column;
79
+ gap: 14px;
80
+ }
81
+
82
+ /* Radio togglable */
83
+ .radio {
84
+ display: inline-flex;
85
+ align-items: center;
86
+ gap: 10px;
87
+ padding: 0;
88
+ font: inherit;
89
+ color: var(--ds-grey-800, #000);
90
+ background: none;
91
+ border: 0;
92
+ cursor: pointer;
93
+ text-align: left;
94
+ }
95
+
96
+ .radio:disabled {
97
+ cursor: default;
98
+ filter: grayscale(100%) opacity(50%);
99
+ }
100
+
101
+ .radioMark {
102
+ --size: 22px;
103
+
104
+ position: relative;
105
+ flex: 0 0 var(--size);
106
+ width: var(--size);
107
+ height: var(--size);
108
+ background-color: var(--ds-radio-background, var(--ds-grey-000, #fff));
109
+ border: var(--ds-radio-border, 1px solid var(--ds-grey-300, #d7d7d7));
110
+ border-radius: 100%;
111
+ }
112
+
113
+ .radio:not(:disabled):hover .radioMark {
114
+ background-color: var(--ds-blue-000, #e8f0fc);
115
+ }
116
+
117
+ .radioChecked .radioMark::after {
118
+ content: "";
119
+ position: absolute;
120
+ inset: 0;
121
+ margin: auto;
122
+ width: 10px;
123
+ height: 10px;
124
+ border-radius: 50%;
125
+ background-color: var(
126
+ --ds-radio-foreground,
127
+ var(--ds-secondary, var(--ds-blue-400, #0038ff))
128
+ );
129
+ }
130
+
131
+ .radioChecked .radioMark {
132
+ border-color: var(
133
+ --ds-radio-foreground,
134
+ var(--ds-secondary, var(--ds-blue-400, #0038ff))
135
+ );
136
+ }
137
+
138
+ .radioLabel {
139
+ font-size: 15px;
140
+ line-height: 1.2;
141
+ }
142
+
143
+ /* Badge inline (utilisable dans le corps si besoin) */
144
+ .badgeInline {
145
+ padding: 4px 10px;
146
+ font-size: 13px;
147
+ line-height: 1;
148
+ color: var(--ds-grey-700, #262626);
149
+ background-color: var(--ds-grey-100, #f8f8f8);
150
+ border-radius: var(--ds-radius-400, 20px);
151
+ white-space: nowrap;
152
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"stay-settings.d.ts","sourceRoot":"","sources":["../../../../../src/future/components/msem-package/components/stay-settings.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,KAAK,KAAK,MAAM,UAAU,CAAC;AAGvC,KAAK,KAAK,GAAG;IACX,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;IACrB,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;CAC/D,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,2CA+EhE"}
1
+ {"version":3,"file":"stay-settings.d.ts","sourceRoot":"","sources":["../../../../../src/future/components/msem-package/components/stay-settings.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,KAAK,KAAK,MAAM,UAAU,CAAC;AAIvC,KAAK,KAAK,GAAG;IACX,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;IACrB,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;CAC/D,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,2CAkHhE"}
@@ -1,32 +1,51 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import Input from "dt-design-system/es/input";
3
3
  import Checkbox from "dt-design-system/es/checkbox";
4
4
  import * as Icons from "dt-design-system/es/icons";
5
+ import { Card, Radio } from "./settings-ui";
5
6
  import styles from "./stay-settings.module.css";
6
7
  export default function StaySettings({ config, setConfig }) {
7
- const updateStay = (key) => (value) => {
8
- setConfig((prev) => ({
9
- ...prev,
10
- stay: { ...prev.stay, [key]: value },
11
- }));
8
+ const stay = config.stay;
9
+ const dated = stay?.dated ?? Boolean(stay?.from || stay?.to);
10
+ const patchStay = (patch) => {
11
+ setConfig((prev) => ({ ...prev, stay: { ...prev.stay, ...patch } }));
12
12
  };
13
- const updateNbDays = (value) => {
14
- setConfig((prev) => ({
15
- ...prev,
16
- stay: { ...prev.stay, nbDays: parseInt(value) },
17
- }));
18
- };
19
- const updateForced = (forced) => {
20
- setConfig((prev) => ({
21
- ...prev,
22
- stay: { ...prev.stay, forced, fixed: false },
23
- }));
24
- };
25
- const updateFixed = (fixed) => {
26
- setConfig((prev) => ({
27
- ...prev,
28
- stay: { ...prev.stay, fixed, forced: false },
29
- }));
30
- };
31
- return (_jsxs("div", { className: styles.container, children: [_jsxs("div", { className: styles.title, children: [_jsx(Icons.Calendar, {}), "Param\u00E8tres de validit\u00E9 de l'offre"] }), _jsxs("div", { className: styles.settings, children: [_jsx(Input, { label: "D\u00E9but de validit\u00E9 de l'offre", type: "date", value: config.stay?.from || "", onValueChange: updateStay("from"), className: styles.field }), _jsx(Input, { label: "Fin de validit\u00E9 de l'offre", type: "date", value: config.stay?.to || "", onValueChange: updateStay("to"), className: styles.field }), _jsxs("div", { className: styles.checkboxes, children: [_jsx(Checkbox, { label: "Verrouiller ces dates de validit\u00E9", checked: config.stay?.forced || false, onCheckedChange: updateForced }), _jsx(Checkbox, { label: _jsxs("div", { className: styles.nbDaysLabel, children: [_jsx("span", { children: "Fixer l'offre \u00E0" }), _jsx(Input, { value: config.stay?.nbDays || "", onValueChange: updateNbDays, className: styles.nbDaysInput, disabled: !config.stay?.fixed, compact: true, type: "number", min: 1 }), _jsx("span", { children: "jour(s)" })] }), checked: config.stay?.fixed || false, onCheckedChange: updateFixed })] })] })] }));
13
+ const toggleDated = () => patchStay(dated
14
+ ? {
15
+ dated: false,
16
+ from: undefined,
17
+ to: undefined,
18
+ forced: undefined,
19
+ fixed: undefined,
20
+ nbDays: undefined,
21
+ }
22
+ : { dated: true, hidden: undefined });
23
+ const updateStay = (key) => (value) => patchStay({ [key]: value });
24
+ const updateNbDays = (value) => patchStay({ nbDays: parseInt(value, 10) || undefined });
25
+ const toggleForced = () => patchStay(stay?.forced
26
+ ? { forced: false, hidden: undefined }
27
+ : { forced: true, fixed: false, nbDays: undefined });
28
+ const toggleFixed = () => patchStay(stay?.fixed
29
+ ? { fixed: false, hidden: undefined, nbDays: undefined }
30
+ : { fixed: true, forced: false, hidden: undefined });
31
+ const updateHidden = (hidden) => patchStay({ hidden });
32
+ const canHide = !dated || Boolean(stay?.forced);
33
+ return (_jsxs(Card, { icon: _jsx(Icons.Calendar, {}), title: "Validit\u00E9 de l'offre", info: "Dans le cas d'un forfait non dat\u00E9, aucune date n'est attendue.", badge: getBadge(dated, stay), children: [_jsx(Radio, { checked: dated, onClick: toggleDated, children: "D\u00E9finir des dates de validit\u00E9s" }), dated && (_jsxs(_Fragment, { children: [_jsxs("div", { className: styles.fields, children: [_jsx(Input, { label: "D\u00E9but de validit\u00E9", type: "date", value: stay?.from || "", onValueChange: updateStay("from"), className: styles.field }), _jsx(Input, { label: "Fin de validit\u00E9", type: "date", value: stay?.to || "", onValueChange: updateStay("to"), className: styles.field })] }), _jsxs("div", { className: styles.modes, children: [_jsx(Radio, { checked: Boolean(stay?.forced), onClick: toggleForced, children: "Verrouiller ces dates" }), _jsxs("div", { className: styles.fixedRow, children: [_jsx(Radio, { checked: Boolean(stay?.fixed), onClick: toggleFixed, children: "Fixer l'offre \u00E0" }), _jsx(Input, { value: stay?.nbDays || "", onValueChange: updateNbDays, className: styles.nbDaysInput, disabled: !stay?.fixed, compact: true, type: "number", min: 1 }), _jsx("span", { children: "jours" })] })] })] })), canHide && (_jsx("div", { className: styles.masquer, children: _jsx(Checkbox, { label: "Masquer la validit\u00E9 de l'offre", checked: stay?.hidden || false, onCheckedChange: updateHidden }) }))] }));
34
+ }
35
+ const formatDate = (iso) => {
36
+ if (!iso)
37
+ return "…";
38
+ const [y, m, d] = iso.split("-");
39
+ return d && m && y ? `${d}/${m}/${y}` : iso;
40
+ };
41
+ function getBadge(dated, stay) {
42
+ if (!dated)
43
+ return "Pack non daté";
44
+ const from = formatDate(stay?.from);
45
+ const to = formatDate(stay?.to);
46
+ if (stay?.forced)
47
+ return `Du ${from} au ${to}`;
48
+ if (stay?.fixed)
49
+ return `${stay.nbDays || "…"} jours - entre ${from} et ${to}`;
50
+ return `Entre ${from} et ${to}`;
32
51
  }
@@ -1,59 +1,36 @@
1
- .container {
2
- width: min(calc(100% - 20px), 840px);
1
+ .fields {
3
2
  display: flex;
4
- flex-direction: column;
5
- gap: 8px;
6
- margin-inline: auto;
7
- padding: 12px;
8
- border: 1px solid var(--ds-grey-200, #ededed);
9
- border-radius: var(--ds-radius-200, 8px);
10
- }
11
-
12
- .title {
13
- display: flex;
14
- align-items: center;
15
- gap: 6px;
16
- margin-bottom: 8px;
17
- font-size: 18px;
18
- font-weight: 700;
19
- }
20
-
21
- .title > svg {
22
- flex: 0 0 22px;
23
- height: 22px;
24
- fill: currentcolor;
25
- }
26
-
27
- .settings {
28
- display: flex;
29
- align-items: flex-end;
30
3
  flex-wrap: wrap;
31
- gap: 12px 6px;
4
+ gap: 12px;
32
5
  }
33
6
 
34
7
  .field {
35
- flex: 1 1 auto;
36
- }
37
-
38
- @media (width > 700px) {
39
- .field {
40
- flex: 1 1 0%;
41
- }
8
+ flex: 1 1 220px;
42
9
  }
43
10
 
44
- .checkboxes {
11
+ .modes {
45
12
  display: flex;
46
13
  flex-direction: column;
47
- gap: 4px;
48
- }
49
- .checkbox {
50
- flex: 1 1 100%;
14
+ gap: 12px;
51
15
  }
52
- .nbDaysLabel {
16
+
17
+ .fixedRow {
53
18
  display: flex;
54
19
  align-items: center;
55
- gap: 4px;
20
+ gap: 8px;
56
21
  }
22
+
57
23
  .nbDaysInput {
58
- width: 45px;
24
+ width: 56px;
25
+ }
26
+
27
+ .masquer {
28
+ display: flex;
29
+ justify-content: flex-end;
30
+ }
31
+
32
+ @media (max-width: 600px) {
33
+ .masquer {
34
+ justify-content: flex-start;
35
+ }
59
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"widget-dialog.d.ts","sourceRoot":"","sources":["../../../../../src/future/components/msem-package/components/widget-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,OAAO,KAAK,KAAK,KAAK,MAAM,UAAU,CAAC;AAIvC,KAAK,KAAK,GAAG;IACX,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;IACrB,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9D,aAAa,EAAE,KAAK,CAAC,aAAa,CAAC;IACnC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,IAAI,CAAC;CAC/B,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EACnC,MAAM,EACN,SAAS,EACT,aAAa,EACb,MAAM,EACN,iBAAiB,GAClB,EAAE,KAAK,2CAuJP"}
1
+ {"version":3,"file":"widget-dialog.d.ts","sourceRoot":"","sources":["../../../../../src/future/components/msem-package/components/widget-dialog.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,OAAO,KAAK,KAAK,KAAK,MAAM,UAAU,CAAC;AAKvC,KAAK,KAAK,GAAG;IACX,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;IACrB,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9D,aAAa,EAAE,KAAK,CAAC,aAAa,CAAC;IACnC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,IAAI,CAAC;CAC/B,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,EACnC,MAAM,EACN,SAAS,EACT,aAAa,EACb,MAAM,EACN,iBAAiB,GAClB,EAAE,KAAK,2CAuJP"}
@@ -7,10 +7,12 @@ import Dialog from "dt-design-system/es/dialog";
7
7
  import Checkbox from "dt-design-system/es/checkbox";
8
8
  import MseMPresetEditor from "../../msem-preset-editor";
9
9
  import * as Icons from "dt-design-system/es/icons";
10
+ import { resolvePaxCount } from "../utils/pax";
10
11
  import styles from "./widget-dialog.module.css";
11
12
  export default function WidgetDialog({ config, setConfig, editorOptions, widget, closeWidgetDialog, }) {
12
13
  const { lang } = useMsemRuntime();
13
14
  const { facet } = config;
15
+ const paxCount = resolvePaxCount(config.pax);
14
16
  const editorLang = lang === "fr" ? "fr" : "en";
15
17
  const { channel, resort, msemServicesUrl } = editorOptions;
16
18
  const [repeatable, setRepeatable] = React.useState(widget.repeatable);
@@ -19,25 +21,21 @@ export default function WidgetDialog({ config, setConfig, editorOptions, widget,
19
21
  const title = isNew ? "Nouvelle offre" : "Modifier l'offre";
20
22
  const defaultPreset = getDefaultPreset(widget);
21
23
  const [preset, setPreset] = React.useState(defaultPreset);
22
- const [image, setImage] = React.useState(widget.image);
23
- const updateImage = (path) => {
24
- setImage(path);
25
- };
24
+ const [offerTitle, setOfferTitle] = React.useState(widget.title);
25
+ const [offerTagline, setOfferTagline] = React.useState(widget.tagline);
26
26
  const submit = React.useCallback((e) => {
27
27
  e.preventDefault();
28
28
  const form = e.currentTarget;
29
29
  const formData = new FormData(form);
30
- const title = formData.get("title");
31
- const tagline = formData.get("tagline");
32
30
  const maxParticipants = parseInt(formData.get("maxParticipants"));
33
- const { name, widget: widgetName, options, presets } = preset;
31
+ const { name, widget: widgetName, logo, options, presets } = preset || {};
34
32
  const id = isNew ? crypto.randomUUID() : widget.id;
35
33
  const data = {
36
34
  name,
37
35
  widget: widgetName,
38
- title,
39
- tagline,
40
- image,
36
+ logo: logo ?? widget.logo,
37
+ title: offerTitle,
38
+ tagline: offerTagline,
41
39
  options,
42
40
  presets,
43
41
  repeatable,
@@ -53,8 +51,18 @@ export default function WidgetDialog({ config, setConfig, editorOptions, widget,
53
51
  }),
54
52
  };
55
53
  setConfig(newConfig);
56
- }, [config, image, isNew, isOptional, preset, setConfig, widget, repeatable]);
57
- return (_jsx(Dialog, { className: styles.dialog, close: closeWidgetDialog, showAsModal: false, closeOnBackdropClick: false, isOpened: true, children: _jsxs("div", { className: styles.inner, children: [_jsxs("div", { className: styles.title, children: [_jsx(Icons.ShoppingBag, {}), title] }), _jsxs("form", { className: styles.form, onSubmit: submit, children: [_jsxs("div", { className: styles.top, children: [_jsx("div", { className: styles.left, children: _jsx(Button, { className: styles.image, variant: "transparent", onClick: () => window?.Cms?.fileManager(updateImage, 150, 100), children: image ? _jsx("img", { src: image, alt: "" }) : _jsx(Icons.Image, {}) }) }), _jsxs("div", { className: styles.right, children: [_jsx(Input, { label: "Titre", name: "title", defaultValue: widget.title }), _jsx(Input, { label: "Phrase d'accroche", name: "tagline", defaultValue: widget.tagline })] })] }), _jsxs("div", { className: styles.editor, children: [_jsx("div", { className: styles.editorTitle, children: "Preset" }), _jsx(MseMPresetEditor, { lang: editorLang, channel: channel, resort: String(resort), msemServicesUrl: msemServicesUrl, facet: facet, currentPreset: preset, onChange: setPreset, hideStay: true })] }), _jsxs("div", { className: styles.checkboxes, children: [!isOptional && (_jsx(Checkbox, { label: "R\u00E9p\u00E9ter le widget pour chaque participant", name: "repeatable", checked: repeatable, onChange: (e) => setRepeatable(e.target.checked) })), isOptional && (_jsx(Checkbox, { label: _jsxs("div", { className: styles.nbParticipantsLabel, children: [_jsx("span", { children: "R\u00E9p\u00E9ter le widget jusqu'\u00E0" }), _jsx(Input, { name: "maxParticipants", defaultValue: widget.maxParticipants || config.paxPlan, className: styles.nbParticipantsInput, disabled: !repeatable, compact: true, type: "number", min: config.paxPlan }), _jsx("span", { children: "fois" })] }), name: "repeatManually", checked: repeatable, onChange: (e) => setRepeatable(e.target.checked) }))] }), _jsx("div", { className: styles.controls, children: _jsxs(Button, { type: "submit", variant: "success", className: styles.save, children: [_jsx(Icons.Check, {}), "Confirmer"] }) })] })] }) }));
54
+ }, [
55
+ config,
56
+ isNew,
57
+ isOptional,
58
+ preset,
59
+ setConfig,
60
+ widget,
61
+ repeatable,
62
+ offerTitle,
63
+ offerTagline,
64
+ ]);
65
+ return (_jsx(Dialog, { className: styles.dialog, close: closeWidgetDialog, showAsModal: false, closeOnBackdropClick: false, isOpened: true, children: _jsxs("div", { className: styles.inner, children: [_jsxs("div", { className: styles.title, children: [_jsx(Icons.ShoppingBag, {}), title] }), _jsxs("form", { className: styles.form, onSubmit: submit, children: [_jsxs("div", { className: styles.top, children: [_jsx(Input, { label: "Titre", value: offerTitle, onValueChange: setOfferTitle }), _jsx(Input, { label: "Phrase d'accroche", value: offerTagline, onValueChange: setOfferTagline })] }), _jsxs("div", { className: styles.editor, children: [_jsx("div", { className: styles.editorTitle, children: "Preset" }), _jsx(MseMPresetEditor, { lang: editorLang, channel: channel, resort: String(resort), msemServicesUrl: msemServicesUrl, facet: facet, currentPreset: preset, onChange: setPreset, hideStay: true })] }), _jsxs("div", { className: styles.checkboxes, children: [!isOptional && (_jsx(Checkbox, { label: "R\u00E9p\u00E9ter le widget pour chaque participant", name: "repeatable", checked: repeatable, onChange: (e) => setRepeatable(e.target.checked) })), isOptional && (_jsx(Checkbox, { label: _jsxs("div", { className: styles.nbParticipantsLabel, children: [_jsx("span", { children: "R\u00E9p\u00E9ter le widget jusqu'\u00E0" }), _jsx(Input, { name: "maxParticipants", defaultValue: widget.maxParticipants || paxCount, className: styles.nbParticipantsInput, disabled: !repeatable, compact: true, type: "number", min: paxCount }), _jsx("span", { children: "fois" })] }), name: "repeatManually", checked: repeatable, onChange: (e) => setRepeatable(e.target.checked) }))] }), _jsx("div", { className: styles.controls, children: _jsxs(Button, { type: "submit", variant: "success", className: styles.save, children: [_jsx(Icons.Check, {}), "Confirmer"] }) })] })] }) }));
58
66
  }
59
67
  function getDefaultPreset(widget) {
60
68
  const { name, widget: widgetName, options, presets } = widget;
@@ -28,31 +28,10 @@
28
28
  .top {
29
29
  width: 100%;
30
30
  display: flex;
31
- align-items: flex-end;
31
+ flex-direction: column;
32
32
  gap: 12px;
33
33
  }
34
34
 
35
- .left {
36
- flex: 0 0 150px;
37
- }
38
-
39
- .right {
40
- flex: 1 1 100%;
41
- }
42
-
43
- .image {
44
- width: 150px;
45
- height: 100px;
46
- margin: 0 auto;
47
- padding: 0;
48
- border: 1px solid var(--ds-grey-300, #d7d7d7);
49
- border-radius: var(--ds-radius-200, 8px);
50
- }
51
-
52
- .image > img {
53
- border-radius: inherit;
54
- }
55
-
56
35
  .editor {
57
36
  flex: 1 1 100%;
58
37
  padding: 10px;
@@ -7,10 +7,12 @@ type Props = {
7
7
  step: string;
8
8
  setStep: React.Dispatch<React.SetStateAction<string>>;
9
9
  stay: Types.Stay;
10
+ pax?: number;
11
+ locked?: boolean;
10
12
  completedSteps?: number[];
11
13
  setCompletedSteps?: React.Dispatch<React.SetStateAction<number[]>>;
12
14
  packageId: string;
13
15
  };
14
- export default function Widget({ index, config, widget, step, setStep, stay, completedSteps, setCompletedSteps, packageId, }: Props): import("react/jsx-runtime").JSX.Element;
16
+ export default function Widget({ index, config, widget, step, setStep, stay, pax, locked, completedSteps, setCompletedSteps, packageId, }: Props): import("react/jsx-runtime").JSX.Element;
15
17
  export {};
16
18
  //# sourceMappingURL=widget.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"widget.d.ts","sourceRoot":"","sources":["../../../../../src/future/components/msem-package/components/widget.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,KAAK,KAAK,MAAM,UAAU,CAAC;AAIvC,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;IACrB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;IACtD,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,iBAAiB,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACnE,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAuBF,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,EAC7B,KAAK,EACL,MAAM,EACN,MAAM,EACN,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,cAAc,EACd,iBAAiB,EACjB,SAAS,GACV,EAAE,KAAK,2CAmLP"}
1
+ {"version":3,"file":"widget.d.ts","sourceRoot":"","sources":["../../../../../src/future/components/msem-package/components/widget.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,KAAK,KAAK,KAAK,MAAM,UAAU,CAAC;AAIvC,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;IACrB,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;IACtD,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,iBAAiB,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACnE,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAuBF,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,EAC7B,KAAK,EACL,MAAM,EACN,MAAM,EACN,IAAI,EACJ,OAAO,EACP,IAAI,EACJ,GAAG,EACH,MAAM,EACN,cAAc,EACd,iBAAiB,EACjB,SAAS,GACV,EAAE,KAAK,2CAkQP"}