ublo-lib 1.0.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.
- package/es/common/components/admin-links/admin-links.js +107 -0
- package/es/common/components/admin-links/admin-links.module.css +85 -0
- package/es/common/components/admin-links/index.js +2 -0
- package/es/common/components/analytics.js +46 -0
- package/es/common/components/breadcrumb.js +69 -0
- package/es/common/components/carousel-zone.js +61 -0
- package/es/common/components/carousel.js +365 -0
- package/es/common/components/cookie-consent/cookie-consent.js +111 -0
- package/es/common/components/cookie-consent/cookie-consent.module.css +103 -0
- package/es/common/components/cookie-consent/index.js +3 -0
- package/es/common/components/cookie-consent/messages.js +31 -0
- package/es/common/components/custom-contact-form/attachment.js +229 -0
- package/es/common/components/custom-contact-form/attachment.module.css +211 -0
- package/es/common/components/custom-contact-form/custom-contact-form.js +168 -0
- package/es/common/components/custom-contact-form/field.js +294 -0
- package/es/common/components/custom-contact-form/field.module.css +17 -0
- package/es/common/components/custom-contact-form/icons.js +55 -0
- package/es/common/components/custom-contact-form/index.js +2 -0
- package/es/common/components/custom-contact-form/index.module.css +119 -0
- package/es/common/components/custom-contact-form/messages.js +79 -0
- package/es/common/components/custom-contact-form/utils.js +132 -0
- package/es/common/components/date-picker/calendar.js +246 -0
- package/es/common/components/date-picker/calendar.module.css +123 -0
- package/es/common/components/date-picker/data.js +96 -0
- package/es/common/components/date-picker/date-item.js +127 -0
- package/es/common/components/date-picker/date-item.module.css +78 -0
- package/es/common/components/date-picker/date-picker.js +119 -0
- package/es/common/components/date-picker/date-picker.module.css +111 -0
- package/es/common/components/date-picker/helper.js +41 -0
- package/es/common/components/date-picker/helper.module.css +81 -0
- package/es/common/components/date-picker/index.js +3 -0
- package/es/common/components/date-picker/messages.js +34 -0
- package/es/common/components/date-picker/modes.js +42 -0
- package/es/common/components/date-picker/modes.module.css +90 -0
- package/es/common/components/date-picker/month.js +78 -0
- package/es/common/components/date-picker/month.module.css +54 -0
- package/es/common/components/date-picker/utils.js +121 -0
- package/es/common/components/error-404/error-404.js +51 -0
- package/es/common/components/error-404/error-404.module.css +55 -0
- package/es/common/components/error-404/index.js +2 -0
- package/es/common/components/error-404/messages.js +29 -0
- package/es/common/components/faq.js +54 -0
- package/es/common/components/info-buttons.js +116 -0
- package/es/common/components/plausible/hooks/use-plausible.js +33 -0
- package/es/common/components/plausible/index.js +7 -0
- package/es/common/components/plausible/plausible.js +20 -0
- package/es/common/components/plausible/services/callback.js +63 -0
- package/es/common/components/plausible/services/load.js +7 -0
- package/es/common/components/plausible/services/send-goal.js +10 -0
- package/es/common/components/popup.js +90 -0
- package/es/common/components/scroll-spy.js +53 -0
- package/es/common/components/tabbed-zones.js +110 -0
- package/es/common/components/unsupported-browser.js +158 -0
- package/es/common/components/video-player/controls.js +125 -0
- package/es/common/components/video-player/icons.js +45 -0
- package/es/common/components/video-player/index.js +1 -0
- package/es/common/components/video-player/player.module.css +151 -0
- package/es/common/components/video-player/utils.js +43 -0
- package/es/common/components/video-player/video-player.js +111 -0
- package/es/common/hooks/use-faq.js +44 -0
- package/es/common/hooks/use-in-view.js +73 -0
- package/es/common/hooks/use-injected-cms-markup.js +50 -0
- package/es/common/hooks/use-packages.js +127 -0
- package/es/common/hooks/use-scroll-direction.js +44 -0
- package/es/common/hooks/use-stay.js +32 -0
- package/es/common/hooks/use-sticky.js +38 -0
- package/es/common/hooks/use-tunnel.js +50 -0
- package/es/common/hooks/use-window-sizes.js +37 -0
- package/es/common/hooks/use-youtube-popup.js +62 -0
- package/es/common/hooks/use-zone-sync.js +65 -0
- package/es/common/utils/cookies.js +13 -0
- package/es/common/utils/copy.js +11 -0
- package/es/common/utils/dates.js +8 -0
- package/es/common/utils/events.js +25 -0
- package/es/common/utils/fetcher.js +37 -0
- package/es/common/utils/file-manager.js +14 -0
- package/es/common/utils/load-js.js +11 -0
- package/es/common/utils/msem-widget.js +16 -0
- package/es/common/utils/touch-device.js +1 -0
- package/es/common/utils/url-parameters.js +12 -0
- package/es/empty.d.ts +4 -0
- package/es/empty.d.ts.map +1 -0
- package/es/empty.js +6 -0
- package/es/esf/components/booking-form/data.js +213 -0
- package/es/esf/components/booking-form/field.js +140 -0
- package/es/esf/components/booking-form/hooks/use-custom-fields.js +20 -0
- package/es/esf/components/booking-form/hooks/use-stay.js +12 -0
- package/es/esf/components/booking-form/icons.js +50 -0
- package/es/esf/components/booking-form/index.js +78 -0
- package/es/esf/components/booking-form/lesson.js +59 -0
- package/es/esf/components/booking-form/lessons.js +93 -0
- package/es/esf/components/booking-form/messages.js +52 -0
- package/es/esf/components/booking-form/personal-data.js +73 -0
- package/es/esf/components/booking-form/progress-bar.js +35 -0
- package/es/esf/components/booking-form/response.js +42 -0
- package/es/esf/components/booking-form/steps.js +81 -0
- package/es/esf/components/booking-form/summary.js +138 -0
- package/es/esf/components/booking-form/utils.js +72 -0
- package/es/esf/components/contact-form/api.js +36 -0
- package/es/esf/components/contact-form/contact-form.js +293 -0
- package/es/esf/components/contact-form/contact-form.module.css +51 -0
- package/es/esf/components/contact-form/data.js +53 -0
- package/es/esf/components/contact-form/index.js +2 -0
- package/es/esf/components/contact-form/messages.js +75 -0
- package/es/esf/components/contact-form/validation.js +63 -0
- package/es/esf/components/covid-link/index.js +119 -0
- package/es/esf/components/covid-link/index.module.css +108 -0
- package/es/esf/components/covid-link/mask-icon.js +17 -0
- package/es/esf/components/covid-link/vax-pass-icon.js +34 -0
- package/es/esf/components/cp-form.js +65 -0
- package/es/esf/components/instructor-suggestions/fetcher.js +17 -0
- package/es/esf/components/instructor-suggestions/icons.js +266 -0
- package/es/esf/components/instructor-suggestions/index.js +181 -0
- package/es/esf/components/instructor-suggestions/loader.js +10 -0
- package/es/esf/components/instructor-suggestions/messages.js +16 -0
- package/es/esf/components/instructors-book/container.js +18 -0
- package/es/esf/components/instructors-book/details.js +120 -0
- package/es/esf/components/instructors-book/icons.js +266 -0
- package/es/esf/components/instructors-book/index.js +15 -0
- package/es/esf/components/instructors-book/link.js +17 -0
- package/es/esf/components/instructors-book/list-utils.js +21 -0
- package/es/esf/components/instructors-book/list.js +184 -0
- package/es/esf/components/instructors-book/loader.js +10 -0
- package/es/esf/components/instructors-book/messages.js +44 -0
- package/es/esf/components/instructors-book/utils.js +5 -0
- package/es/esf/components/levels.js +265 -0
- package/es/esf/components/loyal-customers/api.js +24 -0
- package/es/esf/components/loyal-customers/components/bin-icon.js +31 -0
- package/es/esf/components/loyal-customers/components/bin-icon.module.css +9 -0
- package/es/esf/components/loyal-customers/components/customer-form.js +105 -0
- package/es/esf/components/loyal-customers/components/customer-form.module.css +40 -0
- package/es/esf/components/loyal-customers/components/field.js +119 -0
- package/es/esf/components/loyal-customers/components/field.module.css +3 -0
- package/es/esf/components/loyal-customers/components/row.js +77 -0
- package/es/esf/components/loyal-customers/components/row.module.css +95 -0
- package/es/esf/components/loyal-customers/components/rows.js +38 -0
- package/es/esf/components/loyal-customers/components/rows.module.css +11 -0
- package/es/esf/components/loyal-customers/components/stay.js +37 -0
- package/es/esf/components/loyal-customers/components/stay.module.css +18 -0
- package/es/esf/components/loyal-customers/components/student-form.js +105 -0
- package/es/esf/components/loyal-customers/components/student-form.module.css +68 -0
- package/es/esf/components/loyal-customers/components/voucher.js +26 -0
- package/es/esf/components/loyal-customers/components/voucher.module.css +7 -0
- package/es/esf/components/loyal-customers/content.js +55 -0
- package/es/esf/components/loyal-customers/data.js +131 -0
- package/es/esf/components/loyal-customers/hooks/use-stored-rows.js +14 -0
- package/es/esf/components/loyal-customers/index.js +2 -0
- package/es/esf/components/loyal-customers/loyal-customers.js +141 -0
- package/es/esf/components/loyal-customers/loyal-customers.module.css +62 -0
- package/es/esf/components/loyal-customers/messages.js +59 -0
- package/es/esf/components/loyal-customers/utils.js +81 -0
- package/es/esf/components/village-maps/icons.js +35 -0
- package/es/esf/components/village-maps/index.js +214 -0
- package/es/esf/components/village-maps/messages.js +19 -0
- package/es/esf/components/village-maps/utils.js +26 -0
- package/es/esf/components/week-picker/index.js +244 -0
- package/es/esf/components/week-picker/messages.js +36 -0
- package/es/esf/components/week-picker/utils.js +65 -0
- package/es/esf/components/week-picker/week.js +52 -0
- package/es/esf/components/week-picker-2/index.js +283 -0
- package/es/esf/components/week-picker-2/messages.js +27 -0
- package/es/esf/components/week-picker-2/utils.js +65 -0
- package/es/esf/components/week-picker-2/week.js +55 -0
- package/es/esf/hooks/use-affiliation.js +26 -0
- package/es/esf/hooks/use-booking-links.js +36 -0
- package/es/esf/hooks/use-reviews.js +28 -0
- package/es/esf/hooks/use-season-products.js +100 -0
- package/package.json +51 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { memo, useState, useEffect, useCallback, useRef, createRef } from "react";
|
|
3
|
+
import classnames from "classnames";
|
|
4
|
+
import Week from "./week";
|
|
5
|
+
import { weekToLongDate, weekToDate, formatDate } from "./utils";
|
|
6
|
+
import messages from "./messages";
|
|
7
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
|
+
import { Fragment as _Fragment } from "react/jsx-runtime";
|
|
10
|
+
const WEEK_STORAGE = "stayWeek";
|
|
11
|
+
const LEFT = 0;
|
|
12
|
+
const RIGHT = 1;
|
|
13
|
+
|
|
14
|
+
const buildWeeks = (start, end) => {
|
|
15
|
+
const length = end - start;
|
|
16
|
+
const array = [];
|
|
17
|
+
|
|
18
|
+
for (let i = 0; i < length; i++) {
|
|
19
|
+
array.push(start + i);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return array;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const getFiltrableSections = () => Array.from(document.querySelectorAll("section[data-weeks]"));
|
|
26
|
+
|
|
27
|
+
const removeSectionFilters = () => {
|
|
28
|
+
const filtrables = getFiltrableSections();
|
|
29
|
+
filtrables.forEach(section => {
|
|
30
|
+
if (section.originalDisplayStyle !== undefined) {
|
|
31
|
+
section.style.display = section.originalDisplayStyle;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const filterSections = week => {
|
|
37
|
+
const search = String(week);
|
|
38
|
+
const filtrables = getFiltrableSections();
|
|
39
|
+
filtrables.forEach(section => {
|
|
40
|
+
const weeks = section.dataset.weeks.split(",").filter(week => week !== "");
|
|
41
|
+
const visible = weeks.length === 0 || weeks.indexOf(search) !== -1;
|
|
42
|
+
|
|
43
|
+
if (section.originalDisplayStyle === undefined) {
|
|
44
|
+
section.originalDisplayStyle = section.style.display;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
section.style.display = visible ? section.originalDisplayStyle : "none";
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const WeekPicker = ({
|
|
52
|
+
lang,
|
|
53
|
+
start,
|
|
54
|
+
end,
|
|
55
|
+
setClosed,
|
|
56
|
+
cmsMode,
|
|
57
|
+
customMessages,
|
|
58
|
+
noRoughValidation = false,
|
|
59
|
+
force = false,
|
|
60
|
+
forceSeasonSwitch = false,
|
|
61
|
+
onChange
|
|
62
|
+
}) => {
|
|
63
|
+
const [isBrowser, setBrowser] = useState(false);
|
|
64
|
+
const [warn, setWarn] = useState(-1);
|
|
65
|
+
const [opened, setOpened] = useState(true);
|
|
66
|
+
const [selected, setSelected] = useState();
|
|
67
|
+
const previous = createRef();
|
|
68
|
+
const ref = useRef();
|
|
69
|
+
const mustFilterSections = cmsMode === undefined;
|
|
70
|
+
const texts = messages(lang, customMessages);
|
|
71
|
+
const weekPickerTitle = texts["week-picker-title"];
|
|
72
|
+
const weekPickedSelectedTitle = texts["week-picker-selected-title"];
|
|
73
|
+
const weekPickerWarn = texts["week-picker-warn"];
|
|
74
|
+
const weekPickerOk = texts["week-picker-ok"];
|
|
75
|
+
const weekPickerCancel = texts["week-picker-cancel"];
|
|
76
|
+
const weeks = buildWeeks(start, end);
|
|
77
|
+
const endWeek = weeks[weeks.length - 1];
|
|
78
|
+
const beginWeek = weeks[0];
|
|
79
|
+
const showDialog = force && selected === null;
|
|
80
|
+
const pickerClasses = classnames("week-picker", {
|
|
81
|
+
"week-picker--dialog-opened": showDialog && mustFilterSections,
|
|
82
|
+
"week-picker--inline": force,
|
|
83
|
+
"week-picker--editing": !mustFilterSections
|
|
84
|
+
});
|
|
85
|
+
const selectWeek = useCallback((week, force = false) => {
|
|
86
|
+
const hasCart = sessionStorage.cartId !== undefined;
|
|
87
|
+
|
|
88
|
+
if (force || !hasCart) {
|
|
89
|
+
if (previous.current !== undefined && previous.current !== null && previous.current !== week) {
|
|
90
|
+
sessionStorage.removeItem("cartId");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
setWarn(-1);
|
|
94
|
+
setSelected(week);
|
|
95
|
+
previous.current = week;
|
|
96
|
+
|
|
97
|
+
if (mustFilterSections && week !== null && week !== undefined) {
|
|
98
|
+
filterSections(week, mustFilterSections);
|
|
99
|
+
} else {
|
|
100
|
+
removeSectionFilters();
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
setWarn(week);
|
|
104
|
+
}
|
|
105
|
+
}, [mustFilterSections]);
|
|
106
|
+
useEffect(() => {
|
|
107
|
+
if (!mustFilterSections) {
|
|
108
|
+
removeSectionFilters();
|
|
109
|
+
}
|
|
110
|
+
}, [mustFilterSections]);
|
|
111
|
+
useEffect(() => {
|
|
112
|
+
const stored = sessionStorage.getItem(WEEK_STORAGE);
|
|
113
|
+
selectWeek(stored !== null ? Number(stored) : null, true);
|
|
114
|
+
setBrowser(true);
|
|
115
|
+
}, [selectWeek]);
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
if (selected !== null && selected !== undefined) {
|
|
118
|
+
const stored = sessionStorage.getItem(WEEK_STORAGE);
|
|
119
|
+
const storedSelected = stored !== null ? Number(stored) : null;
|
|
120
|
+
|
|
121
|
+
if (storedSelected !== selected) {
|
|
122
|
+
sessionStorage.setItem(WEEK_STORAGE, selected);
|
|
123
|
+
const startDate = weekToDate(selected, endWeek, forceSeasonSwitch);
|
|
124
|
+
const endDate = weekToDate(selected + 1, endWeek, forceSeasonSwitch);
|
|
125
|
+
const range = {
|
|
126
|
+
from: formatDate(startDate),
|
|
127
|
+
to: formatDate(endDate)
|
|
128
|
+
};
|
|
129
|
+
sessionStorage.stay = JSON.stringify(range);
|
|
130
|
+
sessionStorage.Stay = JSON.stringify(range);
|
|
131
|
+
|
|
132
|
+
if (typeof onChange === "function") {
|
|
133
|
+
onChange(range);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (!noRoughValidation) {
|
|
137
|
+
sessionStorage.roughStay = true;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}, [selected, endWeek, noRoughValidation, forceSeasonSwitch, onChange]);
|
|
142
|
+
useEffect(() => {
|
|
143
|
+
const bar = ref.current;
|
|
144
|
+
if (selected === undefined || !bar) return;
|
|
145
|
+
const selectedItem = bar.querySelector(".week-picker__item--selected");
|
|
146
|
+
if (!selectedItem) return;
|
|
147
|
+
const {
|
|
148
|
+
clientWidth,
|
|
149
|
+
offsetLeft
|
|
150
|
+
} = selectedItem;
|
|
151
|
+
bar.scrollLeft = offsetLeft - clientWidth;
|
|
152
|
+
}, [selected]);
|
|
153
|
+
|
|
154
|
+
const scrollTo = direction => {
|
|
155
|
+
const bar = ref.current;
|
|
156
|
+
if (!bar) return;
|
|
157
|
+
const currentScroll = bar.scrollLeft;
|
|
158
|
+
|
|
159
|
+
if (direction === LEFT) {
|
|
160
|
+
bar.scrollLeft = currentScroll - 200;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (direction === RIGHT) {
|
|
164
|
+
bar.scrollLeft = currentScroll + 200;
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const select = week => _ => {
|
|
169
|
+
selectWeek(week);
|
|
170
|
+
|
|
171
|
+
if (setClosed !== undefined) {
|
|
172
|
+
setClosed(week);
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
const selectAndClose = week => {
|
|
177
|
+
selectWeek(week);
|
|
178
|
+
setOpened(false);
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
return _jsxs(_Fragment, {
|
|
182
|
+
children: [_jsx("div", {
|
|
183
|
+
className: pickerClasses,
|
|
184
|
+
children: isBrowser && _jsxs(_Fragment, {
|
|
185
|
+
children: [_jsx("div", {
|
|
186
|
+
className: "week-picker__top",
|
|
187
|
+
children: _jsxs("div", {
|
|
188
|
+
className: "week-picker__text",
|
|
189
|
+
children: [_jsxs("div", {
|
|
190
|
+
className: "week-picker__controls",
|
|
191
|
+
children: [_jsx("button", {
|
|
192
|
+
className: "week-picker__control",
|
|
193
|
+
onClick: () => scrollTo(LEFT),
|
|
194
|
+
"aria-label": "Previous",
|
|
195
|
+
children: _jsx("svg", {
|
|
196
|
+
viewBox: "0 0 24 24",
|
|
197
|
+
width: "24",
|
|
198
|
+
height: "24",
|
|
199
|
+
children: _jsx("path", {
|
|
200
|
+
d: "M20 3l-3-3L5 12l12 12 3-3-9-9 9-9z"
|
|
201
|
+
})
|
|
202
|
+
})
|
|
203
|
+
}), _jsx("button", {
|
|
204
|
+
className: "week-picker__control",
|
|
205
|
+
onClick: () => scrollTo(RIGHT),
|
|
206
|
+
"aria-label": "Next",
|
|
207
|
+
children: _jsx("svg", {
|
|
208
|
+
viewBox: "0 0 24 24",
|
|
209
|
+
width: "24",
|
|
210
|
+
height: "24",
|
|
211
|
+
children: _jsx("path", {
|
|
212
|
+
d: "M5 3l3-3 12 12L8 24l-3-3 9-9-9-9z"
|
|
213
|
+
})
|
|
214
|
+
})
|
|
215
|
+
})]
|
|
216
|
+
}), selected === null && _jsx("div", {
|
|
217
|
+
className: "week-picker__title",
|
|
218
|
+
dangerouslySetInnerHTML: {
|
|
219
|
+
__html: weekPickerTitle
|
|
220
|
+
}
|
|
221
|
+
}), selected !== undefined && selected !== null && _jsx("div", {
|
|
222
|
+
className: "week-picker__title",
|
|
223
|
+
dangerouslySetInnerHTML: {
|
|
224
|
+
__html: `${weekPickedSelectedTitle} <span>${weekToLongDate(selected, endWeek, forceSeasonSwitch)}</span>`
|
|
225
|
+
}
|
|
226
|
+
})]
|
|
227
|
+
})
|
|
228
|
+
}), _jsxs("div", {
|
|
229
|
+
className: "week-picker__bottom",
|
|
230
|
+
children: [_jsx("div", {
|
|
231
|
+
ref: ref,
|
|
232
|
+
className: "week-picker__bar",
|
|
233
|
+
children: weeks.map(week => _jsx(Week, {
|
|
234
|
+
week: week,
|
|
235
|
+
beginWeek: beginWeek,
|
|
236
|
+
endWeek: endWeek,
|
|
237
|
+
selected: selected,
|
|
238
|
+
onClick: select(week),
|
|
239
|
+
forceSeasonSwitch: forceSeasonSwitch
|
|
240
|
+
}, week))
|
|
241
|
+
}), warn !== -1 && _jsx("div", {
|
|
242
|
+
className: "week-picker__warn",
|
|
243
|
+
children: _jsxs("div", {
|
|
244
|
+
className: "week-picker__warn-inner",
|
|
245
|
+
children: [_jsx("div", {
|
|
246
|
+
className: "week-picker__warn-text",
|
|
247
|
+
children: weekPickerWarn
|
|
248
|
+
}), _jsxs("div", {
|
|
249
|
+
className: "week-picker__warn-buttons",
|
|
250
|
+
children: [_jsx("button", {
|
|
251
|
+
className: "week-picker__warn-button",
|
|
252
|
+
onClick: () => setWarn(-1),
|
|
253
|
+
children: weekPickerCancel
|
|
254
|
+
}), _jsx("button", {
|
|
255
|
+
className: "week-picker__warn-button",
|
|
256
|
+
onClick: () => selectWeek(warn, true),
|
|
257
|
+
children: weekPickerOk
|
|
258
|
+
})]
|
|
259
|
+
})]
|
|
260
|
+
})
|
|
261
|
+
})]
|
|
262
|
+
})]
|
|
263
|
+
})
|
|
264
|
+
}), mustFilterSections && isBrowser && showDialog && opened && _jsx("div", {
|
|
265
|
+
className: "week-picker-popup",
|
|
266
|
+
children: _jsx("div", {
|
|
267
|
+
className: "week-picker-popup__inner",
|
|
268
|
+
children: _jsx("div", {
|
|
269
|
+
className: "week-picker-popup__content",
|
|
270
|
+
children: _jsx(WeekPicker, {
|
|
271
|
+
lang: lang,
|
|
272
|
+
start: start,
|
|
273
|
+
end: end,
|
|
274
|
+
setClosed: selectAndClose,
|
|
275
|
+
forceSeasonSwitch: forceSeasonSwitch
|
|
276
|
+
})
|
|
277
|
+
})
|
|
278
|
+
})
|
|
279
|
+
})]
|
|
280
|
+
});
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
export default memo(WeekPicker);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const locales = {
|
|
2
|
+
fr: {
|
|
3
|
+
"week-picker-title": "Choisissez <span>votre semaine</span>",
|
|
4
|
+
"week-picker-selected-title": "<span>Vous venez</span> la semaine du",
|
|
5
|
+
"week-picker-warn": "Attention, modifier vos dates de séjour entraine la suppression du contenu du panier",
|
|
6
|
+
"week-picker-ok": "Modifier",
|
|
7
|
+
"week-picker-cancel": "Annuler"
|
|
8
|
+
},
|
|
9
|
+
en: {
|
|
10
|
+
"week-picker-title": "<span>When</span> are you coming?",
|
|
11
|
+
"week-picker-selected-title": "<span>Coming</span> the week of the",
|
|
12
|
+
"week-picker-warn": "Warning, if you modify your dates of stay, your cart will be cleared",
|
|
13
|
+
"week-picker-ok": "Modify",
|
|
14
|
+
"week-picker-cancel": "Cancel"
|
|
15
|
+
},
|
|
16
|
+
nl: {
|
|
17
|
+
"week-picker-title": "<span>Wanneer</span> kom je?",
|
|
18
|
+
"week-picker-selected-title": "<span>Keuze</span> de week van",
|
|
19
|
+
"week-picker-warn": "Waarschuwing, als u uw verblijfsdata wijzigt, wordt uw winkelwagentje gewist",
|
|
20
|
+
"week-picker-ok": "Aanpassen",
|
|
21
|
+
"week-picker-cancel": "Annuleren"
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const getMessage = (lang, messages = locales) => messages[lang] || messages["en"];
|
|
26
|
+
|
|
27
|
+
export default getMessage;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export const padStart = (value, count, pad) => {
|
|
2
|
+
let str = String(value);
|
|
3
|
+
|
|
4
|
+
while (str.length < count) {
|
|
5
|
+
str = pad + str;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
return str;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const createDate = (...args) => {
|
|
12
|
+
const ref = new Date(...args);
|
|
13
|
+
const yy = ref.getFullYear();
|
|
14
|
+
const mm = padStart(ref.getMonth() + 1, 2, 0);
|
|
15
|
+
const dd = padStart(ref.getDate(), 2, 0);
|
|
16
|
+
const str = `${yy}-${mm}-${dd}`;
|
|
17
|
+
return new Date(str);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const getPrevSaturday = date => {
|
|
21
|
+
const clone = createDate(date);
|
|
22
|
+
const day = 1 + clone.getDay();
|
|
23
|
+
const prevSaturday = clone.getDate() - day % 7;
|
|
24
|
+
clone.setDate(prevSaturday);
|
|
25
|
+
return clone;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const addDays = (date, days) => {
|
|
29
|
+
const clone = createDate(date);
|
|
30
|
+
clone.setDate(clone.getDate() + days);
|
|
31
|
+
return clone;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const christmasWeek = (endWeek, forceSeasonSwitch) => {
|
|
35
|
+
const now = createDate();
|
|
36
|
+
const year = now.getFullYear();
|
|
37
|
+
const month = now.getMonth();
|
|
38
|
+
const date = now.getDate();
|
|
39
|
+
const isAfterChristmas = month === 11 && date >= 25;
|
|
40
|
+
const lastChristmasYear = isAfterChristmas || !isAfterChristmas && forceSeasonSwitch ? year : year - 1;
|
|
41
|
+
const lastChristmas = createDate(lastChristmasYear, 11, 25);
|
|
42
|
+
const nextChristmas = createDate(lastChristmasYear + 1, 11, 25);
|
|
43
|
+
const dateSeasonEnd = addDays(getPrevSaturday(lastChristmas), endWeek * 7);
|
|
44
|
+
return getPrevSaturday(now <= dateSeasonEnd ? lastChristmas : nextChristmas);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const weekToDate = (week, endWeek, forceSeasonSwitch) => addDays(christmasWeek(endWeek, forceSeasonSwitch), week * 7);
|
|
48
|
+
export const formatShortDate = date => {
|
|
49
|
+
const dd = padStart(date.getDate(), 2, 0);
|
|
50
|
+
const mm = padStart(date.getMonth() + 1, 2, 0);
|
|
51
|
+
return `${dd}/${mm}`;
|
|
52
|
+
};
|
|
53
|
+
export const weekToLongDate = (week, endWeek, forceSeasonSwitch) => {
|
|
54
|
+
const date = weekToDate(week, endWeek, forceSeasonSwitch);
|
|
55
|
+
const dd = padStart(date.getDate(), 2, 0);
|
|
56
|
+
const mm = padStart(date.getMonth() + 1, 2, 0);
|
|
57
|
+
const yy = date.getFullYear();
|
|
58
|
+
return `${dd}/${mm}/${yy}`;
|
|
59
|
+
};
|
|
60
|
+
export const formatDate = date => {
|
|
61
|
+
const dd = padStart(date.getDate(), 2, 0);
|
|
62
|
+
const mm = padStart(date.getMonth() + 1, 2, 0);
|
|
63
|
+
const yy = date.getFullYear();
|
|
64
|
+
return `${yy}-${mm}-${dd}`;
|
|
65
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import classnames from "classnames";
|
|
3
|
+
import { weekToDate, formatDate, formatShortDate } from "./utils";
|
|
4
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
6
|
+
|
|
7
|
+
const Week = ({
|
|
8
|
+
week,
|
|
9
|
+
beginWeek,
|
|
10
|
+
endWeek,
|
|
11
|
+
selected,
|
|
12
|
+
onClick,
|
|
13
|
+
forceSeasonSwitch
|
|
14
|
+
}) => {
|
|
15
|
+
const now = new Date();
|
|
16
|
+
const prevDate = weekToDate(week - 1, endWeek, forceSeasonSwitch);
|
|
17
|
+
const currDate = weekToDate(week, endWeek, forceSeasonSwitch);
|
|
18
|
+
const nextDate = weekToDate(week + 1, endWeek, forceSeasonSwitch);
|
|
19
|
+
const prevYear = prevDate.getFullYear();
|
|
20
|
+
const currYear = currDate.getFullYear();
|
|
21
|
+
const isPast = now.getTime() > nextDate.getTime();
|
|
22
|
+
const isFirst = week === beginWeek;
|
|
23
|
+
const isLast = week === endWeek;
|
|
24
|
+
const hasYearChanged = prevYear !== currYear;
|
|
25
|
+
const showYear = isFirst || hasYearChanged;
|
|
26
|
+
const weekClasses = classnames("week-picker__item", {
|
|
27
|
+
"week-picker__item--selected": selected === week,
|
|
28
|
+
"week-picker__item--past": isPast
|
|
29
|
+
});
|
|
30
|
+
const yearClasses = classnames("week-picker__year", {
|
|
31
|
+
"week-picker__year--changed": hasYearChanged
|
|
32
|
+
});
|
|
33
|
+
return _jsxs("div", {
|
|
34
|
+
className: weekClasses,
|
|
35
|
+
children: [_jsx("button", {
|
|
36
|
+
className: "week-picker__button",
|
|
37
|
+
onClick: onClick,
|
|
38
|
+
"aria-label": `${formatDate(currDate)} ${formatDate(nextDate)}`
|
|
39
|
+
}), _jsxs("div", {
|
|
40
|
+
className: "week-picker__date",
|
|
41
|
+
children: [showYear && _jsx("span", {
|
|
42
|
+
className: yearClasses,
|
|
43
|
+
children: currYear
|
|
44
|
+
}), _jsx("span", {
|
|
45
|
+
className: "week-picker__item-from",
|
|
46
|
+
children: formatShortDate(currDate)
|
|
47
|
+
}), isLast && _jsx("span", {
|
|
48
|
+
className: "week-picker__item-to",
|
|
49
|
+
children: formatShortDate(nextDate)
|
|
50
|
+
})]
|
|
51
|
+
})]
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export default Week;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as Plausible from "../plausible";
|
|
3
|
+
const STORAGE_KEY = "businessProvider";
|
|
4
|
+
const CHECKER_STORAGE_KEY = "businessProviderChecked";
|
|
5
|
+
|
|
6
|
+
const useAffiliation = () => {
|
|
7
|
+
React.useEffect(() => {
|
|
8
|
+
const storedChecker = window.sessionStorage.getItem(CHECKER_STORAGE_KEY);
|
|
9
|
+
const storedBusinessProvider = window.localStorage.getItem(STORAGE_KEY);
|
|
10
|
+
|
|
11
|
+
if (!storedChecker && storedBusinessProvider) {
|
|
12
|
+
const {
|
|
13
|
+
id
|
|
14
|
+
} = JSON.parse(storedBusinessProvider);
|
|
15
|
+
|
|
16
|
+
if (id !== -1) {
|
|
17
|
+
Plausible.sendGoal("Affiliation", {
|
|
18
|
+
id
|
|
19
|
+
});
|
|
20
|
+
window.sessionStorage.setItem(CHECKER_STORAGE_KEY, "true");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}, []);
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default useAffiliation;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { useUbloContext } from "ublo/with-ublo";
|
|
3
|
+
import { loadJS } from "../utils/load-js";
|
|
4
|
+
import * as Plausible from "../plausible";
|
|
5
|
+
|
|
6
|
+
const setupConfig = (lang, breadcrumb, cart = [], multipleVillages, hasLangPrefix) => {
|
|
7
|
+
const pageEsf = multipleVillages ? breadcrumb?.next?.path : breadcrumb?.path;
|
|
8
|
+
const langPrefix = hasLangPrefix ? `/${lang}` : "";
|
|
9
|
+
const pagePanier = langPrefix.concat(cart[0] ? cart[0].path : "/panier");
|
|
10
|
+
window.pagePanier = pagePanier;
|
|
11
|
+
window.pageEsf = pageEsf;
|
|
12
|
+
window.currentLang = lang;
|
|
13
|
+
window.useAnalytics = true;
|
|
14
|
+
window.analytics = Plausible.callback;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const useBookingLinks = (cart, multipleVillages, setupCallback) => {
|
|
18
|
+
const {
|
|
19
|
+
breadcrumb,
|
|
20
|
+
config,
|
|
21
|
+
lang
|
|
22
|
+
} = useUbloContext();
|
|
23
|
+
const hasLangPrefix = config.langPrefix.links;
|
|
24
|
+
const bookingLang = lang === "fr" ? "fr" : "en";
|
|
25
|
+
React.useEffect(() => {
|
|
26
|
+
const run = async () => {
|
|
27
|
+
await loadJS("https://widget.vente-en-ligne-esf.com/boutique/boutique.js", "boutique-js");
|
|
28
|
+
setupConfig(bookingLang, breadcrumb, cart, multipleVillages, hasLangPrefix);
|
|
29
|
+
setupCallback?.();
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
run();
|
|
33
|
+
}, [bookingLang, breadcrumb, cart, hasLangPrefix, multipleVillages, setupCallback]);
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default useBookingLinks;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { useUbloContext } from "ublo/with-ublo";
|
|
3
|
+
import { loadJS } from "../utils/load-js";
|
|
4
|
+
|
|
5
|
+
const useReviews = (lang, resort, containerId = "msem-reviews", preventInit) => {
|
|
6
|
+
const {
|
|
7
|
+
config
|
|
8
|
+
} = useUbloContext();
|
|
9
|
+
const {
|
|
10
|
+
reviews
|
|
11
|
+
} = config;
|
|
12
|
+
const language = lang === "fr" ? "fr" : "en";
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
const run = async () => {
|
|
15
|
+
await loadJS("https://reviews.msem.tech/static/js/widget-msem-reviews.js", `${containerId}-js`);
|
|
16
|
+
window.openReviews({
|
|
17
|
+
language,
|
|
18
|
+
school: resort,
|
|
19
|
+
containerId,
|
|
20
|
+
useDefaultCSS: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
!preventInit && reviews && setTimeout(run, 3000);
|
|
25
|
+
}, [containerId, language, resort, reviews]);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default useReviews;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import getConfig from "next/config";
|
|
3
|
+
const STORAGE_KEY = "forcedSeasonStay";
|
|
4
|
+
|
|
5
|
+
const padStart = (value, count, pad) => {
|
|
6
|
+
let str = String(value);
|
|
7
|
+
|
|
8
|
+
while (str.length < count) {
|
|
9
|
+
str = pad + str;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return str;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const createDate = (...args) => {
|
|
16
|
+
const ref = new Date(...args);
|
|
17
|
+
const yy = ref.getFullYear();
|
|
18
|
+
const mm = padStart(ref.getMonth() + 1, 2, 0);
|
|
19
|
+
const dd = padStart(ref.getDate(), 2, 0);
|
|
20
|
+
const str = `${yy}-${mm}-${dd}`;
|
|
21
|
+
return new Date(str);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const getPrevSaturday = date => {
|
|
25
|
+
const clone = createDate(date);
|
|
26
|
+
const day = 1 + clone.getDay();
|
|
27
|
+
const prevSaturday = clone.getDate() - day % 7;
|
|
28
|
+
clone.setDate(prevSaturday);
|
|
29
|
+
return clone;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const addDays = (date, days) => {
|
|
33
|
+
const clone = createDate(date);
|
|
34
|
+
clone.setDate(clone.getDate() + days);
|
|
35
|
+
return clone;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const christmasWeek = endWeek => {
|
|
39
|
+
const now = createDate();
|
|
40
|
+
const year = now.getFullYear();
|
|
41
|
+
const month = now.getMonth();
|
|
42
|
+
const date = now.getDate();
|
|
43
|
+
const isAfterChristmas = month === 11 && date >= 25;
|
|
44
|
+
const lastChristmasYear = isAfterChristmas ? year : year - 1;
|
|
45
|
+
const lastChristmas = createDate(lastChristmasYear, 11, 25);
|
|
46
|
+
const nextChristmas = createDate(lastChristmasYear + 1, 11, 25);
|
|
47
|
+
const dateSeasonEnd = addDays(getPrevSaturday(lastChristmas), endWeek * 7);
|
|
48
|
+
return getPrevSaturday(now <= dateSeasonEnd ? lastChristmas : nextChristmas);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const weekToDate = (week, endWeek) => addDays(christmasWeek(endWeek), week * 7);
|
|
52
|
+
|
|
53
|
+
const formatDate = date => {
|
|
54
|
+
const dd = padStart(date.getDate(), 2, 0);
|
|
55
|
+
const mm = padStart(date.getMonth() + 1, 2, 0);
|
|
56
|
+
const yy = date.getFullYear();
|
|
57
|
+
return `${yy}-${mm}-${dd}`;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const useSeasonProducts = menuPath => {
|
|
61
|
+
const seasonProductsPage = menuPath?.metadata?.seasonProductsPage;
|
|
62
|
+
const {
|
|
63
|
+
publicRuntimeConfig: config
|
|
64
|
+
} = getConfig();
|
|
65
|
+
const {
|
|
66
|
+
start,
|
|
67
|
+
end
|
|
68
|
+
} = config.season || {};
|
|
69
|
+
const [startDate, endDate] = [weekToDate(start, end), weekToDate(end, end)];
|
|
70
|
+
const isEnabled = seasonProductsPage && start !== undefined && end !== undefined;
|
|
71
|
+
const updateStay = React.useCallback(async () => {
|
|
72
|
+
const stay = JSON.stringify({
|
|
73
|
+
from: formatDate(startDate),
|
|
74
|
+
to: formatDate(endDate)
|
|
75
|
+
});
|
|
76
|
+
window.sessionStorage.setItem("stay", stay);
|
|
77
|
+
window.sessionStorage.setItem(STORAGE_KEY, true);
|
|
78
|
+
}, [endDate, startDate]);
|
|
79
|
+
React.useEffect(() => {
|
|
80
|
+
if (isEnabled) {
|
|
81
|
+
if (seasonProductsPage) {
|
|
82
|
+
const buttons = Array.from(document.querySelectorAll("[onclick*='openBoutiqueESF']"));
|
|
83
|
+
buttons.forEach(button => button.addEventListener("click", updateStay));
|
|
84
|
+
return () => {
|
|
85
|
+
buttons.forEach(button => button.removeEventListener("click", updateStay));
|
|
86
|
+
};
|
|
87
|
+
} else {
|
|
88
|
+
const hasForcedStay = window.sessionStorage.getItem(STORAGE_KEY);
|
|
89
|
+
|
|
90
|
+
if (hasForcedStay) {
|
|
91
|
+
window.sessionStorage.removeItem("stay");
|
|
92
|
+
window.sessionStorage.removeItem("stayWeek");
|
|
93
|
+
window.sessionStorage.removeItem(STORAGE_KEY);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}, [seasonProductsPage, updateStay]);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export default useSeasonProducts;
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ublo-lib",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"peerDependencies": {
|
|
5
|
+
"react": "^18.2.0",
|
|
6
|
+
"react-dom": "^18.2.0"
|
|
7
|
+
},
|
|
8
|
+
"dependencies": {
|
|
9
|
+
"classnames": "^2.3.1"
|
|
10
|
+
},
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"@babel/cli": "^7.12.0",
|
|
13
|
+
"@babel/core": "^7.12.0",
|
|
14
|
+
"@babel/plugin-proposal-class-properties": "^7.12.0",
|
|
15
|
+
"@babel/preset-react": "^7.12.0",
|
|
16
|
+
"@babel/preset-typescript": "^7.12.0",
|
|
17
|
+
"@types/css-modules": "^1.0.2",
|
|
18
|
+
"@types/react": "^18.0.17",
|
|
19
|
+
"@types/react-dom": "^18.0.6",
|
|
20
|
+
"classnames": "^2.3.1",
|
|
21
|
+
"eslint": "^8.11.0",
|
|
22
|
+
"eslint-config-prettier": "^8.5.0",
|
|
23
|
+
"eslint-config-standard": "^16.0.3",
|
|
24
|
+
"eslint-plugin-jsx-a11y": "^6.5.1",
|
|
25
|
+
"eslint-plugin-node": "^11.1.0",
|
|
26
|
+
"eslint-plugin-promise": "^6.0.0",
|
|
27
|
+
"eslint-plugin-react": "^7.29.4",
|
|
28
|
+
"eslint-plugin-react-hooks": "^4.3.0",
|
|
29
|
+
"react": "^18.2.0",
|
|
30
|
+
"react-dom": "^18.2.0",
|
|
31
|
+
"react-scripts": "5.0.1",
|
|
32
|
+
"typescript": "^4.7.2"
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"clean": "rm -rf es",
|
|
36
|
+
"build": "babel src -x '.js,.ts,.tsx' -d es && tsc",
|
|
37
|
+
"postbuild": "cpx 'src/**/*.{json,css}' es",
|
|
38
|
+
"prepublishOnly": "yarn clean && yarn build",
|
|
39
|
+
"watch": "yarn clean && babel ./src -x '.js,.ts,.tsx' -d ./es -w & cpx 'src/**/*.{json,css}' ./es -w"
|
|
40
|
+
},
|
|
41
|
+
"packageManager": "yarn@1.22.18",
|
|
42
|
+
"files": [
|
|
43
|
+
"es"
|
|
44
|
+
],
|
|
45
|
+
"browserslist": [
|
|
46
|
+
">1%",
|
|
47
|
+
"not dead",
|
|
48
|
+
"ie >= 11",
|
|
49
|
+
"not op_mini all"
|
|
50
|
+
]
|
|
51
|
+
}
|