ublo-lib 1.49.11 → 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 (58) hide show
  1. package/es/esf/components/instant-search/services/api.d.ts.map +1 -1
  2. package/es/esf/components/instant-search/services/api.js +3 -1
  3. package/es/esf/components/instructors-book/api.d.ts.map +1 -1
  4. package/es/esf/components/instructors-book/api.js +2 -1
  5. package/es/future/components/msem-package/components/config.d.ts.map +1 -1
  6. package/es/future/components/msem-package/components/config.js +44 -18
  7. package/es/future/components/msem-package/components/filters.d.ts +5 -1
  8. package/es/future/components/msem-package/components/filters.d.ts.map +1 -1
  9. package/es/future/components/msem-package/components/filters.js +78 -15
  10. package/es/future/components/msem-package/components/filters.module.css +124 -20
  11. package/es/future/components/msem-package/components/global-settings.d.ts.map +1 -1
  12. package/es/future/components/msem-package/components/global-settings.js +2 -11
  13. package/es/future/components/msem-package/components/global-settings.module.css +2 -34
  14. package/es/future/components/msem-package/components/pax-settings.d.ts +9 -0
  15. package/es/future/components/msem-package/components/pax-settings.d.ts.map +1 -0
  16. package/es/future/components/msem-package/components/pax-settings.js +73 -0
  17. package/es/future/components/msem-package/components/pax-settings.module.css +48 -0
  18. package/es/future/components/msem-package/components/settings-ui.d.ts +23 -0
  19. package/es/future/components/msem-package/components/settings-ui.d.ts.map +1 -0
  20. package/es/future/components/msem-package/components/settings-ui.js +14 -0
  21. package/es/future/components/msem-package/components/settings-ui.module.css +152 -0
  22. package/es/future/components/msem-package/components/stay-settings.d.ts.map +1 -1
  23. package/es/future/components/msem-package/components/stay-settings.js +44 -25
  24. package/es/future/components/msem-package/components/stay-settings.module.css +21 -44
  25. package/es/future/components/msem-package/components/widget-dialog.d.ts.map +1 -1
  26. package/es/future/components/msem-package/components/widget-dialog.js +20 -12
  27. package/es/future/components/msem-package/components/widget-dialog.module.css +1 -22
  28. package/es/future/components/msem-package/components/widget.d.ts +3 -1
  29. package/es/future/components/msem-package/components/widget.d.ts.map +1 -1
  30. package/es/future/components/msem-package/components/widget.js +102 -36
  31. package/es/future/components/msem-package/components/widget.module.css +114 -51
  32. package/es/future/components/msem-package/components/widgets-settings.d.ts.map +1 -1
  33. package/es/future/components/msem-package/components/widgets-settings.js +22 -22
  34. package/es/future/components/msem-package/components/widgets-settings.module.css +95 -44
  35. package/es/future/components/msem-package/components/widgets.d.ts +3 -1
  36. package/es/future/components/msem-package/components/widgets.d.ts.map +1 -1
  37. package/es/future/components/msem-package/components/widgets.js +28 -13
  38. package/es/future/components/msem-package/core.d.ts.map +1 -1
  39. package/es/future/components/msem-package/core.js +13 -2
  40. package/es/future/components/msem-package/i18n/ca.json +17 -3
  41. package/es/future/components/msem-package/i18n/en.json +17 -3
  42. package/es/future/components/msem-package/i18n/es.json +17 -3
  43. package/es/future/components/msem-package/i18n/fr.json +17 -3
  44. package/es/future/components/msem-package/msem-package.module.css +29 -0
  45. package/es/future/components/msem-package/types.d.ts +12 -1
  46. package/es/future/components/msem-package/types.d.ts.map +1 -1
  47. package/es/future/components/msem-package/utils/pax.d.ts +3 -0
  48. package/es/future/components/msem-package/utils/pax.d.ts.map +1 -0
  49. package/es/future/components/msem-package/utils/pax.js +9 -0
  50. package/es/future/components/msem-preset-editor/editors/easyrent-rental.d.ts.map +1 -1
  51. package/es/future/components/msem-preset-editor/editors/easyrent-rental.js +1 -1
  52. package/es/future/components/msem-preset-editor/editors/ski-rental.d.ts.map +1 -1
  53. package/es/future/components/msem-preset-editor/editors/ski-rental.js +1 -1
  54. package/es/future/components/msem-preset-editor/msem-preset-editor.d.ts.map +1 -1
  55. package/es/future/components/msem-preset-editor/msem-preset-editor.js +1 -0
  56. package/es/market-place/components/instant-search/services/api.d.ts.map +1 -1
  57. package/es/market-place/components/instant-search/services/api.js +1 -1
  58. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../../../src/esf/components/instant-search/services/api.ts"],"names":[],"mappings":"AAKA,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,MAA+F,EACxG,cAAc,CAAC,EAAE,MAAM,gBAaxB"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../../../src/esf/components/instant-search/services/api.ts"],"names":[],"mappings":"AAOA,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,MAA+F,EACxG,cAAc,CAAC,EAAE,MAAM,gBAaxB"}
