ublo-lib 1.13.4 → 1.14.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/editable-calendar/calendar-caption.js +150 -0
- package/es/common/components/editable-calendar/calendar-caption.module.css +76 -0
- package/es/common/components/editable-calendar/calendar-date.js +84 -0
- package/es/common/components/editable-calendar/calendar-date.module.css +52 -0
- package/es/common/components/editable-calendar/calendar-editor.js +89 -0
- package/es/common/components/editable-calendar/calendar-editor.module.css +38 -0
- package/es/common/components/editable-calendar/calendar-header.js +30 -0
- package/es/common/components/editable-calendar/calendar-header.module.css +20 -0
- package/es/common/components/editable-calendar/calendar.js +127 -0
- package/es/common/components/editable-calendar/calendar.module.css +80 -0
- package/es/common/components/editable-calendar/data.js +112 -0
- package/es/common/components/editable-calendar/index.js +56 -0
- package/es/common/components/editable-calendar/utils.js +76 -0
- package/es/common/components/editable-map/edit-form.js +2 -2
- package/es/esf/components/loyal-customers/components/field.js +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { useUbloContext } from "ublo/with-ublo";
|
|
3
|
+
import Input from "dt-design-system/es/input";
|
|
4
|
+
import css from "./calendar-caption.module.css";
|
|
5
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
|
+
const defaultColors = ["#234d5c", "#5F2EEA", "#0038FF", "#4ec3df", "#24C678", "#FFB648", "#F26464", "#FF005C", "#7C7B7B", "#222222"];
|
|
8
|
+
export default function CalendarCaption({
|
|
9
|
+
presets,
|
|
10
|
+
setPresets
|
|
11
|
+
}) {
|
|
12
|
+
const {
|
|
13
|
+
cmsMode
|
|
14
|
+
} = useUbloContext();
|
|
15
|
+
const initialColors = presets.colors ? Object.keys(presets.colors).map(key => presets.colors[key].backgroundColor) : defaultColors;
|
|
16
|
+
const [colors, setColors] = React.useState(initialColors);
|
|
17
|
+
const initialTextColors = presets.colors ? Object.keys(presets.colors).map(key => presets.colors[key].textColor) : [...new Array(colors.length)].fill("#ffffff");
|
|
18
|
+
const [textColors, setTextColors] = React.useState(initialTextColors);
|
|
19
|
+
const initialValues = presets.colors ? Object.keys(presets.colors).map(color => presets.colors[color].text) : [...new Array(colors.length)].fill("");
|
|
20
|
+
const [values, setValues] = React.useState(initialValues);
|
|
21
|
+
const isEditing = cmsMode === "editing";
|
|
22
|
+
React.useEffect(() => {
|
|
23
|
+
if (isEditing) {
|
|
24
|
+
const newPresets = {
|
|
25
|
+
colors: colors.reduce((acc, color, index) => {
|
|
26
|
+
return {
|
|
27
|
+
...acc,
|
|
28
|
+
[index]: {
|
|
29
|
+
text: values[index],
|
|
30
|
+
backgroundColor: color,
|
|
31
|
+
textColor: textColors[index]
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}, {})
|
|
35
|
+
};
|
|
36
|
+
setPresets(currentPresets => {
|
|
37
|
+
return {
|
|
38
|
+
...currentPresets,
|
|
39
|
+
...newPresets
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}, [colors, isEditing, setPresets, textColors, values]);
|
|
44
|
+
return isEditing ? _jsx(Editor, {
|
|
45
|
+
colors: colors,
|
|
46
|
+
setColors: setColors,
|
|
47
|
+
values: values,
|
|
48
|
+
setValues: setValues,
|
|
49
|
+
textColors: textColors,
|
|
50
|
+
setTextColors: setTextColors
|
|
51
|
+
}) : _jsx(Caption, {
|
|
52
|
+
colors: colors,
|
|
53
|
+
values: values,
|
|
54
|
+
textColors: textColors
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function Editor({
|
|
58
|
+
colors,
|
|
59
|
+
setColors,
|
|
60
|
+
values,
|
|
61
|
+
setValues,
|
|
62
|
+
textColors,
|
|
63
|
+
setTextColors
|
|
64
|
+
}) {
|
|
65
|
+
return _jsxs("div", {
|
|
66
|
+
className: css.root,
|
|
67
|
+
children: [colors.map((color, index) => {
|
|
68
|
+
const updateValue = value => {
|
|
69
|
+
setValues(prev => {
|
|
70
|
+
const newValues = [...prev];
|
|
71
|
+
newValues[index] = value;
|
|
72
|
+
return newValues;
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
const updateColor = e => {
|
|
76
|
+
const color = e.target.value;
|
|
77
|
+
setColors(prev => {
|
|
78
|
+
const newColors = [...prev];
|
|
79
|
+
newColors[index] = color;
|
|
80
|
+
return newColors;
|
|
81
|
+
});
|
|
82
|
+
};
|
|
83
|
+
const updateTextColor = e => {
|
|
84
|
+
const color = e.target.value;
|
|
85
|
+
setTextColors(prev => {
|
|
86
|
+
const newTextColors = [...prev];
|
|
87
|
+
newTextColors[index] = color;
|
|
88
|
+
return newTextColors;
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
return _jsxs("div", {
|
|
92
|
+
className: css.row,
|
|
93
|
+
children: [_jsx(Input, {
|
|
94
|
+
className: css.color,
|
|
95
|
+
style: {
|
|
96
|
+
color: textColors[index],
|
|
97
|
+
backgroundColor: color
|
|
98
|
+
},
|
|
99
|
+
placeholder: "Horaires",
|
|
100
|
+
onValueChange: updateValue,
|
|
101
|
+
value: values[index],
|
|
102
|
+
compact: true
|
|
103
|
+
}), _jsx("input", {
|
|
104
|
+
className: css.colorPicker,
|
|
105
|
+
type: "color",
|
|
106
|
+
value: color,
|
|
107
|
+
onChange: updateColor
|
|
108
|
+
}), _jsx("input", {
|
|
109
|
+
className: css.textColorPicker,
|
|
110
|
+
type: "color",
|
|
111
|
+
value: textColors[index],
|
|
112
|
+
onChange: updateTextColor,
|
|
113
|
+
list: "textColors"
|
|
114
|
+
}), _jsx("span", {
|
|
115
|
+
className: css.textPickerLabel,
|
|
116
|
+
children: "A"
|
|
117
|
+
})]
|
|
118
|
+
}, `${color}-${index}`);
|
|
119
|
+
}), _jsxs("datalist", {
|
|
120
|
+
id: "textColors",
|
|
121
|
+
children: [_jsx("option", {
|
|
122
|
+
children: "#000000"
|
|
123
|
+
}), _jsx("option", {
|
|
124
|
+
children: "#ffffff"
|
|
125
|
+
})]
|
|
126
|
+
})]
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function Caption({
|
|
130
|
+
colors,
|
|
131
|
+
values,
|
|
132
|
+
textColors
|
|
133
|
+
}) {
|
|
134
|
+
return _jsx("div", {
|
|
135
|
+
className: css.root,
|
|
136
|
+
children: colors.map((color, index) => {
|
|
137
|
+
return _jsx("div", {
|
|
138
|
+
className: css.row,
|
|
139
|
+
children: _jsx("div", {
|
|
140
|
+
className: css.color,
|
|
141
|
+
style: {
|
|
142
|
+
color: textColors[index],
|
|
143
|
+
backgroundColor: color
|
|
144
|
+
},
|
|
145
|
+
children: values[index]
|
|
146
|
+
})
|
|
147
|
+
}, `${color}-${index}`);
|
|
148
|
+
})
|
|
149
|
+
});
|
|
150
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
flex: 0 0 auto;
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
gap: 3px;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.row {
|
|
9
|
+
position: relative;
|
|
10
|
+
display: flex;
|
|
11
|
+
align-items: center;
|
|
12
|
+
gap: 3px;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.color {
|
|
16
|
+
width: 140px;
|
|
17
|
+
height: 30px;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.color input::placeholder {
|
|
21
|
+
color: inherit;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
div.color {
|
|
25
|
+
flex: 1 1 100%;
|
|
26
|
+
width: auto;
|
|
27
|
+
min-width: 140px;
|
|
28
|
+
display: flex;
|
|
29
|
+
align-items: center;
|
|
30
|
+
justify-content: center;
|
|
31
|
+
padding: 3px 8px;
|
|
32
|
+
text-align: center;
|
|
33
|
+
border-radius: var(--ds-radius-100, 4px);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
div.color:empty {
|
|
37
|
+
display: none;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.color:has(input:focus) {
|
|
41
|
+
z-index: 2;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.colorPicker,
|
|
45
|
+
.textColorPicker {
|
|
46
|
+
flex: 0 0 30px;
|
|
47
|
+
width: 30px;
|
|
48
|
+
height: 30px;
|
|
49
|
+
padding: 0;
|
|
50
|
+
border: 0;
|
|
51
|
+
background-color: transparent;
|
|
52
|
+
cursor: pointer;
|
|
53
|
+
border-radius: var(--ds-radius-100, 4px);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.textColorPicker {
|
|
57
|
+
flex: 0 0 60px;
|
|
58
|
+
width: 60px;
|
|
59
|
+
appearance: none;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.colorPicker:focus {
|
|
63
|
+
z-index: 3;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.textPickerLabel {
|
|
67
|
+
position: absolute;
|
|
68
|
+
top: 6px;
|
|
69
|
+
right: 33px;
|
|
70
|
+
font-family: "Times New Roman", Times, serif;
|
|
71
|
+
font-size: 14px;
|
|
72
|
+
font-weight: 700;
|
|
73
|
+
color: rgb(255, 255, 255);
|
|
74
|
+
mix-blend-mode: difference;
|
|
75
|
+
pointer-events: none;
|
|
76
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import classnames from "classnames";
|
|
3
|
+
import { useUbloContext } from "ublo/with-ublo";
|
|
4
|
+
import * as Ripple from "dt-design-system/es/ripple";
|
|
5
|
+
import * as Utils from "./utils";
|
|
6
|
+
import css from "./calendar-date.module.css";
|
|
7
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
+
export default React.memo(CalendarDate);
|
|
9
|
+
function CalendarDate({
|
|
10
|
+
date,
|
|
11
|
+
month,
|
|
12
|
+
year,
|
|
13
|
+
minDate,
|
|
14
|
+
presets,
|
|
15
|
+
selecting,
|
|
16
|
+
setSelecting,
|
|
17
|
+
hoveredDates,
|
|
18
|
+
setHoveredDates
|
|
19
|
+
}) {
|
|
20
|
+
const {
|
|
21
|
+
cmsMode
|
|
22
|
+
} = useUbloContext();
|
|
23
|
+
const {
|
|
24
|
+
colors,
|
|
25
|
+
dates = {}
|
|
26
|
+
} = presets;
|
|
27
|
+
const isEditing = cmsMode === "editing";
|
|
28
|
+
const dateString = date.join("-");
|
|
29
|
+
const _date = new Date(dateString);
|
|
30
|
+
_date.setHours(0, 0, 0, 0);
|
|
31
|
+
const datesKeys = Object.keys(dates);
|
|
32
|
+
const isInPresets = datesKeys.includes(dateString);
|
|
33
|
+
const dateStyles = isInPresets ? {
|
|
34
|
+
color: colors[dates[dateString]].textColor,
|
|
35
|
+
backgroundColor: colors[dates[dateString]].backgroundColor
|
|
36
|
+
} : undefined;
|
|
37
|
+
const dateTooltip = isInPresets && !isEditing ? colors[dates[dateString]].text : undefined;
|
|
38
|
+
const isToday = Utils.isSameDay(_date);
|
|
39
|
+
const inMonth = month && year && Utils.isSameMonth(_date, new Date([Utils.zeroPad(year, 2), Utils.zeroPad(month, 2), "01"].join("-")));
|
|
40
|
+
const isDisabled = minDate && _date < minDate;
|
|
41
|
+
const createRipple = e => {
|
|
42
|
+
Ripple.create(e);
|
|
43
|
+
};
|
|
44
|
+
const startSelecting = e => {
|
|
45
|
+
if (isDisabled) return;
|
|
46
|
+
createRipple(e);
|
|
47
|
+
if (!isEditing) return;
|
|
48
|
+
setSelecting(true);
|
|
49
|
+
setHoveredDates([_date]);
|
|
50
|
+
};
|
|
51
|
+
const stopSelecting = () => {
|
|
52
|
+
if (!isEditing) return;
|
|
53
|
+
setSelecting(false);
|
|
54
|
+
};
|
|
55
|
+
const computeSelection = () => {
|
|
56
|
+
if (isDisabled || !isEditing || !selecting) return;
|
|
57
|
+
let startDate = hoveredDates[0];
|
|
58
|
+
const endDate = _date;
|
|
59
|
+
const isBefore = startDate.getTime() > endDate.getTime();
|
|
60
|
+
if (isBefore) {
|
|
61
|
+
startDate = hoveredDates[hoveredDates.length - 1];
|
|
62
|
+
}
|
|
63
|
+
const dates = Utils.getDateInterval(startDate, endDate, isBefore);
|
|
64
|
+
setHoveredDates(dates);
|
|
65
|
+
};
|
|
66
|
+
const classes = classnames(css.date, {
|
|
67
|
+
[css.dateToday]: isToday,
|
|
68
|
+
[css.dateNotInMonth]: !inMonth,
|
|
69
|
+
[css.dateDisabled]: isDisabled,
|
|
70
|
+
[css.dateHovered]: !!hoveredDates.find(item => {
|
|
71
|
+
return item.getTime() === _date.getTime();
|
|
72
|
+
})
|
|
73
|
+
});
|
|
74
|
+
return _jsx("button", {
|
|
75
|
+
className: classes,
|
|
76
|
+
tabIndex: isDisabled ? -1 : 0,
|
|
77
|
+
onMouseDown: startSelecting,
|
|
78
|
+
onMouseEnter: computeSelection,
|
|
79
|
+
onMouseUp: stopSelecting,
|
|
80
|
+
style: dateStyles,
|
|
81
|
+
"data-tooltip": dateTooltip,
|
|
82
|
+
children: _date.getDate()
|
|
83
|
+
});
|
|
84
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
.date {
|
|
2
|
+
position: relative;
|
|
3
|
+
width: 100%;
|
|
4
|
+
margin: 0;
|
|
5
|
+
padding: 8px 6px;
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
font-size: 14px;
|
|
8
|
+
text-align: center;
|
|
9
|
+
color: var(--ds-grey-700, #262626);
|
|
10
|
+
background-color: transparent;
|
|
11
|
+
border: 0;
|
|
12
|
+
border-radius: var(--ds-radius-200, 8px);
|
|
13
|
+
cursor: pointer;
|
|
14
|
+
user-select: none;
|
|
15
|
+
outline: none;
|
|
16
|
+
transition: color 160ms
|
|
17
|
+
var(--ds-transition-easing, cubic-bezier(0.4, 0.1, 0.2, 0.9)),
|
|
18
|
+
background-color 160ms
|
|
19
|
+
var(--ds-transition-easing, cubic-bezier(0.4, 0.1, 0.2, 0.9)),
|
|
20
|
+
border-radius 160ms
|
|
21
|
+
var(--ds-transition-easing, cubic-bezier(0.4, 0.1, 0.2, 0.9));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.date:focus-visible {
|
|
25
|
+
outline: var(--ds-focus-ring-width, 2px) solid
|
|
26
|
+
var(--ds-focus-ring-color, var(--ds-blue-400, #0038ff));
|
|
27
|
+
outline-offset: var(--ds-focus-ring-offset, 2px);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.dateToday {
|
|
31
|
+
font-weight: 700;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.dateHovered {
|
|
35
|
+
color: var(--ds-white, #fff) !important;
|
|
36
|
+
background-color: var(--ds-secondary, var(--ds-blue-400, #0038ff)) !important;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.dateDisabled,
|
|
40
|
+
.dateDisabled.dateNotInMonth {
|
|
41
|
+
opacity: 0.25;
|
|
42
|
+
transform: translateZ(0);
|
|
43
|
+
cursor: not-allowed;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.dateNotInMonth {
|
|
47
|
+
opacity: 0.5;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.date:not(.dateDisabled, .dateHovered):hover {
|
|
51
|
+
background-color: var(--ds-grey-200, #ededed);
|
|
52
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import Button from "dt-design-system/es/button";
|
|
3
|
+
import * as Icons from "dt-design-system/es/icons";
|
|
4
|
+
import css from "./calendar-editor.module.css";
|
|
5
|
+
import * as Utils from "./utils";
|
|
6
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
8
|
+
export default function CalendarEditor({
|
|
9
|
+
presets,
|
|
10
|
+
setPresets,
|
|
11
|
+
hoveredDates,
|
|
12
|
+
closeEditor
|
|
13
|
+
}) {
|
|
14
|
+
const {
|
|
15
|
+
colors,
|
|
16
|
+
dates = {}
|
|
17
|
+
} = presets;
|
|
18
|
+
const formatedHoveredDates = hoveredDates.map(date => {
|
|
19
|
+
return Utils.formatDate(date);
|
|
20
|
+
});
|
|
21
|
+
const updateDates = colorIndex => () => {
|
|
22
|
+
const newDates = formatedHoveredDates.reduce((acc, date) => {
|
|
23
|
+
if (!colorIndex) return acc;
|
|
24
|
+
return {
|
|
25
|
+
...acc,
|
|
26
|
+
[date]: colorIndex
|
|
27
|
+
};
|
|
28
|
+
}, {});
|
|
29
|
+
const newPresets = {
|
|
30
|
+
dates: {
|
|
31
|
+
...dates,
|
|
32
|
+
...newDates
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
if (!colorIndex) {
|
|
36
|
+
for (const date of formatedHoveredDates) {
|
|
37
|
+
delete newPresets.dates[date];
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
Object.keys(dates).forEach(key => {
|
|
41
|
+
const now = new Date();
|
|
42
|
+
const date = new Date(key);
|
|
43
|
+
if (date < now) {
|
|
44
|
+
delete newPresets.dates[key];
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
setPresets(currentPresets => {
|
|
48
|
+
return {
|
|
49
|
+
...currentPresets,
|
|
50
|
+
...newPresets
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
closeEditor();
|
|
54
|
+
};
|
|
55
|
+
return _jsxs("div", {
|
|
56
|
+
className: css.editor,
|
|
57
|
+
children: [_jsx(Button, {
|
|
58
|
+
variant: "transparent",
|
|
59
|
+
className: css.close,
|
|
60
|
+
onClick: closeEditor,
|
|
61
|
+
children: _jsx(Icons.Cross, {})
|
|
62
|
+
}), _jsxs("div", {
|
|
63
|
+
className: css.inner,
|
|
64
|
+
children: [_jsx(Button, {
|
|
65
|
+
variant: "transparent",
|
|
66
|
+
className: css.cleanup,
|
|
67
|
+
onClick: updateDates(),
|
|
68
|
+
children: "Aucun"
|
|
69
|
+
}), Object.keys(colors).map(key => {
|
|
70
|
+
const {
|
|
71
|
+
text,
|
|
72
|
+
backgroundColor,
|
|
73
|
+
textColor
|
|
74
|
+
} = colors[key];
|
|
75
|
+
if (!text) return null;
|
|
76
|
+
return _jsx(Button, {
|
|
77
|
+
variant: "secondary",
|
|
78
|
+
className: css.color,
|
|
79
|
+
style: {
|
|
80
|
+
color: textColor,
|
|
81
|
+
backgroundColor
|
|
82
|
+
},
|
|
83
|
+
onClick: updateDates(key),
|
|
84
|
+
children: text
|
|
85
|
+
}, key);
|
|
86
|
+
})]
|
|
87
|
+
})]
|
|
88
|
+
});
|
|
89
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
.editor {
|
|
2
|
+
position: absolute;
|
|
3
|
+
top: 0;
|
|
4
|
+
left: 0;
|
|
5
|
+
width: 100%;
|
|
6
|
+
height: 100%;
|
|
7
|
+
display: flex;
|
|
8
|
+
align-items: center;
|
|
9
|
+
justify-content: center;
|
|
10
|
+
background-color: rgba(0, 0, 0, 0.75);
|
|
11
|
+
backdrop-filter: blur(var(--ds-blur, 8px));
|
|
12
|
+
padding: 20px;
|
|
13
|
+
border-radius: inherit;
|
|
14
|
+
z-index: 2;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.close {
|
|
18
|
+
position: absolute;
|
|
19
|
+
top: 8px;
|
|
20
|
+
right: 8px;
|
|
21
|
+
color: var(--ds-grey-000, #ffffff);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.inner {
|
|
25
|
+
width: 380px;
|
|
26
|
+
max-width: 100%;
|
|
27
|
+
display: flex;
|
|
28
|
+
align-items: flex-start;
|
|
29
|
+
flex-wrap: wrap;
|
|
30
|
+
gap: 4px;
|
|
31
|
+
padding: 16px;
|
|
32
|
+
background-color: var(--ds-grey-000, #ffffff);
|
|
33
|
+
border-radius: inherit;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.color {
|
|
37
|
+
flex: 1 1 auto;
|
|
38
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import Button from "dt-design-system/es/button";
|
|
3
|
+
import * as Icons from "dt-design-system/es/icons";
|
|
4
|
+
import css from "./calendar-header.module.css";
|
|
5
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
|
+
export default function Header({
|
|
8
|
+
goToPreviousMonth,
|
|
9
|
+
goToNextMonth,
|
|
10
|
+
monthName,
|
|
11
|
+
year,
|
|
12
|
+
pastMonthDisabled
|
|
13
|
+
}) {
|
|
14
|
+
return _jsxs("div", {
|
|
15
|
+
className: css.header,
|
|
16
|
+
children: [_jsx(Button, {
|
|
17
|
+
className: css.control,
|
|
18
|
+
onClick: goToPreviousMonth,
|
|
19
|
+
disabled: !!pastMonthDisabled,
|
|
20
|
+
children: _jsx(Icons.ChevronLeft, {})
|
|
21
|
+
}), _jsxs("div", {
|
|
22
|
+
className: css.title,
|
|
23
|
+
children: [monthName, " ", year]
|
|
24
|
+
}), _jsx(Button, {
|
|
25
|
+
className: css.control,
|
|
26
|
+
onClick: goToNextMonth,
|
|
27
|
+
children: _jsx(Icons.ChevronRight, {})
|
|
28
|
+
})]
|
|
29
|
+
});
|
|
30
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
.header {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
button.control {
|
|
7
|
+
color: var(--ds-grey-600, #484848);
|
|
8
|
+
background-color: transparent;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.title {
|
|
12
|
+
margin: 0 auto;
|
|
13
|
+
color: var(--ds-grey-600, #484848);
|
|
14
|
+
font-weight: 700;
|
|
15
|
+
background-color: transparent;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
button.control:not(:disabled):hover {
|
|
19
|
+
background-color: var(--ds-grey-100, #f8f8f8);
|
|
20
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import classnames from "classnames";
|
|
3
|
+
import Header from "./calendar-header";
|
|
4
|
+
import CalendarDate from "./calendar-date";
|
|
5
|
+
import CalendarEditor from "./calendar-editor";
|
|
6
|
+
import CalendarCaption from "./calendar-caption";
|
|
7
|
+
import * as Data from "./data";
|
|
8
|
+
import * as Utils from "./utils";
|
|
9
|
+
import css from "./calendar.module.css";
|
|
10
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
11
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
12
|
+
export default React.forwardRef(Calendar);
|
|
13
|
+
function Calendar({
|
|
14
|
+
lang = "fr",
|
|
15
|
+
format,
|
|
16
|
+
className
|
|
17
|
+
}, ref) {
|
|
18
|
+
const locale = lang || (typeof navigator !== "undefined" && navigator.language) === "fr" ? "fr" : "en";
|
|
19
|
+
const [presets, setPresets] = React.useState(format.presets);
|
|
20
|
+
React.useEffect(() => {
|
|
21
|
+
format.element.dataset.presets = JSON.stringify(presets);
|
|
22
|
+
}, [format, presets]);
|
|
23
|
+
const now = new Date();
|
|
24
|
+
const minDate = now;
|
|
25
|
+
if (minDate) minDate.setHours(0, 0, 0, 0);
|
|
26
|
+
const defaultMonth = Date.THIS_MONTH;
|
|
27
|
+
const currentMonth = getMonthFromPresets(presets?.dates);
|
|
28
|
+
const currentYear = Data.THIS_YEAR;
|
|
29
|
+
const [month, setMonth] = React.useState(currentMonth);
|
|
30
|
+
const [year, setYear] = React.useState(currentYear);
|
|
31
|
+
const [selecting, setSelecting] = React.useState(false);
|
|
32
|
+
const [hoveredDates, setHoveredDates] = React.useState([]);
|
|
33
|
+
const showAssociationEditor = !selecting && hoveredDates.length > 0;
|
|
34
|
+
const closeEditor = () => {
|
|
35
|
+
setSelecting(false);
|
|
36
|
+
setHoveredDates([]);
|
|
37
|
+
};
|
|
38
|
+
const resetSelection = () => {
|
|
39
|
+
if (!selecting) return;
|
|
40
|
+
setSelecting(false);
|
|
41
|
+
setHoveredDates([]);
|
|
42
|
+
};
|
|
43
|
+
const pastMonthDisabled = minDate && month <= minDate.getMonth() + 1 && year <= minDate.getFullYear() || minDate && month <= defaultMonth && year <= currentYear;
|
|
44
|
+
const i18nMonths = Data.MONTHS[locale];
|
|
45
|
+
const monthName = i18nMonths[Object.keys(i18nMonths)[month - 1]];
|
|
46
|
+
const i18nWeekDays = Data.WEEK_DAYS[locale];
|
|
47
|
+
const days = Object.keys(i18nWeekDays);
|
|
48
|
+
const calendarDates = Data.calendar(month, year);
|
|
49
|
+
const goToPreviousMonth = () => {
|
|
50
|
+
const {
|
|
51
|
+
month: newMonth,
|
|
52
|
+
year: newYear
|
|
53
|
+
} = Utils.getPreviousMonth(month, year);
|
|
54
|
+
setMonth(newMonth);
|
|
55
|
+
setYear(newYear);
|
|
56
|
+
};
|
|
57
|
+
const goToNextMonth = () => {
|
|
58
|
+
const {
|
|
59
|
+
month: newMonth,
|
|
60
|
+
year: newYear
|
|
61
|
+
} = Utils.getNextMonth(month, year);
|
|
62
|
+
setMonth(newMonth);
|
|
63
|
+
setYear(newYear);
|
|
64
|
+
};
|
|
65
|
+
const classes = classnames(css.root, className);
|
|
66
|
+
return _jsx("div", {
|
|
67
|
+
ref: ref,
|
|
68
|
+
className: classes,
|
|
69
|
+
"data-cms-remove": "",
|
|
70
|
+
children: _jsxs("div", {
|
|
71
|
+
className: css.outer,
|
|
72
|
+
children: [_jsxs("div", {
|
|
73
|
+
className: css.calendar,
|
|
74
|
+
children: [_jsxs("div", {
|
|
75
|
+
className: css.inner,
|
|
76
|
+
children: [_jsx(Header, {
|
|
77
|
+
goToPreviousMonth: goToPreviousMonth,
|
|
78
|
+
goToNextMonth: goToNextMonth,
|
|
79
|
+
monthName: monthName,
|
|
80
|
+
year: year,
|
|
81
|
+
pastMonthDisabled: pastMonthDisabled
|
|
82
|
+
}), _jsx("div", {
|
|
83
|
+
className: css.days,
|
|
84
|
+
children: days.map((day, i) => _jsx("div", {
|
|
85
|
+
className: css.day,
|
|
86
|
+
children: i18nWeekDays[day]
|
|
87
|
+
}, `${day}-${i}`))
|
|
88
|
+
}), _jsx("div", {
|
|
89
|
+
className: css.dates,
|
|
90
|
+
onMouseLeave: resetSelection,
|
|
91
|
+
children: calendarDates.map((date, i) => _jsx(CalendarDate, {
|
|
92
|
+
date: date,
|
|
93
|
+
month: month,
|
|
94
|
+
year: year,
|
|
95
|
+
minDate: minDate,
|
|
96
|
+
presets: presets,
|
|
97
|
+
setPresets: setPresets,
|
|
98
|
+
selecting: selecting,
|
|
99
|
+
setSelecting: setSelecting,
|
|
100
|
+
hoveredDates: hoveredDates,
|
|
101
|
+
setHoveredDates: setHoveredDates
|
|
102
|
+
}, i))
|
|
103
|
+
})]
|
|
104
|
+
}), showAssociationEditor && _jsx(CalendarEditor, {
|
|
105
|
+
presets: presets,
|
|
106
|
+
setPresets: setPresets,
|
|
107
|
+
hoveredDates: hoveredDates,
|
|
108
|
+
closeEditor: closeEditor
|
|
109
|
+
})]
|
|
110
|
+
}), _jsx(CalendarCaption, {
|
|
111
|
+
presets: presets,
|
|
112
|
+
setPresets: setPresets
|
|
113
|
+
})]
|
|
114
|
+
})
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
function getMonthFromPresets(dates = {}) {
|
|
118
|
+
const keys = Object.keys(dates);
|
|
119
|
+
if (keys.length === 0) return Data.THIS_MONTH;
|
|
120
|
+
const sortedKeys = keys.sort((a, b) => {
|
|
121
|
+
const dateA = new Date(a);
|
|
122
|
+
const dateB = new Date(b);
|
|
123
|
+
return dateA.getTime() - dateB.getTime();
|
|
124
|
+
});
|
|
125
|
+
const firstDate = new Date(sortedKeys[0]);
|
|
126
|
+
return firstDate.getMonth() + 1;
|
|
127
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
justify-content: center;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.outer {
|
|
8
|
+
position: relative;
|
|
9
|
+
display: flex;
|
|
10
|
+
align-items: center;
|
|
11
|
+
justify-content: center;
|
|
12
|
+
gap: 10px;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
:global(body:not(.cms--editing) [data-caption-position="haut"]) .outer {
|
|
16
|
+
flex-direction: column;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
:global(body:not(.cms--editing) [data-caption-position="haut"]) .outer {
|
|
20
|
+
flex-direction: column-reverse;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
:global(body:not(.cms--editing) [data-caption-position="gauche"]) .outer {
|
|
24
|
+
flex-direction: row-reverse;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.calendar {
|
|
28
|
+
width: min-content;
|
|
29
|
+
padding: 6px;
|
|
30
|
+
box-sizing: border-box;
|
|
31
|
+
font-family: var(--ds-sans-serif-font, Montserrat, sans-serif);
|
|
32
|
+
background-color: var(--ds-grey-000, #fff);
|
|
33
|
+
border: 1px solid var(--ds-grey-100, #ebebeb);
|
|
34
|
+
border-radius: var(--ds-date-picker-radius, var(--ds-radius-200, 8px));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@media (min-width: 350px) {
|
|
38
|
+
.calendar {
|
|
39
|
+
padding: 14px;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.inner {
|
|
44
|
+
position: relative;
|
|
45
|
+
display: flex;
|
|
46
|
+
flex-direction: column;
|
|
47
|
+
gap: 10px;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.dates,
|
|
51
|
+
.days {
|
|
52
|
+
display: grid;
|
|
53
|
+
grid-template-columns: repeat(7, minmax(36px, 1fr));
|
|
54
|
+
gap: 3px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@media (min-width: 350px) {
|
|
58
|
+
.dates,
|
|
59
|
+
.days {
|
|
60
|
+
grid-template-columns: repeat(7, minmax(40px, 1fr));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.days {
|
|
65
|
+
height: 34px;
|
|
66
|
+
align-items: center;
|
|
67
|
+
margin-bottom: 3px;
|
|
68
|
+
background-color: var(--ds-grey-100, #f8f8f8);
|
|
69
|
+
border-radius: var(--ds-radius-200, 8px);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.day {
|
|
73
|
+
color: var(--ds-grey-500, #7c7b7b);
|
|
74
|
+
font-size: 15px;
|
|
75
|
+
text-align: center;
|
|
76
|
+
font-weight: 700;
|
|
77
|
+
text-transform: uppercase;
|
|
78
|
+
transition: color 160ms
|
|
79
|
+
var(--ds-transition-easing, cubic-bezier(0.4, 0.1, 0.2, 0.9));
|
|
80
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import * as Utils from "./utils";
|
|
2
|
+
export const THIS_YEAR = new Date().getFullYear();
|
|
3
|
+
export const THIS_MONTH = new Date().getMonth() + 1;
|
|
4
|
+
export const MONTHS = {
|
|
5
|
+
fr: {
|
|
6
|
+
january: "Janvier",
|
|
7
|
+
february: "Février",
|
|
8
|
+
march: "Mars",
|
|
9
|
+
april: "Avril",
|
|
10
|
+
may: "Mai",
|
|
11
|
+
june: "Juin",
|
|
12
|
+
july: "Juillet",
|
|
13
|
+
august: "Aout",
|
|
14
|
+
september: "Septembre",
|
|
15
|
+
october: "Octobre",
|
|
16
|
+
november: "Novembre",
|
|
17
|
+
december: "Décembre"
|
|
18
|
+
},
|
|
19
|
+
en: {
|
|
20
|
+
january: "January",
|
|
21
|
+
february: "February",
|
|
22
|
+
march: "March",
|
|
23
|
+
april: "April",
|
|
24
|
+
may: "May",
|
|
25
|
+
june: "June",
|
|
26
|
+
july: "July",
|
|
27
|
+
august: "August",
|
|
28
|
+
september: "September",
|
|
29
|
+
october: "October",
|
|
30
|
+
november: "November",
|
|
31
|
+
december: "December"
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
export const SHORT_MONTHS = {
|
|
35
|
+
fr: {
|
|
36
|
+
january: "Jan",
|
|
37
|
+
february: "Fév",
|
|
38
|
+
march: "Mar",
|
|
39
|
+
april: "Avr",
|
|
40
|
+
may: "Mai",
|
|
41
|
+
june: "Juin",
|
|
42
|
+
july: "Juil",
|
|
43
|
+
august: "Aou",
|
|
44
|
+
september: "Sept",
|
|
45
|
+
october: "Oct",
|
|
46
|
+
november: "Nov",
|
|
47
|
+
december: "Déc"
|
|
48
|
+
},
|
|
49
|
+
en: {
|
|
50
|
+
january: "Jan",
|
|
51
|
+
february: "Feb",
|
|
52
|
+
march: "Mar",
|
|
53
|
+
april: "Apr",
|
|
54
|
+
may: "May",
|
|
55
|
+
june: "Jun",
|
|
56
|
+
july: "Jul",
|
|
57
|
+
august: "Aug",
|
|
58
|
+
september: "Sept",
|
|
59
|
+
october: "Oct",
|
|
60
|
+
november: "Nov",
|
|
61
|
+
december: "Dec"
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
export const WEEK_DAYS = {
|
|
65
|
+
fr: {
|
|
66
|
+
monday: "L",
|
|
67
|
+
tuesday: "M",
|
|
68
|
+
wednesday: "M",
|
|
69
|
+
thursday: "J",
|
|
70
|
+
friday: "V",
|
|
71
|
+
saturday: "S",
|
|
72
|
+
sunday: "D"
|
|
73
|
+
},
|
|
74
|
+
en: {
|
|
75
|
+
monday: "M",
|
|
76
|
+
tuesday: "T",
|
|
77
|
+
wednesday: "W",
|
|
78
|
+
thursday: "T",
|
|
79
|
+
friday: "F",
|
|
80
|
+
saturday: "S",
|
|
81
|
+
sunday: "S"
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
export const CALENDAR_WEEKS = 6;
|
|
85
|
+
export function calendar(month = THIS_MONTH, year = THIS_YEAR) {
|
|
86
|
+
const monthDays = Utils.getMonthDays(month, year);
|
|
87
|
+
const monthFirstDay = Utils.getMonthFirstDay(month, year);
|
|
88
|
+
const daysFromPrevMonth = monthFirstDay === 0 ? 6 : monthFirstDay - 1;
|
|
89
|
+
const daysFromNextMonth = CALENDAR_WEEKS * 7 - (daysFromPrevMonth + monthDays);
|
|
90
|
+
const {
|
|
91
|
+
month: prevMonth,
|
|
92
|
+
year: prevMonthYear
|
|
93
|
+
} = Utils.getPreviousMonth(month, year);
|
|
94
|
+
const {
|
|
95
|
+
month: nextMonth,
|
|
96
|
+
year: nextMonthYear
|
|
97
|
+
} = Utils.getNextMonth(month, year);
|
|
98
|
+
const prevMonthDays = Utils.getMonthDays(prevMonth, prevMonthYear);
|
|
99
|
+
const prevMonthDates = [...new Array(daysFromPrevMonth)].map((_, i) => {
|
|
100
|
+
const day = i + 1 + (prevMonthDays - daysFromPrevMonth);
|
|
101
|
+
return [prevMonthYear, Utils.zeroPad(prevMonth, 2), Utils.zeroPad(day, 2)];
|
|
102
|
+
});
|
|
103
|
+
const thisMonthDates = [...new Array(monthDays)].map((_, i) => {
|
|
104
|
+
const day = i + 1;
|
|
105
|
+
return [year, Utils.zeroPad(month, 2), Utils.zeroPad(day, 2)];
|
|
106
|
+
});
|
|
107
|
+
const nextMonthDates = [...new Array(daysFromNextMonth)].map((_, i) => {
|
|
108
|
+
const day = i + 1;
|
|
109
|
+
return [nextMonthYear, Utils.zeroPad(nextMonth, 2), Utils.zeroPad(day, 2)];
|
|
110
|
+
});
|
|
111
|
+
return [...prevMonthDates, ...thisMonthDates, ...nextMonthDates];
|
|
112
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import * as ReactDOM from "react-dom";
|
|
3
|
+
import dynamic from "next/dynamic";
|
|
4
|
+
import { useUbloContext } from "ublo/with-ublo";
|
|
5
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
6
|
+
const Calendar = dynamic(() => import("./calendar"), {
|
|
7
|
+
ssr: false
|
|
8
|
+
});
|
|
9
|
+
export default function EditableCalendar() {
|
|
10
|
+
const {
|
|
11
|
+
lang,
|
|
12
|
+
path
|
|
13
|
+
} = useUbloContext();
|
|
14
|
+
const [formats, setFormats] = React.useState([]);
|
|
15
|
+
const refreshFormats = React.useCallback(() => {
|
|
16
|
+
setFormats([]);
|
|
17
|
+
const elements = document.querySelectorAll("section.editable-calendar");
|
|
18
|
+
if (elements.length) {
|
|
19
|
+
const formats = Array.from(elements).map(element => {
|
|
20
|
+
const storedPresets = element.dataset.presets;
|
|
21
|
+
const presets = storedPresets ? JSON.parse(storedPresets) : {};
|
|
22
|
+
return {
|
|
23
|
+
element,
|
|
24
|
+
presets
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
setFormats(formats);
|
|
28
|
+
}
|
|
29
|
+
}, []);
|
|
30
|
+
React.useEffect(() => {
|
|
31
|
+
refreshFormats();
|
|
32
|
+
}, [lang, path, refreshFormats]);
|
|
33
|
+
React.useEffect(() => {
|
|
34
|
+
const zones = Array.from(document.querySelectorAll(".cms"));
|
|
35
|
+
zones.forEach(zone => {
|
|
36
|
+
zone.addEventListener("ublo-section-created", refreshFormats);
|
|
37
|
+
zone.addEventListener("ublo-section-pasted", refreshFormats);
|
|
38
|
+
});
|
|
39
|
+
window.addEventListener("ublo-content-saved", reloadWindow);
|
|
40
|
+
return () => {
|
|
41
|
+
window.addEventListener("ublo-content-saved", reloadWindow);
|
|
42
|
+
zones.forEach(zone => {
|
|
43
|
+
zone.removeEventListener("ublo-section-created", refreshFormats);
|
|
44
|
+
zone.removeEventListener("ublo-section-pasted", refreshFormats);
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
}, [refreshFormats]);
|
|
48
|
+
if (!formats.length) return null;
|
|
49
|
+
return formats.map(format => ReactDOM.createPortal(_jsx(Calendar, {
|
|
50
|
+
lang: lang,
|
|
51
|
+
format: format
|
|
52
|
+
}), format.element));
|
|
53
|
+
}
|
|
54
|
+
function reloadWindow() {
|
|
55
|
+
window.location.reload();
|
|
56
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import * as Data from "./data";
|
|
2
|
+
export function zeroPad(value, length) {
|
|
3
|
+
return `${value}`.padStart(length, "0");
|
|
4
|
+
}
|
|
5
|
+
export function formatDate(date) {
|
|
6
|
+
const d = new Date(date);
|
|
7
|
+
const day = zeroPad(d.getDate(), 2);
|
|
8
|
+
const month = zeroPad(d.getMonth() + 1, 2);
|
|
9
|
+
const year = d.getFullYear();
|
|
10
|
+
return `${year}-${month}-${day}`;
|
|
11
|
+
}
|
|
12
|
+
export function getYearsRange(start, end) {
|
|
13
|
+
return Array(end - start + 1).fill(undefined).map((_, i) => start + i);
|
|
14
|
+
}
|
|
15
|
+
export function getMonthDays(month = Data.THIS_MONTH, year = Data.THIS_YEAR) {
|
|
16
|
+
const months30 = [4, 6, 9, 11];
|
|
17
|
+
const leapYear = year % 4 === 0;
|
|
18
|
+
return month === 2 ? leapYear ? 29 : 28 : months30.includes(month) ? 30 : 31;
|
|
19
|
+
}
|
|
20
|
+
export function getMonthFirstDay(month = Data.THIS_MONTH, year = Data.THIS_YEAR) {
|
|
21
|
+
return new Date(`${year}-${zeroPad(month, 2)}-01`).getDay();
|
|
22
|
+
}
|
|
23
|
+
export function isDate(date) {
|
|
24
|
+
const isDate = Object.prototype.toString.call(date) === "[object Date]";
|
|
25
|
+
const isValidDate = date && !Number.isNaN(date.valueOf());
|
|
26
|
+
return isDate && isValidDate;
|
|
27
|
+
}
|
|
28
|
+
export function isSameMonth(date, basedate = new Date()) {
|
|
29
|
+
if (!(isDate(date) && isDate(basedate))) return false;
|
|
30
|
+
const basedateMonth = basedate.getMonth() + 1;
|
|
31
|
+
const basedateYear = basedate.getFullYear();
|
|
32
|
+
const dateMonth = date.getMonth() + 1;
|
|
33
|
+
const dateYear = date.getFullYear();
|
|
34
|
+
return basedateMonth === dateMonth && basedateYear === dateYear;
|
|
35
|
+
}
|
|
36
|
+
export function isSameDay(date, basedate = new Date()) {
|
|
37
|
+
if (!(isDate(date) && isDate(basedate))) return false;
|
|
38
|
+
const basedateDate = basedate.getDate();
|
|
39
|
+
const basedateMonth = basedate.getMonth() + 1;
|
|
40
|
+
const basedateYear = basedate.getFullYear();
|
|
41
|
+
const dateDate = date.getDate();
|
|
42
|
+
const dateMonth = date.getMonth() + 1;
|
|
43
|
+
const dateYear = date.getFullYear();
|
|
44
|
+
return basedateDate === dateDate && basedateMonth === dateMonth && basedateYear === dateYear;
|
|
45
|
+
}
|
|
46
|
+
export function getPreviousMonth(month, year) {
|
|
47
|
+
const prevMonth = month > 1 ? month - 1 : 12;
|
|
48
|
+
const prevMonthYear = month > 1 ? year : year - 1;
|
|
49
|
+
return {
|
|
50
|
+
month: prevMonth,
|
|
51
|
+
year: prevMonthYear
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export function getNextMonth(month, year) {
|
|
55
|
+
const nextMonth = month < 12 ? month + 1 : 1;
|
|
56
|
+
const nextMonthYear = month < 12 ? year : year + 1;
|
|
57
|
+
return {
|
|
58
|
+
month: nextMonth,
|
|
59
|
+
year: nextMonthYear
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export function addDays(_date, days) {
|
|
63
|
+
const date = new Date(_date);
|
|
64
|
+
date.setDate(date.getDate() + days);
|
|
65
|
+
return date;
|
|
66
|
+
}
|
|
67
|
+
export function getDateInterval(startDate, endDate, reverse) {
|
|
68
|
+
const dates = [];
|
|
69
|
+
let currentDate = reverse ? endDate : startDate;
|
|
70
|
+
const stopDate = reverse ? startDate : endDate;
|
|
71
|
+
while (currentDate <= stopDate) {
|
|
72
|
+
dates.push(currentDate);
|
|
73
|
+
currentDate = addDays(currentDate, 1);
|
|
74
|
+
}
|
|
75
|
+
return dates;
|
|
76
|
+
}
|
|
@@ -94,11 +94,11 @@ export default function EditForm({
|
|
|
94
94
|
onClick: removeMarker,
|
|
95
95
|
compact: true,
|
|
96
96
|
children: [_jsx(Icons.Bin, {}), "Supprimer ce point"]
|
|
97
|
-
}),
|
|
97
|
+
}), _jsxs(Button, {
|
|
98
98
|
variant: "success",
|
|
99
99
|
onClick: closeMarker,
|
|
100
100
|
compact: true,
|
|
101
|
-
children: _jsx(Icons.Check, {})
|
|
101
|
+
children: ["Valider", _jsx(Icons.Check, {})]
|
|
102
102
|
})]
|
|
103
103
|
})]
|
|
104
104
|
});
|
|
@@ -73,7 +73,7 @@ const renderField = (lang, label, classes, name, field, data, setData) => {
|
|
|
73
73
|
newData[name].validator = isValid;
|
|
74
74
|
}
|
|
75
75
|
};
|
|
76
|
-
const formatedOptions = [{
|
|
76
|
+
const formatedOptions = type === "select" ? [{
|
|
77
77
|
label: Messages.get(lang, "select"),
|
|
78
78
|
value: ""
|
|
79
79
|
}].concat(optionsToDisplay.map(option => {
|
|
@@ -81,7 +81,7 @@ const renderField = (lang, label, classes, name, field, data, setData) => {
|
|
|
81
81
|
label: option.label?.[lang],
|
|
82
82
|
value: option.value ?? option.label?.[lang]
|
|
83
83
|
};
|
|
84
|
-
}));
|
|
84
|
+
})) : undefined;
|
|
85
85
|
return _jsx(Tag, {
|
|
86
86
|
onValueChange: onChange,
|
|
87
87
|
options: formatedOptions,
|