willba-component-library 0.2.55 → 0.2.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/lib/assets/IconsSvg.d.ts +9 -0
  2. package/lib/components/FilterBar/FilterBar.stories.d.ts +1 -1
  3. package/lib/components/FilterCalendar/FilterCalendar.d.ts +1 -1
  4. package/lib/components/FilterCalendar/FilterCalendar.stories.d.ts +2 -1
  5. package/lib/components/FilterCalendar/hooks/useFilterCalendar.d.ts +3 -3
  6. package/lib/core/components/calendar/CalendarTypes.d.ts +8 -6
  7. package/lib/core/components/calendar/hooks/index.d.ts +3 -0
  8. package/lib/core/components/calendar/hooks/useCalendarLoadingSpinner.d.ts +7 -0
  9. package/lib/core/components/calendar/hooks/useCalendarTooltips.d.ts +10 -0
  10. package/lib/core/components/calendar/hooks/useUpdateDisabledDates.d.ts +13 -0
  11. package/lib/core/components/calendar/utils/calendarSelectionRules.d.ts +15 -0
  12. package/lib/core/components/calendar/utils/checkForContinuousSelection.d.ts +10 -0
  13. package/lib/core/components/calendar/utils/disabledDatesByPage.d.ts +9 -0
  14. package/lib/core/components/calendar/utils/handleCalendarModifiers.d.ts +46 -0
  15. package/lib/core/components/calendar/utils/handleRangeContextDisabledDates.d.ts +27 -0
  16. package/lib/core/components/calendar/utils/index.d.ts +8 -0
  17. package/lib/core/components/calendar/utils/nightsCount.d.ts +6 -0
  18. package/lib/core/components/calendar/utils/parseDate.d.ts +7 -0
  19. package/lib/core/components/calendar/utils/parseDates.d.ts +6 -0
  20. package/lib/index.d.ts +10 -7
  21. package/lib/index.esm.js +646 -273
  22. package/lib/index.esm.js.map +1 -1
  23. package/lib/index.js +646 -273
  24. package/lib/index.js.map +1 -1
  25. package/lib/index.umd.js +646 -273
  26. package/lib/index.umd.js.map +1 -1
  27. package/lib/themes/useTheme.d.ts +2 -0
  28. package/package.json +1 -1
  29. package/src/assets/IconsSvg.tsx +66 -0
  30. package/src/components/FilterBar/FilterBar.stories.tsx +2 -1
  31. package/src/components/FilterBar/FilterBar.tsx +1 -1
  32. package/src/components/FilterCalendar/FilterCalendar.css +8 -9
  33. package/src/components/FilterCalendar/FilterCalendar.stories.tsx +345 -158
  34. package/src/components/FilterCalendar/FilterCalendar.tsx +69 -52
  35. package/src/components/FilterCalendar/FilterCalendarTypes.ts +0 -1
  36. package/src/components/FilterCalendar/hooks/useFilterCalendar.ts +44 -4
  37. package/src/core/components/buttons/submit-button/SubmitButton.tsx +1 -4
  38. package/src/core/components/calendar/Calendar.css +24 -6
  39. package/src/core/components/calendar/Calendar.tsx +127 -382
  40. package/src/core/components/calendar/CalendarTypes.ts +9 -4
  41. package/src/core/components/calendar/hooks/index.ts +3 -0
  42. package/src/core/components/calendar/hooks/useCalendarLoadingSpinner.tsx +25 -0
  43. package/src/core/components/calendar/hooks/useCalendarTooltips.tsx +139 -0
  44. package/src/core/components/calendar/hooks/useUpdateDisabledDates.tsx +94 -0
  45. package/src/core/components/calendar/utils/calendarSelectionRules.tsx +163 -0
  46. package/src/core/components/calendar/utils/checkForContinuousSelection.tsx +50 -0
  47. package/src/core/components/calendar/utils/disabledDatesByPage.tsx +36 -0
  48. package/src/core/components/calendar/utils/handleCalendarModifiers.tsx +151 -0
  49. package/src/core/components/calendar/utils/handleRangeContextDisabledDates.tsx +70 -0
  50. package/src/core/components/calendar/utils/index.ts +8 -0
  51. package/src/themes/Default.css +6 -0
  52. package/src/themes/useTheme.tsx +3 -0
  53. package/src/assets/SpinnerSvg.tsx +0 -40
  54. package/src/core/utils/handleOverlappingDates.tsx +0 -3
  55. package/src/core/utils/index.ts +0 -3
  56. /package/src/core/{utils → components/calendar/utils}/nightsCount.tsx +0 -0
  57. /package/src/core/{utils → components/calendar/utils}/parseDate.tsx +0 -0
  58. /package/src/core/{utils → components/calendar/utils}/parseDates.tsx +0 -0