@@ -1,5 +1,7 @@
1
1
  import * as Fetcher from "../../../../common/utils/fetcher";
2
- const api = "https://search.ublo.app/api";
2
+ import getConfig from "next/config";
3
+ const { publicRuntimeConfig } = getConfig();
4
+ const { searchApi: api = "https://search.ublo.app/api" } = publicRuntimeConfig;
3
5
  export function fetchResults(site, lang, query, queryBy = "title,subtitle,text,pageTitle,seoKeywords,parentTitle,seoTitle,meetingPoint,imageAlt", queryByWeights) {
4
6
  const endpoint = `${api}/ublo-search/search/esf/v2`;
5
7
  return Fetcher.post(endpoint, {
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../../src/esf/components/instructors-book/api.js"],"names":[],"mappings":"AAgCA,qEAYC;AAED,mEASC;AAEM,8FAYN"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../../src/esf/components/instructors-book/api.js"],"names":[],"mappings":"AAgCA,qEAYC;AAED,mEAUC;AAEM,8FAYN"}
@@ -40,7 +40,8 @@ export async function fetchInstructors(lang, body = {}) {
40
40
  export async function fetchInstructor(lang, uri) {
41
41
  try {
42
42
  const url = `${carnetRougeApi}/annuaire/public/moniteur/${resort}/${lang}/${uri}`;
43
- return fetcher(url);
43
+ const { email, telephone, ...moniteur } = (await fetcher(url)) || {};
44
+ return moniteur;
44
45
  }
45
46
  catch (e) {
46
47
  console.warn(e);
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../../src/future/components/msem-package/components/config.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,KAAK,KAAK,MAAM,UAAU,CAAC;AAIvC,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,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,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,2CAsDpE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../../src/future/components/msem-package/components/config.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,KAAK,KAAK,MAAM,UAAU,CAAC;AAIvC,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,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,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,2CA+EpE"}
@@ -4,9 +4,31 @@ import { useMsemRuntime } from "../context";
4
4
  import styles from "./config.module.css";
5
5
  export default function Config({ idPrefix, config, setConfig }) {
6
6
  const ref = React.useRef(null);
7
- const { menuPath, lang, path, Zone } = useMsemRuntime();
7
+ const { menuPath, lang, path, Zone, cmsMode } = useMsemRuntime();
8
8
  const initializedRef = React.useRef(false);
9
9
  const prevRouteRef = React.useRef(`/${lang}${path}`);
10
+ const prevModeRef = React.useRef(cmsMode);
11
+ const originalConfigRef = React.useRef(null);
12
+ const parseZone = React.useCallback(() => {
13
+ const container = ref.current;
14
+ let script = container?.querySelector("script");
15
+ if (!script) {
16
+ script = Object.assign(document.createElement("script"), {
17
+ type: "application/json",
18
+ innerHTML: "{}",
19
+ });
20
+ container?.appendChild(script);
21
+ }
22
+ const storedConfig = script.textContent;
23
+ if (!storedConfig)
24
+ return null;
25
+ const parsed = JSON.parse(storedConfig);
26
+ return {
27
+ ...parsed,
28
+ id: parsed.id || `${idPrefix}-${menuPath?.id}`,
29
+ pax: parsed.pax ?? migratePaxPlan(parsed.paxPlan),
30
+ };
31
+ }, [idPrefix, menuPath?.id]);
10
32
  React.useEffect(() => {
11
33
  const route = `/${lang}${path}`;
12
34
  if (route !== prevRouteRef.current) {
@@ -14,26 +36,24 @@ export default function Config({ idPrefix, config, setConfig }) {
14
36
  initializedRef.current = false;
15
37
  }
16
38
  if (!initializedRef.current) {
17
- const container = ref.current;
18
- let script = container?.querySelector("script");
19
- if (!script) {
20
- script = Object.assign(document.createElement("script"), {
21
- type: "application/json",
22
- innerHTML: "{}",
23
- });
24
- container?.appendChild(script);
25
- }
26
- const storedConfig = script.textContent;
27
- if (storedConfig) {
28
- const parsed = JSON.parse(storedConfig);
29
- setConfig({
30
- ...parsed,
31
- id: parsed.id || `${idPrefix}-${menuPath?.id}`,
32
- });
39
+ const parsed = parseZone();
40
+ if (parsed) {
41
+ originalConfigRef.current = parsed;
42
+ setConfig(parsed);
33
43
  }
34
44
  initializedRef.current = true;
35
45
  }
36
- }, [lang, path, setConfig, idPrefix, menuPath?.id]);
46
+ }, [lang, path, parseZone, setConfig]);
47
+ React.useEffect(() => {
48
+ const prev = prevModeRef.current;
49
+ prevModeRef.current = cmsMode;
50
+ if (prev === "editing" && cmsMode && cmsMode !== "editing") {
51
+ const original = originalConfigRef.current;
52
+ const changed = !original || JSON.stringify(config) !== JSON.stringify(original);
53
+ if (changed)
54
+ window.location.reload();
55
+ }
56
+ }, [cmsMode, config]);
37
57
  React.useEffect(() => {
38
58
  const container = ref.current;
39
59
  if (initializedRef.current && container) {
@@ -45,3 +65,9 @@ export default function Config({ idPrefix, config, setConfig }) {
45
65
  }, [config]);
46
66
  return (_jsx(Zone, { ref: ref, id: "package-config", className: styles.zone, readOnly: true }));
47
67
  }
68
+ function migratePaxPlan(paxPlan) {
69
+ const value = Number(paxPlan);
70
+ if (!isNaN(value) && value > 0)
71
+ return { mode: "fixed", value };
72
+ return { mode: "unlimited" };
73
+ }
@@ -4,7 +4,11 @@ type Props = {
4
4
  config: Types.Config;
5
5
  stay: Types.Stay;
6
6
  setStay: React.Dispatch<React.SetStateAction<Types.Stay>>;
7
+ pax: number;
8
+ setPax: React.Dispatch<React.SetStateAction<number>>;
9
+ validated: boolean;
10
+ setValidated: React.Dispatch<React.SetStateAction<boolean>>;
7
11
  };
8
- export default function Filters({ config, stay, setStay }: Props): import("react/jsx-runtime").JSX.Element;
12
+ export default function Filters({ config, stay, setStay, pax, setPax, validated, setValidated, }: Props): import("react/jsx-runtime").JSX.Element;
9
13
  export {};
10
14
  //# sourceMappingURL=filters.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"filters.d.ts","sourceRoot":"","sources":["../../../../../src/future/components/msem-package/components/filters.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,OAAO,KAAK,KAAK,KAAK,MAAM,UAAU,CAAC;AAIvC,KAAK,KAAK,GAAG;IACX,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;IACrB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;CAC3D,CAAC;AAMF,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,2CA+I/D"}
1
+ {"version":3,"file":"filters.d.ts","sourceRoot":"","sources":["../../../../../src/future/components/msem-package/components/filters.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAW/B,OAAO,KAAK,KAAK,KAAK,MAAM,UAAU,CAAC;AAIvC,KAAK,KAAK,GAAG;IACX,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC;IACrB,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAC1D,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;IACrD,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;CAC7D,CAAC;AAMF,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,EAC9B,MAAM,EACN,IAAI,EACJ,OAAO,EACP,GAAG,EACH,MAAM,EACN,SAAS,EACT,YAAY,GACb,EAAE,KAAK,2CA0TP"}
@@ -1,41 +1,82 @@
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 * as React from "react";
3
3
  import { useMsemRuntime } from "../context";
4
4
  import Input from "dt-design-system/es/input";
5
+ import NumberPicker from "dt-design-system/es/number-picker";
5
6
  import Dropdown from "dt-design-system/es/dropdown";
7
+ import Dialog from "dt-design-system/es/dialog";
8
+ import Button from "dt-design-system/es/button";
9
+ import * as Icons from "dt-design-system/es/icons";
6
10
  import * as Utils from "../../../../common/components/date-picker/utils";
11
+ import * as DatePickerMessages from "../../../../common/components/date-picker/messages";
7
12
  import T, { t } from "../i18n/translations";
8
13
  import styles from "./filters.module.css";
9
- export default function Filters({ config, stay, setStay }) {
14
+ export default function Filters({ config, stay, setStay, pax, setPax, validated, setValidated, }) {
10
15
  const ref = React.useRef(null);
11
16
  const { lang, DatePicker } = useMsemRuntime();
12
17
  const [stayDates, setStayDates] = React.useState([]);
13
18
  const [datePickerOpen, setDatePickerOpen] = React.useState(false);
14
19
  const [datePickerOptions, setDatePickerOptions] = React.useState();
15
- const { from: min, to: max, forced, fixed, nbDays } = config.stay || {};
16
- const { paxPlan } = config;
20
+ const [pendingModify, setPendingModify] = React.useState(false);
21
+ const { from: min, to: max, forced, fixed, nbDays, hidden: stayHidden, } = config.stay || {};
22
+ const dated = config.stay?.dated ?? Boolean(min || max);
23
+ const paxMode = config.pax?.mode ?? "unlimited";
24
+ const paxHidden = Boolean(config.pax?.hidden);
25
+ const paxMin = config.pax?.min ?? 1;
26
+ const paxMax = config.pax?.max;
27
+ const paxValue = config.pax?.value;
28
+ const showDateInput = dated && !forced;
29
+ const showPaxInput = paxMode === "range" && !paxHidden;
30
+ const needsChoice = showDateInput || showPaxInput;
31
+ const editing = needsChoice && !validated;
17
32
  const usedMax = fixed
18
33
  ? Utils.getDateISO(Utils.addDays(max, -nbDays + 1))
19
34
  : max;
35
+ const fmt = (iso) => (iso ? Utils.weekToLongDate(iso) : "");
36
+ const diffDays = (a, b) => a && b
37
+ ? Math.max(1, Math.round((new Date(b).getTime() - new Date(a).getTime()) / 86400000))
38
+ : 0;
39
+ const staySummary = (() => {
40
+ if (!dated || stayHidden)
41
+ return null;
42
+ const from = stay?.from ?? min;
43
+ const to = stay?.to ?? max;
44
+ if (!from || !to)
45
+ return null;
46
+ const days = diffDays(from, to);
47
+ return `${days} ${t(lang, "filters.day")}${days > 1 ? "s" : ""} - ${t(lang, "filters.from")} ${fmt(from)} ${t(lang, "filters.to")} ${fmt(to)}`;
48
+ })();
49
+ const paxSummary = (() => {
50
+ const n = paxMode === "fixed" ? paxValue : paxMode === "range" ? pax : undefined;
51
+ if (paxHidden || n == null)
52
+ return null;
53
+ const people = t(lang, n > 1 ? "filters.people" : "filters.person");
54
+ return `${t(lang, "filters.for")} ${n} ${people}`;
55
+ })();
56
+ const canValidate = (!showDateInput || Boolean(stay?.from && stay?.to)) &&
57
+ (!showPaxInput || pax != null);
20
58
  React.useEffect(() => {
21
59
  if (forced) {
22
60
  setStay({ from: min, to: usedMax });
23
61
  }
24
62
  }, [forced, usedMax, min, setStay]);
25
63
  React.useEffect(() => {
26
- if (stay) {
27
- const { from, to } = stay;
28
- const fromDate = new Date(from);
64
+ if (showPaxInput && pax == null) {
65
+ setPax(paxMin);
66
+ }
67
+ }, [showPaxInput, pax, paxMin, setPax]);
68
+ React.useEffect(() => {
69
+ if (stay?.from && stay?.to) {
70
+ const fromDate = new Date(stay.from);
29
71
  fromDate.setHours(0, 0, 0, 0);
30
- const toDate = new Date(to);
72
+ const toDate = new Date(stay.to);
31
73
  toDate.setHours(0, 0, 0, 0);
32
- const interval = Utils.getDateInterval(fromDate, toDate);
33
- setStayDates(interval);
74
+ setStayDates(Utils.getDateInterval(fromDate, toDate));
34
75
  }
35
76
  }, [stay]);
36
77
  const scrollToFilters = () => {
37
78
  window.requestAnimationFrame(() => {
38
- ref.current.scrollIntoView({ behavior: "smooth" });
79
+ ref.current?.scrollIntoView({ behavior: "smooth" });
39
80
  });
40
81
  };
41
82
  const openDatePicker = (options = {}) => {
@@ -54,10 +95,32 @@ export default function Filters({ config, stay, setStay }) {
54
95
  const to = fixed
55
96
  ? Utils.getDateISO(Utils.addDays(data[0], nbDays - 1))
56
97
  : Utils.getDateISO(data[data.length - 1]);
57
- const newStay = { from, to };
58
- setStay(newStay);
98
+ setStay({ from, to });
59
99
  closeDatePicker();
60
100
  };
61
- const titleKey = forced ? "filters.fixed-title" : "filters.title";
62
- return (_jsx("div", { ref: ref, className: styles.filters, style: { display: forced ? "none" : "block" }, children: _jsxs("div", { className: styles.form, children: [_jsx("div", { className: styles.title, children: _jsx(T, { id: titleKey }) }), fixed && (_jsxs("div", { className: styles.subtitle, children: [_jsx(T, { id: "filters.subtitle" }), " ", _jsxs("span", { className: styles.bold, children: [nbDays, " ", _jsx(T, { id: "filters.day" }), nbDays > 1 ? "s" : ""] })] })), _jsxs("div", { className: styles.inner, children: [_jsx(Dropdown, { open: datePickerOpen, onClose: closeDatePicker, onOpenChange: (open) => setDatePickerOpen(open), breakpoint: 600, content: _jsx(DatePicker, { stayDates: stayDates, popup: false, close: closeDatePicker, onSubmit: updateStay, min: min, max: usedMax, singleDate: fixed, submitOnSelectionEnd: fixed, ...datePickerOptions }), children: _jsx(Input, { type: "text", icon: "Calendar", className: styles.field, label: t(lang, "filters.stay-from-label"), placeholder: t(lang, "filters.stay-from-placeholder"), value: stay?.from ? Utils.weekToLongDate(stay.from) : "", onClick: () => openDatePicker(), readOnly: true, disabled: forced }) }, JSON.stringify(datePickerOptions)), _jsx(Input, { type: "text", icon: "Calendar", className: styles.field, label: t(lang, "filters.stay-to-label"), placeholder: t(lang, "filters.stay-to-placeholder"), value: stay?.to ? Utils.weekToLongDate(stay?.to || "") : "", onClick: () => openDatePicker({ defaultSelecting: true }), readOnly: true, disabled: forced || fixed || !stay?.from }), _jsxs("div", { className: styles.pax, children: [_jsx(Input, { icon: "User", type: "number", label: t(lang, "filters.pax"), className: styles.field, value: paxPlan || "", disabled: true }), _jsxs("span", { className: styles.paxMessage, children: [_jsx(T, { id: "filters.pax-message" }), " ", paxPlan] })] })] })] }) }));
101
+ const updatePax = (value) => setPax(value);
102
+ const onValidate = () => setValidated(true);
103
+ const onModify = () => {
104
+ const hasCart = window.sessionStorage.cartId !== undefined;
105
+ if (hasCart)
106
+ setPendingModify(true);
107
+ else
108
+ setValidated(false);
109
+ };
110
+ const confirmModify = () => {
111
+ setPendingModify(false);
112
+ setValidated(false);
113
+ };
114
+ const cancelModify = () => setPendingModify(false);
115
+ const renderSummaryItems = (stayText, paxText) => (_jsxs(_Fragment, { children: [stayText && (_jsxs("span", { className: styles.summaryItem, children: [_jsx(Icons.Calendar, { className: styles.summaryIcon }), stayText] })), paxText && (_jsxs("span", { className: styles.summaryItem, children: [_jsx(Icons.User, { className: styles.summaryIcon }), paxText] }))] }));
116
+ const editStaySummary = !showDateInput ? staySummary : null;
117
+ const editPaxSummary = !showPaxInput ? paxSummary : null;
118
+ if (!editing) {
119
+ if (!staySummary && !paxSummary)
120
+ return null;
121
+ return (_jsxs("div", { ref: ref, className: styles.filters, children: [_jsxs("div", { className: styles.summaryBar, children: [_jsx("div", { className: styles.summaryItems, children: renderSummaryItems(staySummary, paxSummary) }), needsChoice && (_jsxs("button", { type: "button", className: styles.modify, onClick: onModify, children: [_jsx(Icons.Edit, { className: styles.modifyIcon }), t(lang, "filters.modify")] }))] }), pendingModify && (_jsxs(Dialog, { isOpened: true, className: styles.confirmDialog, close: cancelModify, showCloseButton: false, children: [_jsx("div", { className: styles.confirmTitle, children: DatePickerMessages.get(lang, "warning-date-change-title") }), _jsx("div", { className: styles.confirmMessage, children: DatePickerMessages.get(lang, "warning-date-change-text") }), _jsxs("div", { className: styles.confirmButtons, children: [_jsx(Button, { variant: "transparent", onClick: cancelModify, children: DatePickerMessages.get(lang, "warning-date-change-cancel") }), _jsx(Button, { onClick: confirmModify, children: DatePickerMessages.get(lang, "warning-date-change-confirm") })] })] }))] }));
122
+ }
123
+ return (_jsx("div", { ref: ref, className: styles.filters, children: _jsxs("div", { className: styles.form, children: [_jsx("div", { className: styles.title, children: _jsx(T, { id: "filters.title" }) }), fixed && showDateInput && (_jsxs("div", { className: styles.subtitle, children: [_jsx(T, { id: "filters.subtitle" }), " ", _jsxs("span", { className: styles.bold, children: [nbDays, " ", _jsx(T, { id: "filters.day" }), nbDays > 1 ? "s" : ""] })] })), (editStaySummary || editPaxSummary) && (_jsx("div", { className: styles.summary, children: renderSummaryItems(editStaySummary, editPaxSummary) })), _jsxs("div", { className: styles.bottom, children: [_jsxs("div", { className: styles.inner, children: [showDateInput && (_jsxs(_Fragment, { children: [_jsx(Dropdown, { open: datePickerOpen, onClose: closeDatePicker, onOpenChange: (open) => setDatePickerOpen(open), breakpoint: 600, content: _jsx(DatePicker, { lang: lang, stayDates: stayDates, popup: false, close: closeDatePicker, onSubmit: updateStay, min: min, max: usedMax, singleDate: fixed, submitOnSelectionEnd: fixed, disableConfirmModal: true, ...datePickerOptions }), children: _jsx(Input, { type: "text", icon: "Calendar", className: styles.field, label: t(lang, "filters.stay-from-label"), placeholder: t(lang, "filters.stay-from-placeholder"), value: stay?.from ? Utils.weekToLongDate(stay.from) : "", onClick: () => openDatePicker(), readOnly: true }) }, JSON.stringify(datePickerOptions)), _jsx(Input, { type: "text", icon: "Calendar", className: styles.field, label: t(lang, "filters.stay-to-label"), placeholder: t(lang, "filters.stay-to-placeholder"), value: stay?.to ? Utils.weekToLongDate(stay?.to || "") : "", onClick: fixed || !stay?.from
124
+ ? undefined
125
+ : () => openDatePicker({ defaultSelecting: true }), readOnly: true, disabled: fixed || !stay?.from })] })), showPaxInput && (_jsxs("div", { className: styles.pax, children: [_jsx("span", { className: styles.paxLabel, children: t(lang, "filters.pax") }), _jsx(NumberPicker, { min: paxMin, max: paxMax, value: pax ?? paxMin, onChange: updatePax, withInput: true })] }))] }), _jsxs(Button, { className: styles.validate, onClick: onValidate, disabled: !canValidate, children: [_jsx(Icons.Check, {}), t(lang, "filters.validate")] })] })] }) }));
63
126
  }
@@ -1,23 +1,15 @@
1
1
  .filters {
2
- padding: 10px;
3
- background-color: var(--ds-grey-100, #f8f8f8);
4
- border-radius: var(--ds-radius-200, 8px);
5
- }
6
-
7
- @media (min-width: 1320px) {
8
- .filters {
9
- padding: 40px 10px;
10
- border-radius: 0;
11
- }
2
+ width: 100%;
12
3
  }
13
4
 
5
+ /* Carte "Choisissez vos dates" (mode édition) */
14
6
  .form {
15
- width: min(100%, 900px);
7
+ width: min(calc(100% - 20px), 1100px);
16
8
  display: flex;
17
9
  flex-direction: column;
18
- gap: 8px;
10
+ gap: 12px;
19
11
  margin: 0 auto;
20
- padding: 16px;
12
+ padding: 20px;
21
13
  background-color: var(--ds-grey-000, #fff);
22
14
  border: 1px solid var(--ds-grey-200, #ededed);
23
15
  border-radius: var(--ds-radius-200, 8px);
@@ -27,38 +19,150 @@
27
19
  font-size: 17px;
28
20
  font-weight: 700;
29
21
  }
22
+
30
23
  .subtitle {
31
24
  font-size: 15px;
32
- margin-bottom: 8px;
33
25
  }
26
+
34
27
  .bold {
35
28
  font-weight: 700;
36
29
  }
30
+
31
+ /* Barre de résumé (paramètres validés / sans choix) */
32
+ .summaryBar {
33
+ width: min(calc(100% - 20px), 1100px);
34
+ display: flex;
35
+ flex-wrap: wrap;
36
+ align-items: center;
37
+ gap: 8px 20px;
38
+ margin: 0 auto;
39
+ padding: 16px 20px;
40
+ background-color: var(--ds-grey-100, #f8f8f8);
41
+ border-radius: var(--ds-radius-200, 8px);
42
+ }
43
+
44
+ .summaryItems {
45
+ display: flex;
46
+ flex: 1 1 auto;
47
+ flex-wrap: wrap;
48
+ gap: 6px 24px;
49
+ }
50
+
51
+ /* Ligne de résumé des choix figés (dans la carte d'édition) */
52
+ .summary {
53
+ display: flex;
54
+ flex-wrap: wrap;
55
+ gap: 6px 24px;
56
+ }
57
+
58
+ .summaryItem {
59
+ display: inline-flex;
60
+ align-items: center;
61
+ gap: 8px;
62
+ font-size: 14px;
63
+ font-weight: 600;
64
+ color: var(--ds-grey-800, #000);
65
+ }
66
+
67
+ .summaryIcon {
68
+ width: 16px;
69
+ height: 16px;
70
+ flex: 0 0 16px;
71
+ fill: currentcolor;
72
+ }
73
+
74
+ /* Bouton "Modifier" dans la barre de résumé */
75
+ .modify {
76
+ display: inline-flex;
77
+ align-items: center;
78
+ gap: 6px;
79
+ padding: 0;
80
+ font: inherit;
81
+ font-size: 14px;
82
+ font-weight: 700;
83
+ color: var(--ds-secondary, var(--ds-primary, #002dcc));
84
+ background: none;
85
+ border: 0;
86
+ cursor: pointer;
87
+ white-space: nowrap;
88
+ }
89
+
90
+ .modifyIcon {
91
+ width: 16px;
92
+ height: 16px;
93
+ fill: currentcolor;
94
+ }
95
+
96
+ /* Champs + bouton "Valider" sur la même ligne */
97
+ .bottom {
98
+ display: flex;
99
+ flex-wrap: wrap;
100
+ align-items: flex-end;
101
+ gap: 16px;
102
+ margin-top: 4px;
103
+ }
104
+
37
105
  .inner {
38
106
  display: flex;
107
+ flex: 1 1 auto;
39
108
  flex-direction: column;
40
- gap: 8px;
109
+ gap: 12px;
41
110
  }
42
111
 
43
112
  @media (min-width: 640px) {
44
113
  .inner {
45
114
  flex-direction: row;
115
+ align-items: flex-end;
46
116
  }
47
117
  }
48
118
 
119
+ /* Champs dates : partagent l'espace */
49
120
  .field {
50
121
  --ds-input-padding: 13px;
51
122
 
52
- flex: 1 1 auto;
123
+ flex: 1 1 0;
124
+ min-width: 0;
125
+ width: 100%;
53
126
  }
54
127
 
128
+ /* PAX : stepper compact (pas étiré) */
55
129
  .pax {
56
130
  display: flex;
131
+ flex: 0 0 auto;
57
132
  flex-direction: column;
58
- gap: 4px;
133
+ gap: 6px;
134
+ }
135
+
136
+ .paxLabel {
137
+ font-size: 13px;
138
+ color: var(--ds-grey-500, #7c7b7b);
139
+ }
140
+
141
+ /* Bouton "Valider" (à droite des champs) */
142
+ .validate {
143
+ flex: 0 0 auto;
144
+ margin-left: auto;
59
145
  }
60
146
 
61
- .paxMessage {
62
- font-size: 12px;
63
- color: var(--ds-grey-600, #484848);
147
+ /* Confirmation suppression du pack (bouton "Modifier") */
148
+ .confirmDialog {
149
+ max-width: 440px;
150
+ padding: 24px;
151
+ }
152
+
153
+ .confirmTitle {
154
+ font-size: 18px;
155
+ font-weight: 700;
156
+ }
157
+
158
+ .confirmMessage {
159
+ margin: 8px 0 20px;
160
+ font-size: 15px;
161
+ line-height: 1.4;
162
+ }
163
+
164
+ .confirmButtons {
165
+ display: flex;
166
+ justify-content: flex-end;
167
+ gap: 8px;
64
168
  }
@@ -1 +1 @@
1
- {"version":3,"file":"global-settings.d.ts","sourceRoot":"","sources":["../../../../../src/future/components/msem-package/components/global-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;AAYF,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,2CAyDlE"}
1
+ {"version":3,"file":"global-settings.d.ts","sourceRoot":"","sources":["../../../../../src/future/components/msem-package/components/global-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;AAOF,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,2CAoClE"}
@@ -2,15 +2,12 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import Select from "dt-design-system/es/select";
3
3
  import Input from "dt-design-system/es/input";
4
4
  import * as Icons from "dt-design-system/es/icons";
5
+ import { Card } from "./settings-ui";
5
6
  import styles from "./global-settings.module.css";
6
7
  const FACET_OPTIONS = [
7
8
  { value: "0", label: "Hiver" },
8
9
  { value: "1", label: "Été" },
9
10
  ];
10
- const PAX = {
11
- MIN: 0,
12
- MAX: 20,
13
- };
14
11
  export default function GlobalSettings({ config, setConfig }) {
15
12
  const updateName = (value) => {
16
13
  setConfig((prev) => ({ ...prev, name: value }));
@@ -19,11 +16,5 @@ export default function GlobalSettings({ config, setConfig }) {
19
16
  const facet = Number(value);
20
17
  setConfig((prev) => ({ ...prev, facet }));
21
18
  };
22
- const updatePaxPlan = (value) => {
23
- const paxPlan = isNaN(Number(value))
24
- ? 0
25
- : Math.min(Math.max(Number(value), PAX.MIN), PAX.MAX);
26
- setConfig((prev) => ({ ...prev, paxPlan }));
27
- };
28
- return (_jsxs("div", { className: styles.container, children: [_jsxs("div", { className: styles.title, children: [_jsx(Icons.Tune, {}), "Param\u00E8tres g\u00E9n\u00E9raux"] }), _jsxs("div", { className: styles.settings, children: [_jsx(Input, { label: "Nom du package", value: config.name, onValueChange: updateName, className: styles.field }), _jsx(Input, { label: "Identifiant", value: config.id, onValueChange: updateName, className: styles.field, disabled: true }), _jsx(Select, { label: "Facette", placeholder: "Choisissez une facette", options: FACET_OPTIONS, value: config.facet, onValueChange: updateFacet, className: styles.field }), _jsx(Input, { type: "number", label: "Nombre de personne(s)", value: config.paxPlan || "0", onValueChange: updatePaxPlan, className: styles.field, min: "0", max: "20" })] })] }));
19
+ return (_jsx(Card, { icon: _jsx(Icons.Settings, {}), title: "G\u00E9n\u00E9ral", children: _jsxs("div", { className: styles.settings, children: [_jsx(Input, { label: "Nom du package", value: config.name, onValueChange: updateName, className: styles.field }), _jsx(Input, { label: "Identifiant", value: config.id, className: styles.field, disabled: true }), _jsx(Select, { label: "Facette", placeholder: "Choisissez une facette", options: FACET_OPTIONS, value: config.facet, onValueChange: updateFacet, className: styles.field })] }) }));
29
20
  }
@@ -1,42 +1,10 @@
1
- .container {
2
- width: min(calc(100% - 20px), 840px);
3
- 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
1
  .settings {
28
2
  display: flex;
29
3
  align-items: flex-end;
30
4
  flex-wrap: wrap;
31
- gap: 12px 6px;
5
+ gap: 12px;
32
6
  }
33
7
 
34
8
  .field {
35
- flex: 1 1 auto;
36
- }
37
-
38
- @media (width > 700px) {
39
- .field {
40
- flex: 1 1 49%;
41
- }
9
+ flex: 1 1 220px;
42
10
  }
@@ -0,0 +1,9 @@
1
+ import * as React from "react";
2
+ import type * as Types from "../types";
3
+ type Props = {
4
+ config: Types.Config;
5
+ setConfig: React.Dispatch<React.SetStateAction<Types.Config>>;
6
+ };
7
+ export default function PaxSettings({ config, setConfig }: Props): import("react/jsx-runtime").JSX.Element;
8
+ export {};
9
+ //# sourceMappingURL=pax-settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pax-settings.d.ts","sourceRoot":"","sources":["../../../../../src/future/components/msem-package/components/pax-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;AAOF,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,2CAsG/D"}
@@ -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
+ }