refactor(SW-649): DateSelect component state refactoring

This commit is contained in:
Chuma McPhoy
2024-10-29 09:02:34 +01:00
parent 249a5f6cb8
commit 33fd052c04

View File

@@ -28,6 +28,22 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
rules: registerOptions,
})
const dayLabel = intl.formatMessage({ id: "Day" })
const monthLabel = intl.formatMessage({ id: "Month" })
const yearLabel = intl.formatMessage({ id: "Year" })
const initialDate = dt(currentValue)
const [selectedYear, setSelectedYear] = useState<number | null>(
initialDate.isValid() ? initialDate.year() : null
)
const [selectedMonth, setSelectedMonth] = useState<number | null>(
initialDate.isValid() ? initialDate.month() : null
)
const [selectedDay, setSelectedDay] = useState<number | null>(
initialDate.isValid() ? initialDate.date() : null
)
const currentYear = new Date().getFullYear()
const months = rangeArray(1, 12).map((month) => ({
@@ -39,32 +55,60 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
.reverse()
.map((year) => ({ value: year, label: year.toString() }))
// Ensure the user can't select a date that doesn't exist.
const daysInMonth = dt(currentValue).daysInMonth()
// Get max days based on selected month/year
const daysInMonth =
selectedMonth !== null && selectedYear !== null
? dt(`${selectedYear}-${selectedMonth + 1}-01`).daysInMonth()
: 31
const days = rangeArray(1, daysInMonth).map((day) => ({
value: day,
label: `${day}`,
}))
function createOnSelect(selector: DateName) {
/**
* Months are 0 index based and therefore we
* must subtract by 1 to get the selected month
*/
return (select: Key) => {
if (selector === DateName.month) {
select = Number(select) - 1
function handleSegmentChange(selector: DateName, value: number) {
let newYear = selectedYear
let newMonth = selectedMonth
let newDay = selectedDay
switch (selector) {
case DateName.year:
newYear = value
setSelectedYear(newYear)
break
/**
* Months are 0 index based and therefore we
* must subtract by 1 to get the selected month
*/
case DateName.month:
const monthZeroBased = value - 1
newMonth = monthZeroBased
setSelectedMonth(newMonth)
if (selectedDay) {
const maxDays = dt(`${newYear}-${value}-01`).daysInMonth()
if (selectedDay > maxDays) {
newDay = maxDays
setSelectedDay(newDay)
}
}
break
case DateName.date:
newDay = value
setSelectedDay(newDay)
break
}
// Check if all segments are set and update form value.
if (newYear && newMonth !== null && newDay) {
const newDate = dt().year(newYear).month(newMonth).date(newDay)
if (newDate.isValid()) {
setValue(name, newDate.format("YYYY-MM-DD"))
trigger(name)
}
const newDate = dt(currentValue).set(selector, Number(select))
setValue(name, newDate.format("YYYY-MM-DD"))
trigger(name)
}
}
const dayLabel = intl.formatMessage({ id: "Day" })
const monthLabel = intl.formatMessage({ id: "Month" })
const yearLabel = intl.formatMessage({ id: "Year" })
let dateValue = null
try {
/**
@@ -98,7 +142,9 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
items={days}
label={dayLabel}
name={DateName.date}
onSelect={createOnSelect(DateName.date)}
onSelect={(select: Key) =>
handleSegmentChange(DateName.date, Number(select))
}
placeholder="DD"
required
tabIndex={3}
@@ -117,7 +163,9 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
items={months}
label={monthLabel}
name={DateName.month}
onSelect={createOnSelect(DateName.month)}
onSelect={(select: Key) =>
handleSegmentChange(DateName.month, Number(select))
}
placeholder="MM"
required
tabIndex={2}
@@ -136,7 +184,9 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
items={years}
label={yearLabel}
name={DateName.year}
onSelect={createOnSelect(DateName.year)}
onSelect={(select: Key) =>
handleSegmentChange(DateName.year, Number(select))
}
placeholder="YYYY"
required
tabIndex={1}