@@ -9,7 +9,8 @@ import {
9
9
  useCloseFilterSection,
10
10
  useUpdateTranslations,
11
11
  } from '../../core/hooks'
12
- import { nightsCount, parseDate } from '../../core/utils'
12
+ import { nightsCount, parseDate } from '../../core/components/calendar/utils'
13
+ import { IconsSvg } from '../../assets/IconsSvg'
13
14
 
14
15
  import { FilterCalendarTypes } from './FilterCalendarTypes'
15
16
  import { useFilterCalendar } from './hooks/useFilterCalendar'
@@ -28,6 +29,7 @@ export default function FilterCalendar({
28
29
  requestDates,
29
30
  showFeedback,
30
31
  noActiveSelection,
32
+ rangeContext,
31
33
  }: FilterCalendarTypes) {
32
34
  const themePalette = useTheme({ palette })
33
35
 
@@ -36,7 +38,6 @@ export default function FilterCalendar({
36
38
  const { t } = useTranslation()
37
39
 
38
40
  const {
39
- handleSubmit,
40
41
  setCalendarRange,
41
42
  handleClearDates,
42
43
  calendarRange,
@@ -45,9 +46,9 @@ export default function FilterCalendar({
45
46
  updateCalendarMonthNavigation,
46
47
  updateCalendarDefaultMoth,
47
48
  setUpdateCalendarMonthNavigation,
48
- initialCalendarRange,
49
- overlappingDates,
50
- setOverlappingDates,
49
+ calendarHasError,
50
+ setCalendarHasError,
51
+ setUpdatedForSubmit,
51
52
  } = useFilterCalendar({
52
53
  onSubmit,
53
54
  setToggleCalendar,
@@ -64,7 +65,7 @@ export default function FilterCalendar({
64
65
  })
65
66
 
66
67
  const nights = nightsCount({
67
- calendarRange: calendarRange || initialCalendarRange,
68
+ calendarRange: calendarRange,
68
69
  })
69
70
 
70
71
  return (
@@ -72,13 +73,9 @@ export default function FilterCalendar({
72
73
  {toggleCalendar && (
73
74
  <div className={`will-calendar-wrapper`} ref={filtersRef}>
74
75
  <div className={`will-calendar-header`}>
75
- <div className={`will-calendar-header-row`}>
76
- <h2>{t('filterBar:calendar.title')}</h2>
77
- <CloseButton handleClose={() => setToggleCalendar(false)} />
78
- </div>
79
- {overlappingDates && <div>Chose other dates</div>}
76
+ <h2>{t('filterBar:calendar.title')}</h2>
77
+ <CloseButton handleClose={() => setToggleCalendar(false)} />
80
78
  </div>
81
-
82
79
  <div className={`will-calendar-main`}>
83
80
  <Calendar
84
81
  calendarRange={calendarRange}
@@ -96,55 +93,75 @@ export default function FilterCalendar({
96
93
  }
97
94
  updateCalendarDefaultMoth={updateCalendarDefaultMoth}
98
95
  loadingData={loadingData}
99
- initialCalendarRange={initialCalendarRange}
100
96
  showFeedback={showFeedback}
101
97
  noActiveSelection={noActiveSelection}
102
98
  palette={palette}
103
- setOverlappingDates={setOverlappingDates}
99
+ setCalendarHasError={setCalendarHasError}
100
+ setUpdatedForSubmit={setUpdatedForSubmit}
101
+ rangeContext={rangeContext}
102
+ calendarHasError={calendarHasError}
104
103
  />
105
104
  </div>
106
- <div className={`will-calendar-footer`}>
107
- <div className={`will-calendar-footer-dates`}>
108
- <div>
109
- <span>
110
- {parseDate({
111
- date: calendarRange?.from || initialCalendarRange?.from,
112
- dateFormat: 'EEEEEE d.M.yyyy',
113
- language,
114
- }) || t('common:checkIn')}
115
- </span>
116
- <span className={`will-calendar-footer-dates-separator`}>
117
- -
118
- </span>
119
- <span>
120
- {parseDate({
121
- date: calendarRange?.to || initialCalendarRange?.to,
122
- dateFormat: 'EEEEEE d.M.yyyy',
123
- language,
124
- }) || t('common:checkOut')}
105
+ <div className="will-calendar-footer">
106
+ <div className="will-calendar-footer-actions-wrapper">
107
+ <div className="will-calendar-footer-dates">
108
+ {calendarHasError ? (
109
+ <span>
110
+ Start or end day need connection for previous reservation
111
+ </span>
112
+ ) : (
113
+ <div>
114
+ <span>
115
+ {parseDate({
116
+ date: calendarRange?.from,
117
+ dateFormat: 'EEEEEE d.M.yyyy',
118
+ language,
119
+ }) || t('common:checkIn')}
120
+ </span>
121
+ <span className="will-calendar-footer-dates-separator">
122
+ -
123
+ </span>
124
+ <span>
125
+ {parseDate({
126
+ date: calendarRange?.to,
127
+ dateFormat: 'EEEEEE d.M.yyyy',
128
+ language,
129
+ }) || t('common:checkOut')}
130
+ </span>
131
+ </div>
132
+ )}
133
+
134
+ <span className="will-calendar-footer-booked">
135
+ {calendarHasError
136
+ ? '2 nights min'
137
+ : nights
138
+ ? `${nights} ${t(
139
+ `common:${nights === 1 ? 'night' : 'nights'}`
140
+ )}`
141
+ : ''}
125
142
  </span>
126
143
  </div>
127
144
 
128
- <span className={`will-calendar-footer-booked`}>
129
- {nights
130
- ? `${nights} ${t(
131
- `common:${nights === 1 ? 'night' : 'nights'}`
132
- )}`
133
- : ''}
134
- </span>
135
- </div>
136
- <div className={`will-calendar-footer-actions`}>
137
- <SubmitButton
138
- onClick={handleClearDates}
139
- disabled={!calendarRange?.from}
140
- label={t(`common:clearDates`)}
141
- />
142
- <SubmitButton
143
- onClick={() => handleSubmit()}
144
- label={t(`common:apply`)}
145
- disabled={!calendarRange?.from || !calendarRange?.to}
146
- />
145
+ <div className="will-calendar-footer-actions">
146
+ <SubmitButton
147
+ onClick={handleClearDates}
148
+ disabled={!calendarRange?.from}
149
+ label={t(`common:clearDates`)}
150
+ />
151
+ </div>
147
152
  </div>
153
+ {calendarHasError && (
154
+ <div style={{ display: 'flex', alignItems: 'center' }}>
155
+ <IconsSvg
156
+ fill={palette?.error || 'inherit'}
157
+ size={25}
158
+ icon="warning"
159
+ />
160
+ <span style={{ marginLeft: '10px' }}>
161
+ Check-in available for second room only with connection dates
162
+ </span>
163
+ </div>
164
+ )}
148
165
  </div>
149
166
  </div>
150
167
  )}
@@ -1,4 +1,3 @@
1
- import { CSSProperties } from 'react'
2
1
  import { DateRange } from 'react-day-picker'
3
2
 
4
3
  import { Palette } from '../../themes/useTheme'
@@ -1,5 +1,6 @@
1
1
  import { useEffect, useState } from 'react'
2
2
  import { DateRange, Matcher } from 'react-day-picker'
3
+ import { format } from 'date-fns'
3
4
 
4
5
  type Props = {
5
6
  onSubmit: (val: any) => void
@@ -14,6 +15,7 @@ export const useFilterCalendar = ({
14
15
  noActiveSelection,
15
16
  toggleCalendar,
16
17
  }: Props) => {
18
+ // State
17
19
  const [calendarRange, setCalendarRange] = useState<DateRange | undefined>()
18
20
  const [initialCalendarRange, setInitialCalendarRange] = useState<
19
21
  DateRange | undefined
@@ -24,8 +26,11 @@ export const useFilterCalendar = ({
24
26
  const [updateCalendarDefaultMoth, setUpdateCalendarDefaultMoth] =
25
27
  useState<number>(0)
26
28
 
27
- const [overlappingDates, setOverlappingDates] = useState<boolean>(false)
29
+ const [calendarHasError, setCalendarHasError] = useState<boolean>(false)
28
30
 
31
+ const [updatedForSubmit, setUpdatedForSubmit] = useState<boolean>(false)
32
+
33
+ // Lifecycle
29
34
  useEffect(() => {
30
35
  if (typeof window === 'undefined') return
31
36
 
@@ -38,10 +43,15 @@ export const useFilterCalendar = ({
38
43
  if (noActiveSelection) {
39
44
  handleClearDates()
40
45
  setUpdateCalendarDefaultMoth((prev) => prev + 1)
46
+ setUpdatedForSubmit(false)
41
47
  setInitialCalendarRange({
42
48
  from: new Date(startDateParam),
43
49
  to: new Date(endDateParam),
44
50
  })
51
+ setCalendarRange({
52
+ from: new Date(startDateParam),
53
+ to: new Date(endDateParam),
54
+ })
45
55
  } else {
46
56
  setCalendarRange({
47
57
  from: new Date(startDateParam),
@@ -51,6 +61,34 @@ export const useFilterCalendar = ({
51
61
  }
52
62
  }, [toggleCalendar])
53
63
 
64
+ useEffect(() => {
65
+ const formatString = 'dd.MM.yyyy'
66
+ const initialRangeTo = initialCalendarRange?.to
67
+ ? format(initialCalendarRange.to, formatString)
68
+ : null
69
+ const initialRangeFrom = initialCalendarRange?.from
70
+ ? format(initialCalendarRange.from, formatString)
71
+ : null
72
+ const calendarRangeTo = calendarRange?.to
73
+ ? format(calendarRange.to, formatString)
74
+ : null
75
+ const calendarRangeFrom = calendarRange?.from
76
+ ? format(calendarRange.from, formatString)
77
+ : null
78
+
79
+ if (!!(calendarRangeTo && calendarRangeFrom && updatedForSubmit)) {
80
+ if (
81
+ !!(calendarRangeTo !== initialRangeTo) ||
82
+ !!(calendarRangeFrom !== initialRangeFrom)
83
+ ) {
84
+ handleSubmit()
85
+ } else {
86
+ setToggleCalendar(false)
87
+ }
88
+ }
89
+ }, [calendarRange])
90
+
91
+ // Methods
54
92
  const handleSubmit = () => {
55
93
  setToggleCalendar(false)
56
94
  return onSubmit(calendarRange)
@@ -59,6 +97,8 @@ export const useFilterCalendar = ({
59
97
  const handleClearDates = () => {
60
98
  setDisabledDates([])
61
99
  setCalendarRange(undefined)
100
+ setCalendarHasError(false)
101
+ setInitialCalendarRange(undefined)
62
102
  }
63
103
 
64
104
  return {
@@ -71,8 +111,8 @@ export const useFilterCalendar = ({
71
111
  disabledDates,
72
112
  updateCalendarMonthNavigation,
73
113
  updateCalendarDefaultMoth,
74
- initialCalendarRange,
75
- overlappingDates,
76
- setOverlappingDates,
114
+ calendarHasError,
115
+ setCalendarHasError,
116
+ setUpdatedForSubmit,
77
117
  }
78
118
  }
@@ -1,10 +1,7 @@
1
+ import { FaSpinner } from 'react-icons/fa'
1
2
  import React, { ReactNode } from 'react'
2
3
 
3
- import { SpinnerSVG } from '../../../../assets/SpinnerSvg'
4
- import { Palette } from '../../../../themes/useTheme'
5
-
6
4
  import './SubmitButton.css'
7
- import { FaSpinner } from 'react-icons/fa'
8
5
 
9
6
  type Props = {
10
7
  onClick?: () => void
@@ -88,7 +88,9 @@
88
88
  /* Tooltip */
89
89
  .will-root .will-calendar-filter-container .will-calendar-tooltip,
90
90
  .will-root .will-calendar-filter-container .will-calendar-tooltip-check-out,
91
- .will-root .will-calendar-filter-container .will-calendar-tooltip-overlapping-date {
91
+ .will-root .will-calendar-filter-container .will-calendar-tooltip-overlapping-date,
92
+ .will-root .will-calendar-filter-container .will-calendar-tooltip-check-out-only,
93
+ .will-root .will-calendar-filter-container .will-calendar-tooltip-check-in-only {
92
94
  position: absolute;
93
95
  top: -42px;
94
96
  transform: translateX(calc(-50% + 20px));
@@ -96,9 +98,12 @@
96
98
  white-space: nowrap;
97
99
  z-index: 2;
98
100
  }
101
+
99
102
  .will-root .will-calendar-filter-container .will-calendar-tooltip > div,
100
103
  .will-root .will-calendar-filter-container .will-calendar-tooltip-check-out > div,
101
- .will-root .will-calendar-filter-container .will-calendar-tooltip-overlapping-date > div {
104
+ .will-root .will-calendar-filter-container .will-calendar-tooltip-overlapping-date > div,
105
+ .will-root .will-calendar-filter-container .will-calendar-tooltip-check-out-only > div,
106
+ .will-root .will-calendar-filter-container .will-calendar-tooltip-check-in-only > div {
102
107
  background-color: white;
103
108
  position: relative;
104
109
  padding: 5px 10px;
@@ -108,7 +113,9 @@
108
113
 
109
114
  .will-root .will-calendar-filter-container .will-calendar-tooltip::before,
110
115
  .will-root .will-calendar-filter-container .will-calendar-tooltip-check-out::before,
111
- .will-root .will-calendar-filter-container .will-calendar-tooltip-overlapping-date::before {
116
+ .will-root .will-calendar-filter-container .will-calendar-tooltip-overlapping-date::before,
117
+ .will-root .will-calendar-filter-container .will-calendar-tooltip-check-out-only::before,
118
+ .will-root .will-calendar-filter-container .will-calendar-tooltip-check-in-only::before {
112
119
  content: "";
113
120
  width: 10px;
114
121
  height: 10px;
@@ -123,7 +130,9 @@
123
130
 
124
131
  .will-root .will-calendar-filter-container .rdp-cell:hover .will-calendar-tooltip,
125
132
  .will-root .will-calendar-filter-container .rdp-cell:hover .will-calendar-tooltip-check-out,
126
- .will-root .will-calendar-filter-container .rdp-cell:hover .will-calendar-tooltip-overlapping-date {
133
+ .will-root .will-calendar-filter-container .rdp-cell:hover .will-calendar-tooltip-overlapping-date,
134
+ .will-root .will-calendar-filter-container .rdp-cell:hover .will-calendar-tooltip-check-out-only,
135
+ .will-root .will-calendar-filter-container .rdp-cell:hover .will-calendar-tooltip-check-in-only {
127
136
  display: block;
128
137
  }
129
138
 
@@ -151,8 +160,11 @@
151
160
 
152
161
  .will-root .will-calendar-filter-container .rdp-day_selected.rdp-day_range_start.no-active-selection,
153
162
  .will-root .will-calendar-filter-container .rdp-day_selected.rdp-day_range_middle.no-active-selection,
154
- .will-root .will-calendar-filter-container .rdp-day_selected.rdp-day_range_end.no-active-selection {
155
- background-color: var(--will-onahau);
163
+ .will-root .will-calendar-filter-container .rdp-day_selected.rdp-day_range_end.no-active-selection,
164
+ .will-root .will-calendar-filter-container .rdp-day_selected.rdp-day_range_start.no-active-selection.checkout-option,
165
+ .will-root .will-calendar-filter-container .rdp-day_selected.rdp-day_range_middle.no-active-selection.checkout-option,
166
+ .will-root .will-calendar-filter-container .rdp-day_selected.rdp-day_range_end.no-active-selection.checkout-option {
167
+ background-color: var(--rdp-background-color);
156
168
  color: inherit;
157
169
  }
158
170
 
@@ -162,6 +174,12 @@
162
174
  background-color: var(--rdp-background-color);
163
175
  }
164
176
 
177
+ .will-root .will-calendar-filter-container .rdp-day_selected.rdp-day_range_middle.checkout-option {
178
+ background-color: var(--will-primary-lightest);
179
+ color: inherit;
180
+ }
181
+
182
+
165
183
  /* Overlapping date */
166
184
 
167
185
  .will-root .will-calendar-filter-container .overlapping-date {