willba-component-library 0.2.63 → 0.2.64

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "willba-component-library",
3
- "version": "0.2.63",
3
+ "version": "0.2.64",
4
4
  "description": "A custom UI component library",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/index.esm.js",
@@ -48,6 +48,7 @@
48
48
  .will-root .will-calendar-wrapper .will-calendar-footer-dates .will-calendar-footer-booked {
49
49
  display: flex;
50
50
  min-height: 20.5px;
51
+ margin-top: 10px;
51
52
  }
52
53
 
53
54
  .will-root .will-calendar-wrapper .will-calendar-footer-actions {
@@ -56,6 +57,11 @@
56
57
  gap: 10px;
57
58
  }
58
59
 
60
+ .will-root .will-calendar-wrapper .will-calendar-footer-error {
61
+ display: flex;
62
+ align-items: center;
63
+ }
64
+
59
65
  @media (max-width: 960px) {
60
66
  .will-root .will-calendar-wrapper {
61
67
  width: -webkit-fill-available;
@@ -67,7 +73,7 @@
67
73
  padding: 20px 10px;
68
74
  }
69
75
 
70
- .will-root .will-calendar-wrapper .will-calendar-footer {
76
+ .will-root .will-calendar-wrapper .will-calendar-footer-actions-wrapper {
71
77
  flex-direction: column;
72
78
  }
73
79
 
@@ -88,6 +94,11 @@
88
94
  .will-root .will-calendar-wrapper .will-calendar-footer-actions button{
89
95
  width: 100%;
90
96
  }
97
+
98
+ .will-root .will-calendar-wrapper .will-calendar-footer-error {
99
+ min-width: 20px;
100
+ margin-bottom: 10px;
101
+ }
91
102
  }
92
103
 
93
104
  .will-root .will-calendar-wrapper .will-calendar-header .will-filter-bar-close-button {
@@ -1,7 +1,8 @@
1
1
  import React from 'react'
2
2
  import { useTranslation } from 'react-i18next'
3
+ import { useMediaQuery } from 'react-responsive'
3
4
 
4
- import useTheme from '../../themes/useTheme'
5
+ import useTheme, { Palette } from '../../themes/useTheme'
5
6
  import '../../themes/Default.css'
6
7
  import { Calendar, SubmitButton, CloseButton } from '../../core/components'
7
8
  import {
@@ -22,7 +23,7 @@ export default function FilterCalendar({
22
23
  language,
23
24
  palette,
24
25
  onSubmit,
25
- disableCalendarDates,
26
+ disableCalendarDates: outerDisableCalendarDates,
26
27
  toggleCalendar,
27
28
  loadingData,
28
29
  setToggleCalendar,
@@ -36,7 +37,8 @@ export default function FilterCalendar({
36
37
  // Translations
37
38
  useUpdateTranslations({ language })
38
39
  const { t } = useTranslation()
39
-
40
+ const isMobile = useMediaQuery({ maxWidth: 690 })
41
+ console.log('1', { outerDisableCalendarDates })
40
42
  const {
41
43
  setCalendarRange,
42
44
  handleClearDates,
@@ -50,14 +52,18 @@ export default function FilterCalendar({
50
52
  setCalendarHasError,
51
53
  setUpdatedForSubmit,
52
54
  rangeContext,
55
+ disableCalendarDates,
53
56
  } = useFilterCalendar({
54
57
  onSubmit,
55
58
  setToggleCalendar,
56
59
  noActiveSelection,
57
60
  toggleCalendar,
58
61
  outerRangeContext,
62
+ outerDisableCalendarDates,
59
63
  })
60
64
 
65
+ console.log('1', { disableCalendarDates })
66
+
61
67
  // Display component after fully loaded
62
68
  useAwaitRender()
63
69
 
@@ -109,7 +115,7 @@ export default function FilterCalendar({
109
115
  <div className="will-calendar-footer-dates">
110
116
  {calendarHasError ? (
111
117
  <span>
112
- Start or end day need connection for previous reservation
118
+ {t(`common:errors.calendarErrors.checkInAvailabilityGuide`)}
113
119
  </span>
114
120
  ) : (
115
121
  <div>
@@ -135,7 +141,7 @@ export default function FilterCalendar({
135
141
 
136
142
  <span className="will-calendar-footer-booked">
137
143
  {calendarHasError
138
- ? '2 nights min'
144
+ ? t(`filterBar:calendar.minNights`)
139
145
  : nights
140
146
  ? `${nights} ${t(
141
147
  `common:${nights === 1 ? 'night' : 'nights'}`
@@ -144,6 +150,15 @@ export default function FilterCalendar({
144
150
  </span>
145
151
  </div>
146
152
 
153
+ {calendarHasError &&
154
+ isMobile &&
155
+ renderCalendarErrorMessage({
156
+ palette,
157
+ message: t(
158
+ `common:errors.calendarErrors.checkInAvailabilityError`
159
+ ),
160
+ })}
161
+
147
162
  <div className="will-calendar-footer-actions">
148
163
  <SubmitButton
149
164
  onClick={handleClearDates}
@@ -152,21 +167,33 @@ export default function FilterCalendar({
152
167
  />
153
168
  </div>
154
169
  </div>
155
- {calendarHasError && (
156
- <div style={{ display: 'flex', alignItems: 'center' }}>
157
- <IconsSvg
158
- fill={palette?.error || 'inherit'}
159
- size={25}
160
- icon="warning"
161
- />
162
- <span style={{ marginLeft: '10px' }}>
163
- Check-in available for second room only with connection dates
164
- </span>
165
- </div>
166
- )}
170
+
171
+ {calendarHasError &&
172
+ !isMobile &&
173
+ renderCalendarErrorMessage({
174
+ palette,
175
+ message: t(
176
+ `common:errors.calendarErrors.checkInAvailabilityError`
177
+ ),
178
+ })}
167
179
  </div>
168
180
  </div>
169
181
  )}
170
182
  </div>
171
183
  )
172
184
  }
185
+
186
+ /////////
187
+
188
+ const renderCalendarErrorMessage = ({
189
+ message,
190
+ palette,
191
+ }: {
192
+ message?: string
193
+ palette: Palette
194
+ }) => (
195
+ <div className="will-calendar-footer-error">
196
+ <IconsSvg fill={palette?.error || 'inherit'} size={25} icon="warning" />
197
+ <span style={{ marginLeft: '10px' }}>{message || ''}</span>
198
+ </div>
199
+ )
@@ -1,7 +1,10 @@
1
1
  import { useEffect, useState } from 'react'
2
2
  import { DateRange, Matcher } from 'react-day-picker'
3
3
  import { format } from 'date-fns'
4
- import { RangeContext } from 'src/core/components/calendar/CalendarTypes'
4
+ import {
5
+ DisableCalendarDates,
6
+ RangeContext,
7
+ } from 'src/core/components/calendar/CalendarTypes'
5
8
 
6
9
  type Props = {
7
10
  onSubmit: (val: any) => void
@@ -9,6 +12,7 @@ type Props = {
9
12
  noActiveSelection?: boolean
10
13
  toggleCalendar?: boolean
11
14
  outerRangeContext?: RangeContext
15
+ outerDisableCalendarDates?: DisableCalendarDates
12
16
  }
13
17
 
14
18
  export const useFilterCalendar = ({
@@ -17,6 +21,7 @@ export const useFilterCalendar = ({
17
21
  noActiveSelection,
18
22
  toggleCalendar,
19
23
  outerRangeContext,
24
+ outerDisableCalendarDates,
20
25
  }: Props) => {
21
26
  // State
22
27
  const [calendarRange, setCalendarRange] = useState<DateRange | undefined>()
@@ -35,8 +40,19 @@ export const useFilterCalendar = ({
35
40
  const [calendarHasError, setCalendarHasError] = useState<boolean>(false)
36
41
 
37
42
  const [updatedForSubmit, setUpdatedForSubmit] = useState<boolean>(false)
43
+ const [disableCalendarDates, setDisableCalendarDates] =
44
+ useState<DisableCalendarDates>()
38
45
 
39
46
  // Lifecycle
47
+
48
+ // Handle update component with new data
49
+ useEffect(() => {
50
+ if (outerDisableCalendarDates) {
51
+ setDisableCalendarDates(outerDisableCalendarDates)
52
+ }
53
+ }, [outerDisableCalendarDates])
54
+
55
+ // Handle Range Context initial selections
40
56
  useEffect(() => {
41
57
  if (typeof window === 'undefined') return
42
58
 
@@ -68,6 +84,7 @@ export const useFilterCalendar = ({
68
84
  }
69
85
  }, [toggleCalendar])
70
86
 
87
+ // Handle submit dates
71
88
  useEffect(() => {
72
89
  const formatString = 'dd.MM.yyyy'
73
90
  const initialRangeTo = initialCalendarRange?.to
@@ -122,5 +139,6 @@ export const useFilterCalendar = ({
122
139
  setCalendarHasError,
123
140
  setUpdatedForSubmit,
124
141
  rangeContext,
142
+ disableCalendarDates,
125
143
  }
126
144
  }
@@ -55,15 +55,18 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
55
55
  const selectedStartDate = calendarRange?.from
56
56
  const rangeContextStartDate = rangeContext?.from
57
57
 
58
- // Handle overlapping availableDates.lastCheckOut and disabledDates.start
59
- const { newDisableCalendarDates, overlappingDate } = useUpdateDisabledDates(
60
- {
58
+ console.log({ disableCalendarDates })
59
+
60
+ // Handle initial disable dates including overlapping availableDates.lastCheckOut and disabledDates.start
61
+ const { newDisableCalendarDates, overlappingDate, lastPossibleCheckout } =
62
+ useUpdateDisabledDates({
61
63
  disableCalendarDates,
62
64
  calendarRange,
63
65
  updateCalendarMonthNavigation,
64
66
  updateCalendarDefaultMonth,
65
- }
66
- )
67
+ })
68
+
69
+ console.log({ newDisableCalendarDates })
67
70
 
68
71
  // Handle disable dates by page
69
72
  const disabledDatesByPage = handleDisabledDatesByPage({
@@ -100,6 +103,8 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
100
103
  setUpdatedForSubmit && setUpdatedForSubmit(true)
101
104
  }
102
105
 
106
+ console.log({ disabledDates })
107
+
103
108
  // Handle disabled dates for range context
104
109
  const {
105
110
  findFirstPossibleRangeContextCheckIn,
@@ -121,14 +126,6 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
121
126
  calendarHasError,
122
127
  })
123
128
 
124
- // Find last possible checkout for dates
125
- const lastPossibleCheckout = !!newDisableCalendarDates?.availableDates
126
- ?.length
127
- ? newDisableCalendarDates?.availableDates[
128
- newDisableCalendarDates.availableDates.length - 1
129
- ].lastCheckOut
130
- : null
131
-
132
129
  return (
133
130
  <div className="will-filter-bar-calendar" ref={ref}>
134
131
  <div className="will-calendar-filter-container">
@@ -155,14 +152,14 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
155
152
  ? disabledDatesByPage
156
153
  : disabledDates?.length
157
154
  ? [
158
- lastPossibleCheckout ? { after: lastPossibleCheckout } : [],
155
+ lastPossibleCheckout && lastPossibleCheckout,
159
156
  ...disabledDates,
160
157
  ...firstPossibleRangeContextCheckIn,
161
158
  ...lastPossibleRangeContextCheckOut,
162
159
  ]
163
160
  : newDisableCalendarDates?.disabledDates?.length
164
161
  ? [
165
- lastPossibleCheckout ? { after: lastPossibleCheckout } : [],
162
+ lastPossibleCheckout && lastPossibleCheckout,
166
163
  ...newDisableCalendarDates.disabledDates,
167
164
  ...firstPossibleRangeContextCheckIn,
168
165
  ...lastPossibleRangeContextCheckOut,
@@ -206,6 +203,7 @@ export const Calendar = forwardRef<HTMLDivElement, CalendarTypes>(
206
203
  disabledDates,
207
204
  overlappingDate,
208
205
  rangeContext,
206
+ lastPossibleCheckout,
209
207
  findFirstPossibleRangeContextCheckIn,
210
208
  findLastPossibleRangeContextCheckOut,
211
209
  firstPossibleRangeContextCheckIn,
@@ -1,6 +1,6 @@
1
1
  import { useMemo, useState } from 'react'
2
2
  import { addDays, format } from 'date-fns'
3
- import { DateRange } from 'react-day-picker'
3
+ import { DateRange, Matcher } from 'react-day-picker'
4
4
 
5
5
  import { DisableCalendarDates } from '../CalendarTypes'
6
6
 
@@ -21,6 +21,8 @@ export const useUpdateDisabledDates = ({
21
21
  DateRange[] | undefined
22
22
  >(undefined)
23
23
 
24
+ const [lastPossibleCheckout, setLatsPossibleCheckout] = useState<Matcher>([])
25
+
24
26
  const newDisableCalendarDates = useMemo(() => {
25
27
  if (disableCalendarDates?.availableDates) {
26
28
  const dateFormat = 'dd-MM-yyyy'
@@ -71,10 +73,25 @@ export const useUpdateDisabledDates = ({
71
73
  { updatedDisabledDates: [], newOverlappingDates: [] }
72
74
  )
73
75
 
76
+ // Find last possible checkout ( disable all dates after the last possible checkout )
77
+ const lastPossibleCheckout =
78
+ disableCalendarDates.availableDates[
79
+ disableCalendarDates.availableDates.length - 1
80
+ ].lastCheckOut
81
+
82
+ if (lastPossibleCheckout) {
83
+ setLatsPossibleCheckout({ after: lastPossibleCheckout })
84
+ }
85
+
86
+ // Extract overlapping dates ( dates that are only available for checkout )
74
87
  if (newOverlappingDates.length) {
75
88
  setOverlappingDate((prev = []) => [...prev, ...newOverlappingDates])
76
89
  }
77
90
 
91
+ if (newOverlappingDates.length) {
92
+ console.log(newOverlappingDates)
93
+ }
94
+
78
95
  const newDisableCalendarDates = {
79
96
  ...disableCalendarDates,
80
97
  disabledDates: updatedDisabledDates,
@@ -90,5 +107,5 @@ export const useUpdateDisabledDates = ({
90
107
  updateCalendarDefaultMonth,
91
108
  ])
92
109
 
93
- return { newDisableCalendarDates, overlappingDate }
110
+ return { newDisableCalendarDates, overlappingDate, lastPossibleCheckout }
94
111
  }
@@ -21,6 +21,7 @@ type Props = {
21
21
  to: Date
22
22
  }[]
23
23
  disabledDates?: Matcher[]
24
+ lastPossibleCheckout?: Matcher
24
25
  overlappingDate?: DateRange[]
25
26
  rangeContext?: RangeContext
26
27
  findFirstPossibleRangeContextCheckIn?: NonNullable<
@@ -48,6 +49,7 @@ export const handleCalendarModifiers = ({
48
49
  findFirstPossibleRangeContextCheckIn,
49
50
  findLastPossibleRangeContextCheckOut,
50
51
  currentSelectionLastCheckoutDate,
52
+ lastPossibleCheckout,
51
53
  }: Props) => {
52
54
  // Parse data
53
55
  const calendarRangeFrom = calendarRange?.from && endOfDay(calendarRange.from)
@@ -93,19 +95,19 @@ export const handleCalendarModifiers = ({
93
95
  )
94
96
  : []
95
97
 
96
- console.log()
97
-
98
98
  return {
99
99
  booked: disabledDatesByPage.length
100
100
  ? disabledDatesByPage
101
101
  : disabledDates?.length
102
102
  ? [
103
+ lastPossibleCheckout || [],
103
104
  ...disabledDates,
104
105
  ...firstPossibleRangeContextCheckIn,
105
106
  ...lastPossibleRangeContextCheckOut,
106
107
  ]
107
108
  : newDisableCalendarDates?.disabledDates?.length
108
109
  ? [
110
+ lastPossibleCheckout || [],
109
111
  ...newDisableCalendarDates?.disabledDates,
110
112
  ...firstPossibleRangeContextCheckIn,
111
113
  ...lastPossibleRangeContextCheckOut,
@@ -8,5 +8,13 @@
8
8
  "clearDates": "Clear dates",
9
9
  "noCheckIn": "Room not available",
10
10
  "noCheckOut": "Check-out not available",
11
- "checkOutOnly": "Check-out only"
11
+ "checkOutOnly": "Check-out only",
12
+ "onlyCheckOut": "Check-in only",
13
+ "onlyCheckIn": "Check-out only",
14
+ "errors": {
15
+ "calendarErrors": {
16
+ "checkInAvailabilityError": "Check-in available for second room only with connection dates",
17
+ "checkInAvailabilityGuide": "Start or end day need connection for previous reservation"
18
+ }
19
+ }
12
20
  }
@@ -7,7 +7,8 @@
7
7
  "endDate": "End date",
8
8
  "title": "Calendar",
9
9
  "checkoutOnly": "Check-out only",
10
- "hasDisableDates": "Contains unavailable dates"
10
+ "hasDisableDates": "Contains unavailable dates",
11
+ "minNights": "2 nights min"
11
12
  },
12
13
  "guests": {
13
14
  "label": "Number of guests",
@@ -8,6 +8,14 @@
8
8
  "clearDates": "Tyhjennä",
9
9
  "noCheckIn": "Huone ei saatavilla",
10
10
  "noCheckOut": "Uloskirjaus ei saatavilla",
11
- "checkOutOnly": "Vain uloskirjaus"
11
+ "checkOutOnly": "Vain uloskirjaus",
12
+ "onlyCheckOut": "Check-in only",
13
+ "onlyCheckIn": "Check-out only",
14
+ "errors": {
15
+ "calendarErrors": {
16
+ "checkInAvailabilityError": "Check-in available for second room only with connection dates",
17
+ "checkInAvailabilityGuide": "Start or end day need connection for previous reservation"
18
+ }
19
+ }
12
20
  }
13
21
 
@@ -7,7 +7,8 @@
7
7
  "endDate": "Loppu",
8
8
  "title": "Kalenteri",
9
9
  "checkoutOnly": "Check-out only",
10
- "hasDisableDates": "Contains unavailable dates"
10
+ "hasDisableDates": "Contains unavailable dates",
11
+ "minNights": "2 nights min"
11
12
  },
12
13
  "guests": {
13
14
  "label": "Vierasmäärä",