Files
supabase/apps/studio/components/ui/DatePicker/TimeSplitInput.tsx
T
Ivan VasilovandJoshen Lim 05a542ccea chore: Migrate all feather icons to lucide icons (#29038)
* Add lucide-react to docs (to make the autocomplete work).

* Migrate the docs app icons.

* Migrate the ui-patterns.

* Remove the old icons from ui package.

* Migrate the www app from react-feather icons.

* Migrate all of studio icons.

* Migrate the only component in design-system.

* Fix an old import in ui package. Revert an import in docs app.

* Fix some pages in www.

* Remove unneeded files used in generation of icons.

* Fix a prettier error.

* Fix more issues in www.

* Fix an issue in Log Date picker.

* Replace all string sizes with number sizes because the icons grew in some cases.

* Fix more imports in security page.

* Fix an extra import.

* Remove the size prop from all icons if they're in a button and they match the button size.

* Minor fixes for docs and www.

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2024-09-04 19:46:21 +08:00

241 lines
5.9 KiB
TypeScript

import { format } from 'date-fns'
import { Clock } from 'lucide-react'
import React, { useEffect, useState } from 'react'
import type { TimeSplitInputProps, TimeType } from './DatePicker.types'
const TimeSplitInput = ({
type,
time,
setTime,
setStartTime,
setEndTime,
startTime,
endTime,
startDate,
endDate,
}: TimeSplitInputProps) => {
const [focus, setFocus] = useState(false)
function handleOnBlur() {
const _time = time
if (_time.HH.length === 1) _time.HH = '0' + _time.HH
if (_time.mm.length === 1) _time.mm = '0' + _time.mm
if (_time.ss.length === 1) _time.ss = '0' + _time.ss
if (!_time.HH) _time.HH = '00'
if (!_time.mm) _time.mm = '00'
if (!_time.ss) _time.ss = '00'
let endTimeChanges = false
let endTimePayload = endTime
let startTimeChanges = false
let startTimePayload = startTime
// Only run time conflicts if
// startDate and endDate are the same date
if (format(new Date(startDate), 'dd/mm/yyyy') == format(new Date(endDate), 'dd/mm/yyyy')) {
// checks if start time is ahead of end time
if (type === 'start') {
if (_time.HH && Number(_time.HH) > Number(endTime.HH)) {
endTimePayload.HH = _time.HH
endTimeChanges = true
}
if (
// also check the hour
_time.HH &&
Number(_time.HH) >= Number(endTime.HH) &&
// check the minutes
_time.mm &&
Number(_time.mm) > Number(endTime.mm)
) {
endTimePayload.mm = _time.mm
endTimeChanges = true
}
if (
// also check the hour
_time.HH &&
Number(_time.HH) >= Number(endTime.HH) &&
// check the minutes
_time.mm &&
Number(_time.mm) >= Number(endTime.mm) &&
// check the seconds
_time.ss &&
Number(_time.ss) > Number(endTime.ss)
) {
endTimePayload.ss = _time.ss
endTimeChanges = true
}
}
if (type === 'end') {
if (_time.HH && Number(_time.HH) < Number(startTime.HH)) {
startTimePayload.HH = _time.HH
startTimeChanges = true
}
if (
// also check the hour
_time.HH &&
Number(_time.HH) <= Number(startTime.HH) &&
// check the minutes
_time.mm &&
Number(_time.mm) < Number(startTime.mm)
) {
startTimePayload.mm = _time.mm
startTimeChanges = true
}
if (
// also check the hour
_time.HH &&
Number(_time.HH) <= Number(startTime.HH) &&
// check the minutes
_time.mm &&
Number(_time.mm) <= Number(startTime.mm) &&
// check the seconds
_time.ss &&
Number(_time.ss) < Number(startTime.ss)
) {
startTimePayload.ss = _time.ss
startTimeChanges = true
}
}
}
setTime({ ..._time })
if (endTimeChanges) {
setEndTime({ ...endTimePayload })
}
if (startTimeChanges) {
setStartTime({ ...startTimePayload })
}
setFocus(false)
}
function handleOnChange(value: string, valueType: TimeType) {
const payload = {
HH: time.HH,
mm: time.mm,
ss: time.ss,
}
if (value.length > 2) return
switch (valueType) {
case 'HH':
if (value && Number(value) > 23) return
break
case 'mm':
if (value && Number(value) > 59) return
break
case 'ss':
if (value && Number(value) > 59) return
break
default:
break
}
payload[valueType] = value
setTime({ ...payload })
}
const handleFocus = (event: React.FocusEvent<HTMLInputElement>) => {
event.target.select()
setFocus(true)
}
useEffect(() => {
handleOnBlur()
}, [startDate, endDate])
return (
<div
className={`
flex h-7 items-center justify-center
gap-0 rounded border border-strong bg-surface-100 text-xs text-foreground-light
${focus && ' border-stronger outline outline-2 outline-border'}
`}
>
<div className="mr-1 text-foreground-lighter">
<Clock size={14} strokeWidth={1.5} />
</div>
<input
type="text"
onBlur={() => handleOnBlur()}
onFocus={handleFocus}
pattern="[0-23]*"
placeholder="00"
onChange={(e) => handleOnChange(e.target.value, 'HH')}
aria-label="Hours"
className="
ring-none
w-4
border-none
bg-transparent
p-0 text-center text-xs
text-foreground
outline-none
ring-0
focus:ring-0
"
value={time.HH}
/>
<span className="text-foreground-lighter">:</span>
<input
type="text"
onBlur={() => handleOnBlur()}
onFocus={handleFocus}
pattern="[0-12]*"
placeholder="00"
onChange={(e) => handleOnChange(e.target.value, 'mm')}
aria-label="Minutes"
className="
ring-none
w-4
border-none
bg-transparent
p-0 text-center text-xs
text-foreground
outline-none
ring-0
focus:ring-0
"
value={time.mm}
/>
<span className="text-foreground-lighter">:</span>
<input
type="text"
onBlur={() => handleOnBlur()}
onFocus={handleFocus}
pattern="[0-59]*"
placeholder="00"
onChange={(e) => handleOnChange(e.target.value, 'ss')}
aria-label="Seconds"
className="
ring-none
w-4
border-none
bg-transparent
p-0 text-center text-xs
text-foreground
outline-none
ring-0
focus:ring-0
"
value={time.ss}
/>
</div>
)
}
export default TimeSplitInput