ublo-lib 1.10.29 → 1.11.1

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.
@@ -87,13 +87,18 @@ const CustomContactForm = ({
87
87
  React.useEffect(() => {
88
88
  if (!ready && !settings) {
89
89
  const init = async () => {
90
+ if (typeof customSend === "function") {
91
+ setReady(true);
92
+ setSettings({});
93
+ return;
94
+ }
90
95
  const formSettings = await getSettings(site);
91
96
  setSettings(formSettings);
92
97
  setReady(true);
93
98
  };
94
99
  init();
95
100
  }
96
- }, [ready, settings, site]);
101
+ }, [customSend, ready, settings, site]);
97
102
  React.useEffect(() => {
98
103
  setData(getInitialFormState(fields, presets?.values));
99
104
  }, [fields, presets?.values]);
@@ -1 +1 @@
1
- {"version":3,"file":"use-tunnel.d.ts","sourceRoot":"","sources":["../../../src/common/hooks/use-tunnel.ts"],"names":[],"mappings":"AAKA,aAAK,KAAK,GAAG;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAChC,OAAe,EACf,gBAAgB,EAChB,WAAW,GACZ,GAAE,KAAU,QA0BZ"}
1
+ {"version":3,"file":"use-tunnel.d.ts","sourceRoot":"","sources":["../../../src/common/hooks/use-tunnel.ts"],"names":[],"mappings":"AAMA,aAAK,KAAK,GAAG;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAMF,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAChC,OAAe,EACf,gBAAgB,EAChB,WAAW,GACZ,GAAE,KAAU,QA0BZ"}
@@ -1,29 +1,32 @@
1
- import { useEffect } from "react";
1
+ import * as React from "react";
2
+ import getConfig from "next/config";
2
3
  import { useUbloContext } from "ublo/with-ublo";
3
4
  import * as Plausible from "../components/plausible";
4
5
  import { loadJS } from "../utils/load-js";
6
+ const { publicRuntimeConfig } = getConfig();
7
+ const { langPrefix, resort } = publicRuntimeConfig;
8
+ const hasLangPrefix = langPrefix.links;
5
9
  export default function useTunnel({ channel = "ESF", multipleVillages, integration, } = {}) {
6
- const { lang, breadcrumb, config } = useUbloContext();
10
+ const { lang, breadcrumb } = useUbloContext();
7
11
  const { path: esfPath } = multipleVillages ? breadcrumb?.next : breadcrumb;
8
- const { langPrefix } = config;
9
- const hasLangPrefix = langPrefix.links;
10
- const esfUrl = hasLangPrefix ? `/${lang.concat(esfPath)}` : esfPath;
11
- const widgetLang = lang === "fr" ? "fr" : "en";
12
- useEffect(() => {
13
- const run = async () => {
12
+ const widgetLang = React.useMemo(() => (lang === "fr" ? "fr" : "en"), [lang]);
13
+ const esfUrl = React.useMemo(() => (hasLangPrefix ? `/${lang.concat(esfPath)}` : esfPath), [esfPath, lang]);
14
+ React.useEffect(() => {
15
+ const startTunnel = async () => {
14
16
  await loadWigetMseM(integration);
15
- const open = () => window.MseM.tunnel({
16
- channel,
17
- resort: config.resort,
18
- groundedTo: "#esfplus_container",
19
- lang: widgetLang,
20
- esfUrl,
21
- analytics: Plausible.callback,
17
+ window.MseM.onLoad(() => {
18
+ window.MseM.tunnel({
19
+ channel,
20
+ resort,
21
+ groundedTo: "#esfplus_container",
22
+ lang: widgetLang,
23
+ esfUrl,
24
+ analytics: Plausible.callback,
25
+ });
22
26
  });
23
- window.MseM.onLoad(open);
24
27
  };
25
- run();
26
- }, [channel, config.resort, esfUrl, lang, widgetLang]);
28
+ startTunnel();
29
+ }, [channel, esfUrl, integration, widgetLang]);
27
30
  }
28
31
  async function loadWigetMseM(integration) {
29
32
  const source = integration
@@ -0,0 +1,36 @@
1
+ import getConfig from "next/config";
2
+ const {
3
+ publicRuntimeConfig
4
+ } = getConfig();
5
+ const {
6
+ resort
7
+ } = publicRuntimeConfig;
8
+ const host = "https://instructors-book-server.carnet-rouge-esf.com";
9
+ const authorization = "00q2qa545018261l252gg3414t3qa2";
10
+ const fetcher = async (url, body) => {
11
+ const res = await fetch(url, {
12
+ method: "POST",
13
+ headers: {
14
+ "content-type": "application/json;charset=utf-8",
15
+ Authorization: authorization,
16
+ schoolcode: resort
17
+ },
18
+ body: body ? JSON.stringify(body) : undefined
19
+ });
20
+ return res.json();
21
+ };
22
+ export async function fetchInstructors(lang, body = {}) {
23
+ return fetcher(`${host}/api/instructors-book/${resort}/${lang}`, {
24
+ ...body,
25
+ project: true
26
+ });
27
+ }
28
+ export async function fetchInstructor(lang, uri) {
29
+ return fetcher(`${host}/api/instructors-book/${resort}/${lang}/${uri}`);
30
+ }
31
+ export const fetchRandomInstructors = async (lang, tags, nbInstructor) => {
32
+ return fetcher(`${host}/api/instructors-book/${resort}/${lang}/byTags`, {
33
+ tags,
34
+ size: nbInstructor
35
+ });
36
+ };
@@ -0,0 +1,81 @@
1
+ import * as React from "react";
2
+ import { useUbloContext } from "ublo/with-ublo";
3
+ import Filters from "./filters";
4
+ import List from "./list";
5
+ import * as API from "./api";
6
+ import * as Utils from "./utils";
7
+ import css from "./book.module.css";
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ import { jsxs as _jsxs } from "react/jsx-runtime";
10
+ export default function Book({
11
+ instructors,
12
+ trombi
13
+ }) {
14
+ const {
15
+ lang
16
+ } = useUbloContext();
17
+ const [context, setContext] = React.useState(instructors);
18
+ const [activity, setActivity] = React.useState("");
19
+ const [language, setLanguage] = React.useState("");
20
+ const [search, setSearch] = React.useState("");
21
+ const [loading, setLoading] = React.useState(false);
22
+ const refreshContext = React.useCallback(async () => {
23
+ try {
24
+ setLoading(true);
25
+ const newContext = await API.fetchInstructors(lang, {
26
+ activity,
27
+ language
28
+ });
29
+ setContext(newContext);
30
+ } catch (e) {
31
+ console.info("error while refreshing instructor context", e);
32
+ } finally {
33
+ setLoading(false);
34
+ }
35
+ }, [activity, lang, language]);
36
+ const updateFilter = React.useCallback(name => async value => {
37
+ if (name === "search") {
38
+ return setSearch(value);
39
+ }
40
+ if (name === "activity") {
41
+ setActivity(value);
42
+ window.sessionStorage.setItem("activity", value);
43
+ }
44
+ if (name === "language") {
45
+ setLanguage(value);
46
+ window.sessionStorage.setItem("language", value);
47
+ }
48
+ }, []);
49
+ React.useEffect(() => {
50
+ const {
51
+ activity,
52
+ language
53
+ } = Utils.propsFromQueryString();
54
+ const storedActivity = window.sessionStorage.getItem("activity") || activity;
55
+ if (storedActivity) {
56
+ updateFilter("activity")(storedActivity);
57
+ }
58
+ const storedLanguage = window.sessionStorage.getItem("language") || language;
59
+ if (storedLanguage) {
60
+ updateFilter("language")(storedLanguage);
61
+ }
62
+ }, [updateFilter]);
63
+ React.useEffect(() => {
64
+ refreshContext();
65
+ }, [activity, language, refreshContext]);
66
+ return _jsxs("div", {
67
+ className: css.book,
68
+ children: [_jsx(Filters, {
69
+ context: context,
70
+ search: search,
71
+ activity: activity,
72
+ language: language,
73
+ updateFilter: updateFilter,
74
+ loading: loading
75
+ }), _jsx(List, {
76
+ search: search,
77
+ instructors: context.instructors,
78
+ trombi: trombi
79
+ })]
80
+ });
81
+ }
@@ -0,0 +1,4 @@
1
+ .book {
2
+ display: flex;
3
+ flex-direction: column;
4
+ }
@@ -0,0 +1,62 @@
1
+ import * as React from "react";
2
+ import css from "./filters.module.css";
3
+ import Input from "dt-design-system/es/input";
4
+ import Select from "dt-design-system/es/select";
5
+ import { useUbloContext } from "ublo/with-ublo";
6
+ import { message } from "./messages";
7
+ import { jsx as _jsx } from "react/jsx-runtime";
8
+ import { jsxs as _jsxs } from "react/jsx-runtime";
9
+ export default function Filters({
10
+ context,
11
+ search,
12
+ activity,
13
+ language,
14
+ updateFilter,
15
+ loading
16
+ }) {
17
+ const {
18
+ lang
19
+ } = useUbloContext();
20
+ const {
21
+ activities,
22
+ languages
23
+ } = context;
24
+ const formatedActivities = ["", ...activities.map(({
25
+ code,
26
+ label
27
+ }) => ({
28
+ label,
29
+ value: code
30
+ }))];
31
+ const formatedLanguages = ["", ...languages.map(({
32
+ code,
33
+ label
34
+ }) => ({
35
+ label,
36
+ value: code
37
+ }))];
38
+ return _jsxs("div", {
39
+ className: css.container,
40
+ children: [_jsx(Input, {
41
+ icon: "Search",
42
+ label: message(lang, "search-label"),
43
+ placeholder: message(lang, "search-placeholder"),
44
+ value: search,
45
+ onValueChange: updateFilter("search")
46
+ }), _jsx(Select, {
47
+ icon: "Filter",
48
+ label: message(lang, "activity-label"),
49
+ value: activity,
50
+ options: formatedActivities,
51
+ onValueChange: updateFilter("activity"),
52
+ loading: loading
53
+ }), _jsx(Select, {
54
+ icon: "Globe",
55
+ label: message(lang, "language-label"),
56
+ value: language,
57
+ options: formatedLanguages,
58
+ onValueChange: updateFilter("language"),
59
+ loading: loading
60
+ })]
61
+ });
62
+ }
@@ -0,0 +1,17 @@
1
+ .container {
2
+ width: 100%;
3
+ display: flex;
4
+ flex-wrap: wrap;
5
+ gap: 16px;
6
+ margin: 10px 0;
7
+ }
8
+
9
+ .container > * {
10
+ flex: 1 1 auto;
11
+ }
12
+
13
+ @media (min-width: 690px) {
14
+ .container > * {
15
+ flex: 0 0 auto;
16
+ }
17
+ }
@@ -0,0 +1,248 @@
1
+ import * as React from "react";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { jsxs as _jsxs } from "react/jsx-runtime";
4
+ const SVG = ({
5
+ title,
6
+ ...props
7
+ }) => _jsxs("svg", {
8
+ viewBox: "0 0 24 24",
9
+ ...props,
10
+ children: [title && _jsx("title", {
11
+ children: title
12
+ }), props.children]
13
+ });
14
+ const ArFlag = props => _jsxs(SVG, {
15
+ ...props,
16
+ children: [_jsx("path", {
17
+ d: "M0 3h24v6H0V3z",
18
+ fill: "#000"
19
+ }), _jsx("path", {
20
+ d: "M0 9h24v6H0V9z",
21
+ fill: "#fff"
22
+ }), _jsx("path", {
23
+ d: "M0 15h24v6H0v-6z",
24
+ fill: "#00732F"
25
+ })]
26
+ });
27
+ const CnFlag = props => _jsxs(SVG, {
28
+ ...props,
29
+ children: [_jsx("path", {
30
+ d: "M0 3h24v18H0V3z",
31
+ fill: "#DE2910"
32
+ }), _jsx("path", {
33
+ d: "M2.91 9.69L4.5 4.8l1.59 4.89-4.16-3.03h5.14L2.91 9.7zM9.9 4.88l-1.66.38 1.12-1.29-.15 1.7-.88-1.46 1.58.67zM11.6 7.01l-1.7-.3 1.55-.74-.8 1.51-.25-1.7 1.2 1.23zM11.35 10.01l-1.42-.96L11.64 9l-1.35 1.06.48-1.65.58 1.61zM9.24 11.97l-.95-1.43 1.6.6-1.65.46 1.08-1.34-.08 1.71z",
34
+ fill: "#FFDE00"
35
+ })]
36
+ });
37
+ const DeFlag = props => _jsxs(SVG, {
38
+ ...props,
39
+ children: [_jsx("path", {
40
+ d: "M0 15h24v6H0v-6z",
41
+ fill: "#FFCE00"
42
+ }), _jsx("path", {
43
+ d: "M0 3h24v6H0V3z",
44
+ fill: "#000"
45
+ }), _jsx("path", {
46
+ d: "M0 9h24v6H0V9z",
47
+ fill: "#D00"
48
+ })]
49
+ });
50
+ const DkFlag = props => _jsxs(SVG, {
51
+ ...props,
52
+ children: [_jsx("path", {
53
+ d: "M0 3h24v18H0V3z",
54
+ fill: "#C60C30"
55
+ }), _jsx("path", {
56
+ d: "M7.7 3h2.6v18H7.7V3z",
57
+ fill: "#fff"
58
+ }), _jsx("path", {
59
+ d: "M0 10.7h24v2.6H0v-2.6z",
60
+ fill: "#fff"
61
+ })]
62
+ });
63
+ const EsFlag = props => _jsxs(SVG, {
64
+ ...props,
65
+ children: [_jsx("path", {
66
+ d: "M0 3h24v18H0V3z",
67
+ fill: "#C60B1E"
68
+ }), _jsx("path", {
69
+ d: "M0 7.5h24v9H0v-9z",
70
+ fill: "#FFC400"
71
+ })]
72
+ });
73
+ const FrFlag = props => _jsxs(SVG, {
74
+ ...props,
75
+ children: [_jsx("path", {
76
+ fillRule: "evenodd",
77
+ clipRule: "evenodd",
78
+ d: "M0 3h24v18H0V3z",
79
+ fill: "#fff"
80
+ }), _jsx("path", {
81
+ fillRule: "evenodd",
82
+ clipRule: "evenodd",
83
+ d: "M0 3h8v18H0V3z",
84
+ fill: "#00267F"
85
+ }), _jsx("path", {
86
+ fillRule: "evenodd",
87
+ clipRule: "evenodd",
88
+ d: "M16 3h8v18h-8V3z",
89
+ fill: "#F31830"
90
+ })]
91
+ });
92
+ const EnFlag = props => _jsxs(SVG, {
93
+ ...props,
94
+ children: [_jsx("path", {
95
+ d: "M-6 3h36v18H-6V3z",
96
+ fill: "#006"
97
+ }), _jsx("path", {
98
+ d: "M-6 3v2l32 16h4v-2L-2 3h-4zm36 0v2L-2 21h-4v-2L26 3h4z",
99
+ fill: "#fff"
100
+ }), _jsx("path", {
101
+ d: "M9 3v18h6V3H9zM-6 9v6h36V9H-6z",
102
+ fill: "#fff"
103
+ }), _jsx("path", {
104
+ d: "M-6 10.2v3.6h36v-3.6H-6zM10.2 3v18h3.6V3h-3.6zM-7 21l11-6h3l-11 6h-3zm1-18.5L7 9H4.5L-6 4V2.5zM16.5 9l12-6H31L19 9h-2.5zM30 21.5L17 15h3l10 5v1.5z",
105
+ fill: "#C00"
106
+ })]
107
+ });
108
+ const IlFlag = props => _jsxs(SVG, {
109
+ ...props,
110
+ children: [_jsx("path", {
111
+ d: "M25 21H-1V3H25v18z",
112
+ fill: "#fff"
113
+ }), _jsx("path", {
114
+ d: "M25 7H-1V4.8H25V7zm0 12.4H-1V17H25v2.4zM7.8 9.7l3.9 6.8 4-6.7h-8z",
115
+ fill: "#00C"
116
+ }), _jsx("path", {
117
+ d: "M11 14.2l.8 1.3.7-1.3H11z",
118
+ fill: "#fff"
119
+ }), _jsx("path", {
120
+ d: "M7.9 14.3l3.9-6.8 4 6.8h-8z",
121
+ fill: "#00C"
122
+ }), _jsx("path", {
123
+ d: "M11 9.8l.8-1.3.7 1.2H11zm-1.5 2.8l-.8 1.2h1.5l-.7-1.2zm-.8-2.4h1.5l-.7 1.3-.8-1.3zm5.4 2.4l.7 1.2h-1.5l.8-1.2zm.7-2.4h-1.5l.7 1.3.8-1.3zm-4 0l-1 1.8 1 1.8h1.8l1.2-1.8-1-1.8h-2z",
124
+ fill: "#fff"
125
+ })]
126
+ });
127
+ const ItFlag = props => _jsxs(SVG, {
128
+ ...props,
129
+ children: [_jsx("path", {
130
+ fillRule: "evenodd",
131
+ clipRule: "evenodd",
132
+ d: "M0 3h24v18H0V3z",
133
+ fill: "#fff"
134
+ }), _jsx("path", {
135
+ fillRule: "evenodd",
136
+ clipRule: "evenodd",
137
+ d: "M0 3h8v18H0V3z",
138
+ fill: "#009246"
139
+ }), _jsx("path", {
140
+ fillRule: "evenodd",
141
+ clipRule: "evenodd",
142
+ d: "M16 3h8v18h-8V3z",
143
+ fill: "#CE2B37"
144
+ })]
145
+ });
146
+ const JpFlag = props => _jsxs(SVG, {
147
+ ...props,
148
+ children: [_jsx("path", {
149
+ fillRule: "evenodd",
150
+ clipRule: "evenodd",
151
+ d: "M-1.5 3h27v18h-27V3z",
152
+ fill: "#fff"
153
+ }), _jsx("path", {
154
+ d: "M12 17.6a5.6 5.6 0 100-11.2 5.6 5.6 0 000 11.2z",
155
+ fill: "#D30000"
156
+ })]
157
+ });
158
+ const NlFlag = props => _jsxs(SVG, {
159
+ ...props,
160
+ children: [_jsx("path", {
161
+ d: "M24 3H0v18h24V3z",
162
+ fill: "#fff"
163
+ }), _jsx("path", {
164
+ d: "M24 15H0v6h24v-6z",
165
+ fill: "#21468B"
166
+ }), _jsx("path", {
167
+ fillRule: "evenodd",
168
+ clipRule: "evenodd",
169
+ d: "M0 3h24v6H0V3z",
170
+ fill: "#AE1C28"
171
+ })]
172
+ });
173
+ const PlFlag = props => _jsxs(SVG, {
174
+ ...props,
175
+ children: [_jsx("path", {
176
+ fillRule: "evenodd",
177
+ clipRule: "evenodd",
178
+ d: "M24 21H0V3h24v18z",
179
+ fill: "#fff"
180
+ }), _jsx("path", {
181
+ fillRule: "evenodd",
182
+ clipRule: "evenodd",
183
+ d: "M24 21H0v-9h24v9z",
184
+ fill: "#DC143C"
185
+ })]
186
+ });
187
+ const PtFlag = props => _jsxs(SVG, {
188
+ ...props,
189
+ children: [_jsx("path", {
190
+ d: "M9.6 3H24v18H9.6V3z",
191
+ fill: "red"
192
+ }), _jsx("path", {
193
+ d: "M0 3h9.6v18H0V3z",
194
+ fill: "#060"
195
+ })]
196
+ });
197
+ const RuFlag = props => _jsxs(SVG, {
198
+ ...props,
199
+ children: [_jsx("path", {
200
+ fillRule: "evenodd",
201
+ clipRule: "evenodd",
202
+ d: "M0 3h24v18H0V3z",
203
+ fill: "#fff"
204
+ }), _jsx("path", {
205
+ fillRule: "evenodd",
206
+ clipRule: "evenodd",
207
+ d: "M0 9h24v12H0V9z",
208
+ fill: "#0039A6"
209
+ }), _jsx("path", {
210
+ fillRule: "evenodd",
211
+ clipRule: "evenodd",
212
+ d: "M0 15h24v6H0v-6z",
213
+ fill: "#D52B1E"
214
+ })]
215
+ });
216
+ const SeFlag = props => _jsxs(SVG, {
217
+ ...props,
218
+ children: [_jsx("path", {
219
+ d: "M-2.4 3h9v7.2h-9V3zm0 10.8h9V21h-9v-7.2z",
220
+ fill: "#006AA7"
221
+ }), _jsx("path", {
222
+ d: "M-2.4 10.2h9v3.6h-9v-3.6zM6.6 3h3.6v18H6.6V3z",
223
+ fill: "#FECC00"
224
+ }), _jsx("path", {
225
+ d: "M10 10.2h16.3v3.6H10v-3.6z",
226
+ fill: "#FECC00"
227
+ }), _jsx("path", {
228
+ d: "M10.2 13.8h16.2V21H10.2v-7.2zm0-10.8h16.2v7.2H10.2V3z",
229
+ fill: "#006AA7"
230
+ })]
231
+ });
232
+ export const flags = {
233
+ ar: ArFlag,
234
+ cn: CnFlag,
235
+ de: DeFlag,
236
+ dk: DkFlag,
237
+ en: EnFlag,
238
+ es: EsFlag,
239
+ fr: FrFlag,
240
+ il: IlFlag,
241
+ it: ItFlag,
242
+ jp: JpFlag,
243
+ nl: NlFlag,
244
+ pl: PlFlag,
245
+ pt: PtFlag,
246
+ ru: RuFlag,
247
+ se: SeFlag
248
+ };
@@ -0,0 +1,6 @@
1
+ import * as API from "./api";
2
+ import Book from "./book";
3
+ import Sheet from "./sheet";
4
+ import Suggestions from "./suggestions";
5
+ import config from "./config";
6
+ export { Book, Sheet, Suggestions, API, config };
@@ -0,0 +1,112 @@
1
+ import * as React from "react";
2
+ import Image from "next/image";
3
+ import Link from "ublo/link";
4
+ import { useUbloContext } from "ublo/with-ublo";
5
+ import Dialog from "dt-design-system/es/dialog";
6
+ import * as Icons from "dt-design-system/es/icons";
7
+ import Sheet from "./sheet";
8
+ import * as Utils from "./utils";
9
+ import prefixes from "./prefixes";
10
+ import css from "./instructor.module.css";
11
+ import { jsx as _jsx } from "react/jsx-runtime";
12
+ import { Fragment as _Fragment } from "react/jsx-runtime";
13
+ import { jsxs as _jsxs } from "react/jsx-runtime";
14
+ export default function Instructor({
15
+ instructor,
16
+ formFields,
17
+ formSendFunction,
18
+ trombi,
19
+ popup
20
+ }) {
21
+ const {
22
+ lang
23
+ } = useUbloContext();
24
+ const {
25
+ firstname,
26
+ lastname,
27
+ photo,
28
+ uri
29
+ } = instructor;
30
+ const [loading, setLoading] = React.useState(true);
31
+ const [picture, setPicture] = React.useState(photo);
32
+ const [popupOpened, setPopupOpened] = React.useState(false);
33
+ const prefixLang = lang === "fr" ? "fr" : "en";
34
+ const openPopup = async e => {
35
+ if (!popup) return;
36
+ e.preventDefault();
37
+ setPopupOpened(true);
38
+ };
39
+ const closePopup = () => {
40
+ setPopupOpened(false);
41
+ };
42
+ const Tag = trombi ? "div" : Link;
43
+ const divProps = {};
44
+ const linkProps = {
45
+ href: `${prefixes[prefixLang]}/${uri}`,
46
+ onClick: openPopup
47
+ };
48
+ const props = trombi ? divProps : linkProps;
49
+ const stopLoading = () => {
50
+ setLoading(false);
51
+ };
52
+ const setFallbackPicture = ({
53
+ currentTarget
54
+ }) => {
55
+ setPicture(null);
56
+ stopLoading();
57
+ currentTarget.onerror = null;
58
+ };
59
+ return _jsxs(_Fragment, {
60
+ children: [_jsxs(Tag, {
61
+ className: css.card,
62
+ ...props,
63
+ children: [_jsx("div", {
64
+ className: css.imageContainer,
65
+ children: picture ? _jsxs(_Fragment, {
66
+ children: [loading && _jsx(Icons.Loader2, {
67
+ className: css.imageLoader
68
+ }), _jsx(Image, {
69
+ loading: "lazy",
70
+ src: picture,
71
+ className: css.image,
72
+ alt: `${firstname} ${lastname}`,
73
+ onLoad: stopLoading,
74
+ onError: setFallbackPicture,
75
+ width: "190",
76
+ height: "190"
77
+ })]
78
+ }) : _jsx("div", {
79
+ className: css.imagePlaceholder,
80
+ children: _jsx(Icons.User, {
81
+ className: css.imagePlaceholderIcon
82
+ })
83
+ })
84
+ }), _jsx("div", {
85
+ className: css.information,
86
+ children: _jsxs("div", {
87
+ className: css.name,
88
+ children: [_jsxs("span", {
89
+ className: css.firstName,
90
+ children: [Utils.formatNames(firstname), " "]
91
+ }), _jsx("span", {
92
+ className: css.lastName,
93
+ children: Utils.formatNames(lastname)
94
+ })]
95
+ })
96
+ })]
97
+ }), _jsx(Dialog, {
98
+ isOpened: popupOpened,
99
+ close: closePopup,
100
+ onClose: closePopup,
101
+ children: _jsx("div", {
102
+ className: css.dialogContent,
103
+ children: _jsx(Sheet, {
104
+ instructor: instructor,
105
+ formFields: formFields,
106
+ formSendFunction: formSendFunction,
107
+ popup: true
108
+ })
109
+ })
110
+ })]
111
+ });
112
+ }
@@ -0,0 +1,68 @@
1
+ .card {
2
+ display: flex;
3
+ flex-direction: column;
4
+ border-radius: var(--ds-radius-200, 10px);
5
+ background-color: var(--ds-grey-000, #ffffff);
6
+ box-shadow: var(--ds-shadow-200, 0 5px 10px rgba(0, 0, 0, 0.12));
7
+ }
8
+
9
+ .imageContainer {
10
+ position: relative;
11
+ display: flex;
12
+ align-items: center;
13
+ justify-content: center;
14
+ height: 190px;
15
+ border-bottom: 1px solid var(--ds-grey-100, #f5f5f5);
16
+ border-radius: var(--ds-radius-200, 10px) var(--ds-radius-200, 10px) 0 0;
17
+ }
18
+
19
+ .image {
20
+ position: relative;
21
+ width: 100%;
22
+ height: 100%;
23
+ object-fit: cover;
24
+ border-radius: inherit;
25
+ }
26
+
27
+ .imageLoader {
28
+ position: absolute;
29
+ top: 50%;
30
+ left: 50%;
31
+ transform: translate(-50%, -50%);
32
+ fill: var(--ds-secondary, var(--ds-blue-400, #4177f6));
33
+ animation: image-loader-spinning 1280ms
34
+ var(--ds-transition-easing, cubic-bezier(0.4, 0.1, 0.2, 0.9)) infinite;
35
+ }
36
+
37
+ @keyframes image-loader-spinning {
38
+ 100% {
39
+ transform: translate(-50%, -50%) rotate(1turn);
40
+ }
41
+ }
42
+
43
+ .imagePlaceholder {
44
+ padding: 16px 22px;
45
+ background-color: var(--ds-grey-100, #f5f5f5);
46
+ border-radius: var(--ds-radius-100, 6px);
47
+ }
48
+
49
+ .imagePlaceholderIcon {
50
+ width: 34px;
51
+ height: 34px;
52
+ fill: var(--ds-grey-300, #d4d4d4);
53
+ }
54
+
55
+ .information {
56
+ display: flex;
57
+ flex-direction: column;
58
+ gap: 8px;
59
+ padding: 8px;
60
+ }
61
+
62
+ .name {
63
+ text-align: center;
64
+ }
65
+
66
+ .lastName {
67
+ font-weight: 700;
68
+ }
@@ -0,0 +1,47 @@
1
+ import * as React from "react";
2
+ import classNames from "classnames";
3
+ import { useUbloContext } from "ublo/with-ublo";
4
+ import * as Utils from "./utils";
5
+ import Instructor from "./instructor";
6
+ import { message } from "./messages";
7
+ import css from "./list.module.css";
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ import { jsxs as _jsxs } from "react/jsx-runtime";
10
+ export default function List({
11
+ search = "",
12
+ instructors,
13
+ fromSuggestions,
14
+ formSendFunction,
15
+ formFields,
16
+ trombi,
17
+ popup
18
+ }) {
19
+ const {
20
+ lang
21
+ } = useUbloContext();
22
+ const displayedInstructors = fromSuggestions ? instructors : Utils.filter(instructors, search);
23
+ const listCountMessageCode = displayedInstructors?.length > 1 ? "instructors" : "instructor";
24
+ const classes = classNames(css.container, {
25
+ [css.containerSuggestions]: fromSuggestions
26
+ });
27
+ return _jsxs("div", {
28
+ className: classes,
29
+ children: [!fromSuggestions && _jsxs("div", {
30
+ className: css.listCount,
31
+ children: [_jsx("b", {
32
+ children: displayedInstructors.length
33
+ }), " ", message(lang, listCountMessageCode)]
34
+ }), _jsx("div", {
35
+ className: css.inner,
36
+ children: displayedInstructors?.map(instructor => {
37
+ return _jsx(Instructor, {
38
+ instructor: instructor,
39
+ trombi: trombi,
40
+ formFields: formFields,
41
+ formSendFunction: formSendFunction,
42
+ popup: popup
43
+ }, instructor.uri);
44
+ })
45
+ })]
46
+ });
47
+ }
@@ -0,0 +1,18 @@
1
+ .container {
2
+ margin: 16px 0;
3
+ }
4
+
5
+ .listCount {
6
+ font-size: 14px;
7
+ }
8
+
9
+ .inner {
10
+ display: grid;
11
+ grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
12
+ gap: 26px;
13
+ padding: 10px 0;
14
+ }
15
+
16
+ .containerSuggestions .inner {
17
+ grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
18
+ }
@@ -0,0 +1,41 @@
1
+ const locales = {
2
+ fr: {
3
+ "search-label": "Chercher un moniteur",
4
+ "search-placeholder": "Nom, prénom...",
5
+ "activity-label": "Quelle pratique ?",
6
+ "language-label": "Quelle langue ?",
7
+ instructors: "moniteurs trouvés",
8
+ instructor: "moniteur trouvé",
9
+ activities: "Activités pratiquées",
10
+ and: "et",
11
+ languages: "Langues parlées",
12
+ about: "À propos",
13
+ contact: "Quand souhaitez-vous skier avec moi ?",
14
+ "suggestions-title": "Les moniteurs qui vous proposent ce cours",
15
+ "suggestions-button": "Voir tous les moniteurs",
16
+ "see-more": "Voir plus",
17
+ "go-back": "Retour"
18
+ },
19
+ en: {
20
+ "search-label": "Search an instructor",
21
+ "search-placeholder": "Lastname, firstname...",
22
+ "activity-label": "Which activity?",
23
+ "language-label": "Which language?",
24
+ instructors: "instructors found",
25
+ instructor: "instructor found",
26
+ activities: "Activities",
27
+ and: "and",
28
+ languages: "Spoken languages",
29
+ about: "About",
30
+ contact: "When would you like to ski with me?",
31
+ "suggestions-title": "The instructors who offer you this course",
32
+ "suggestions-button": "See all instructors",
33
+ "see-more": "See more",
34
+ "go-back": "Go back"
35
+ }
36
+ };
37
+ export const message = (lang, id) => {
38
+ const locale = lang === "fr" ? "fr" : "en";
39
+ const messages = locales[locale];
40
+ return messages[id] || `??${id}??`;
41
+ };
@@ -0,0 +1,5 @@
1
+ const prefixes = {
2
+ fr: "/moniteur",
3
+ en: "/instructor"
4
+ };
5
+ export default prefixes;
@@ -0,0 +1,172 @@
1
+ import * as React from "react";
2
+ import Image from "next/image";
3
+ import classNames from "classnames";
4
+ import { useUbloContext } from "ublo/with-ublo";
5
+ import CustomContactForm from "../../../common/components/custom-contact-form";
6
+ import Button from "dt-design-system/es/button";
7
+ import * as Icons from "dt-design-system/es/icons";
8
+ import * as Utils from "./utils";
9
+ import prefixes from "./prefixes";
10
+ import { message } from "./messages";
11
+ import css from "./sheet.module.css";
12
+ import { jsx as _jsx } from "react/jsx-runtime";
13
+ import { jsxs as _jsxs } from "react/jsx-runtime";
14
+ import { Fragment as _Fragment } from "react/jsx-runtime";
15
+ export default function Sheet({
16
+ instructor,
17
+ popup,
18
+ formFields,
19
+ formSendFunction,
20
+ bookUrl
21
+ }) {
22
+ const {
23
+ firstname,
24
+ lastname,
25
+ photo,
26
+ languages,
27
+ activities,
28
+ introduction,
29
+ description,
30
+ uri
31
+ } = instructor;
32
+ const {
33
+ lang
34
+ } = useUbloContext();
35
+ const [loading, setLoading] = React.useState(true);
36
+ const [picture, setPicture] = React.useState(photo);
37
+ const prefixLang = lang === "fr" ? "fr" : "en";
38
+ const stopLoading = () => {
39
+ setLoading(false);
40
+ };
41
+ const setFallbackPicture = ({
42
+ currentTarget
43
+ }) => {
44
+ setPicture(null);
45
+ stopLoading();
46
+ currentTarget.onerror = null;
47
+ };
48
+ const classes = classNames(css.container, {
49
+ [css.containerPopup]: popup
50
+ });
51
+ return _jsxs("div", {
52
+ className: classes,
53
+ children: [_jsxs("div", {
54
+ className: css.content,
55
+ children: [!popup && bookUrl && _jsxs(Button, {
56
+ tag: "a",
57
+ href: bookUrl,
58
+ variant: "link",
59
+ children: [_jsx(Icons.ChevronLeft, {}), message(lang, "go-back")]
60
+ }), _jsxs("div", {
61
+ className: css.header,
62
+ children: [_jsx("div", {
63
+ className: css.imageContainer,
64
+ children: picture ? _jsxs(_Fragment, {
65
+ children: [loading && _jsx(Icons.Loader2, {
66
+ className: css.imageLoader
67
+ }), _jsx(Image, {
68
+ loading: "lazy",
69
+ src: picture,
70
+ className: css.image,
71
+ alt: `${firstname} ${lastname}`,
72
+ onLoad: stopLoading,
73
+ onError: setFallbackPicture,
74
+ width: "190",
75
+ height: "250"
76
+ }, uri)]
77
+ }) : _jsx("div", {
78
+ className: css.imagePlaceholder,
79
+ children: _jsx(Icons.User, {
80
+ className: css.imagePlaceholderIcon
81
+ })
82
+ })
83
+ }), _jsxs("div", {
84
+ className: css.information,
85
+ children: [_jsxs("div", {
86
+ className: css.name,
87
+ children: [_jsxs("span", {
88
+ className: css.firstName,
89
+ children: [Utils.formatNames(firstname), " "]
90
+ }), _jsx("span", {
91
+ className: css.lastName,
92
+ children: Utils.formatNames(lastname)
93
+ })]
94
+ }), activities && _jsxs("div", {
95
+ className: css.activities,
96
+ children: [_jsx("div", {
97
+ className: css.activitiesTitle,
98
+ children: message(lang, "activities")
99
+ }), _jsx("div", {
100
+ className: css.activitiesList,
101
+ children: activities.map((activity, i) => {
102
+ const {
103
+ code,
104
+ label
105
+ } = activity;
106
+ const length = activities.length;
107
+ return _jsxs("span", {
108
+ className: css.activity,
109
+ children: [_jsx("span", {
110
+ children: label
111
+ }), i < length - 2 ? ", " : i < length - 1 ? ` ${message(lang, "and")} ` : ""]
112
+ }, code);
113
+ })
114
+ })]
115
+ }), languages && _jsxs("div", {
116
+ className: css.languages,
117
+ children: [_jsx("div", {
118
+ className: css.languagesTitle,
119
+ children: message(lang, "languages")
120
+ }), _jsx("div", {
121
+ className: css.languagesList,
122
+ children: languages.map((language, i) => {
123
+ const {
124
+ code,
125
+ label
126
+ } = language;
127
+ const length = languages.length;
128
+ return _jsxs("span", {
129
+ className: css.language,
130
+ children: [label, " ", i < length - 1 ? " - " : ""]
131
+ }, code);
132
+ })
133
+ })]
134
+ })]
135
+ })]
136
+ }), !popup && introduction && _jsx("div", {
137
+ className: css.introduction,
138
+ dangerouslySetInnerHTML: {
139
+ __html: introduction
140
+ }
141
+ }), description && _jsxs("div", {
142
+ className: css.description,
143
+ children: [_jsx("div", {
144
+ className: css.descriptionTitle,
145
+ children: message(lang, "about")
146
+ }), _jsx("div", {
147
+ className: css.descriptionInner,
148
+ dangerouslySetInnerHTML: {
149
+ __html: popup ? Utils.truncate(Utils.sanitizeHTML(description)) : description
150
+ }
151
+ }), popup && _jsxs(Button, {
152
+ tag: "a",
153
+ href: `${prefixes[prefixLang]}/${uri}`,
154
+ variant: "secondary",
155
+ target: "_blank",
156
+ children: [message(lang, "see-more"), _jsx(Icons.ChevronRight, {})]
157
+ })]
158
+ })]
159
+ }), formFields && formSendFunction && _jsxs("div", {
160
+ className: css.aside,
161
+ children: [_jsx("div", {
162
+ className: css.formTitle,
163
+ children: message(lang, "contact")
164
+ }), _jsx(CustomContactForm, {
165
+ fields: formFields,
166
+ className: css.form,
167
+ innerClassName: css.formInner,
168
+ customSend: formSendFunction(firstname, lastname)
169
+ })]
170
+ })]
171
+ });
172
+ }
@@ -0,0 +1,194 @@
1
+ .container {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 26px;
5
+ padding: 26px 0;
6
+ color: var(--ds-grey-600, #323338);
7
+ }
8
+
9
+ .containerPopup {
10
+ max-width: 780px;
11
+ padding: 16px;
12
+ }
13
+
14
+ @media (min-width: 910px) {
15
+ .container:not(.containerPopup) {
16
+ flex-direction: row;
17
+ }
18
+ }
19
+
20
+ .content {
21
+ flex: 0 1 60%;
22
+ display: flex;
23
+ flex-direction: column;
24
+ gap: 26px;
25
+ }
26
+
27
+ .header {
28
+ display: flex;
29
+ align-items: center;
30
+ gap: 44px;
31
+ }
32
+
33
+ .imageContainer {
34
+ position: relative;
35
+ width: 190px;
36
+ height: 250px;
37
+ display: flex;
38
+ align-items: center;
39
+ justify-content: center;
40
+ border-bottom: 1px solid var(--ds-grey-100, #f5f5f5);
41
+ border-radius: var(--ds-radius-200, 10px);
42
+ }
43
+
44
+ .image {
45
+ position: relative;
46
+ width: 100%;
47
+ height: 100%;
48
+ object-fit: cover;
49
+ border-radius: inherit;
50
+ }
51
+
52
+ .imageLoader {
53
+ position: absolute;
54
+ top: 50%;
55
+ left: 50%;
56
+ transform: translate(-50%, -50%);
57
+ fill: var(--ds-secondary, var(--ds-blue-400, #4177f6));
58
+ animation: image-loader-spinning 1280ms
59
+ var(--ds-transition-easing, cubic-bezier(0.4, 0.1, 0.2, 0.9)) infinite;
60
+ }
61
+
62
+ @keyframes image-loader-spinning {
63
+ 100% {
64
+ transform: translate(-50%, -50%) rotate(1turn);
65
+ }
66
+ }
67
+
68
+ .imagePlaceholder {
69
+ padding: 16px 22px;
70
+ background-color: var(--ds-grey-100, #f5f5f5);
71
+ border-radius: var(--ds-radius-100, 6px);
72
+ }
73
+
74
+ .imagePlaceholderIcon {
75
+ width: 34px;
76
+ height: 34px;
77
+ fill: var(--ds-grey-300, #d4d4d4);
78
+ }
79
+
80
+ .information {
81
+ display: flex;
82
+ flex-direction: column;
83
+ gap: 12px;
84
+ }
85
+
86
+ .name {
87
+ display: flex;
88
+ flex-direction: column;
89
+ gap: 4px;
90
+ font-size: 28px;
91
+ line-height: 1.1;
92
+ }
93
+
94
+ @media (min-width: 480px) {
95
+ .name {
96
+ font-size: 34px;
97
+ }
98
+ }
99
+
100
+ @media (min-width: 992px) {
101
+ .name {
102
+ font-size: 40px;
103
+ }
104
+ }
105
+
106
+ .lastName {
107
+ font-weight: 700;
108
+ }
109
+
110
+ .activities,
111
+ .languages {
112
+ display: flex;
113
+ flex-direction: column;
114
+ gap: 6px;
115
+ }
116
+
117
+ .activitiesTitle,
118
+ .languagesTitle {
119
+ font-size: 14px;
120
+ }
121
+
122
+ .activitiesList,
123
+ .languagesList {
124
+ font-size: 15px;
125
+ font-weight: 700;
126
+ }
127
+
128
+ .introduction {
129
+ color: var(--ds-secondary, var(--ds-blue-400, #4177f6));
130
+ line-height: 1.45;
131
+ font-size: 22px;
132
+ padding: 16px;
133
+ background-color: var(--ds-grey-100, #f5f5f5);
134
+ border-radius: var(--ds-radius-100, 6px);
135
+ }
136
+
137
+ .description {
138
+ display: flex;
139
+ flex-direction: column;
140
+ gap: 12px;
141
+ }
142
+
143
+ .descriptionTitle {
144
+ font-size: 22px;
145
+ font-weight: 700;
146
+ }
147
+
148
+ .description hr {
149
+ opacity: 0;
150
+ }
151
+
152
+ .descriptionInner {
153
+ font-size: 15px;
154
+ text-align: justify;
155
+ font-weight: 400;
156
+ line-height: 1.65;
157
+ }
158
+
159
+ .aside {
160
+ flex: 1 0 420px;
161
+ align-self: flex-start;
162
+ display: flex;
163
+ flex-direction: column;
164
+ gap: 12px;
165
+ margin: 0 auto;
166
+ padding: 16px;
167
+ border-radius: var(--ds-radius-100, 6px);
168
+ box-shadow: var(--ds-shadow-100, 0px 3px 6px rgba(0, 0, 0, 0.12));
169
+ }
170
+
171
+ .containerPopup .aside {
172
+ flex: auto;
173
+ align-self: normal;
174
+ margin: 0;
175
+ padding: 0;
176
+ box-shadow: none;
177
+ }
178
+
179
+ .formTitle {
180
+ font-size: 22px;
181
+ font-weight: 700;
182
+ }
183
+
184
+ .form {
185
+ padding-bottom: 0;
186
+ }
187
+
188
+ .formInner {
189
+ gap: 8px;
190
+ }
191
+
192
+ .containerPopup .formInner {
193
+ gap: 16px;
194
+ }
@@ -0,0 +1,59 @@
1
+ import * as React from "react";
2
+ import { useUbloContext } from "ublo/with-ublo";
3
+ import Button from "dt-design-system/es/button";
4
+ import * as Icons from "dt-design-system/es/icons";
5
+ import List from "./list";
6
+ import * as API from "./api";
7
+ import css from "./suggestions.module.css";
8
+ import { message } from "./messages";
9
+ import { jsx as _jsx } from "react/jsx-runtime";
10
+ import { jsxs as _jsxs } from "react/jsx-runtime";
11
+ export default function Suggestions({
12
+ bookUrl,
13
+ popup,
14
+ formFields,
15
+ formSendFunction
16
+ }) {
17
+ const [instructors, setInstructors] = React.useState([]);
18
+ const {
19
+ seo,
20
+ lang
21
+ } = useUbloContext();
22
+ const tags = React.useMemo(() => seo && seo.keywords && seo.keywords.trim() !== "" ? seo.keywords.split(",") : undefined, [seo]);
23
+ React.useEffect(() => {
24
+ const fetchInstructors = async () => {
25
+ if (tags) {
26
+ try {
27
+ const instructors = await API.fetchRandomInstructors(lang, tags, 6);
28
+ if (instructors) {
29
+ setInstructors(instructors);
30
+ }
31
+ } catch (e) {
32
+ setInstructors([]);
33
+ }
34
+ }
35
+ };
36
+ fetchInstructors();
37
+ }, [lang, tags]);
38
+ return _jsxs("div", {
39
+ className: css.suggestions,
40
+ children: [_jsxs("div", {
41
+ className: css.header,
42
+ children: [_jsx("div", {
43
+ className: css.headerTitle,
44
+ children: message(lang, "suggestions-title")
45
+ }), bookUrl && _jsxs(Button, {
46
+ tag: "a",
47
+ href: bookUrl,
48
+ className: css.headerButton,
49
+ children: [message(lang, "suggestions-button"), " ", _jsx(Icons.ArrowRight, {})]
50
+ })]
51
+ }), _jsx(List, {
52
+ instructors: instructors,
53
+ popup: popup,
54
+ formFields: formFields,
55
+ formSendFunction: formSendFunction,
56
+ fromSuggestions: true
57
+ })]
58
+ });
59
+ }
@@ -0,0 +1,17 @@
1
+ .suggestions {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 12px;
5
+ }
6
+
7
+ .header {
8
+ display: flex;
9
+ align-items: center;
10
+ justify-content: space-between;
11
+ gap: 22px;
12
+ }
13
+
14
+ .headerTitle {
15
+ font-size: 22px;
16
+ font-weight: 700;
17
+ }
@@ -0,0 +1,51 @@
1
+ const SLASH = "/";
2
+ export function truncate(input, lenght = 140) {
3
+ return input.length > lenght ? `${input.substring(0, lenght)}...` : input;
4
+ }
5
+ export function sanitizeHTML(text) {
6
+ const element = document.createElement("div");
7
+ element.innerHTML = text;
8
+ return element.textContent;
9
+ }
10
+ export function propsFromQueryString() {
11
+ if (typeof window === "undefined") return {};
12
+ const params = new URLSearchParams(document.location.search);
13
+ const activity = params.get("activity") || undefined;
14
+ const language = params.get("language") || undefined;
15
+ return {
16
+ activity,
17
+ language
18
+ };
19
+ }
20
+ export function hasTrailingSlash(path) {
21
+ return path.length > 1 && path.endsWith(SLASH);
22
+ }
23
+ export const formatNames = name => {
24
+ const lowercasedName = name && name.toLowerCase();
25
+ return lowercasedName ? lowercasedName.charAt(0).toUpperCase() + lowercasedName.slice(1) : "";
26
+ };
27
+ export function includesString(source, included) {
28
+ source.toLowerCase().includes(included.toLowerCase());
29
+ }
30
+ function strStartWith(str1, str2) {
31
+ return str1.toLowerCase().trim().startsWith(str2.toLowerCase().trim());
32
+ }
33
+ function strEquals(str1, str2) {
34
+ return str1.toLowerCase().trim() === str2.toLowerCase().trim();
35
+ }
36
+ function match(searchingArray, entries) {
37
+ return searchingArray.reduce((acc, str, index) => {
38
+ const matched = index === searchingArray.length - 1 ? strStartWith : strEquals;
39
+ return acc && entries.some(entry => matched(entry, str));
40
+ }, true);
41
+ }
42
+ export function filter(array, search = "") {
43
+ const searchingArray = search.split(" ");
44
+ const filtered = array.all.filter(uri => {
45
+ const instructor = array.byUri[uri];
46
+ const firstnameWords = instructor.firstname.split(" ");
47
+ const lastnameWords = instructor.lastname.split(" ");
48
+ return match(searchingArray, [...firstnameWords, ...lastnameWords]);
49
+ });
50
+ return filtered.reduce((acc, uri) => [...acc, array.byUri[uri]], []);
51
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ublo-lib",
3
- "version": "1.10.29",
3
+ "version": "1.11.1",
4
4
  "peerDependencies": {
5
5
  "dt-design-system": "^2.1.0",
6
6
  "leaflet": "^1.9.1",