4e57f6b342
* draft for tablet view * adapt sidebar to tablet view * split menubar to handle tablet and desktop separatly * split sidebar to handle tablet and desktop separatly * prettier day navigationin tablet view * added missing translations * coderabbit comments * fix UI of view switcher on tablet, remove hard text * fix style of selected view option * fix wrong I18n key * extracted menubar recurring components to own files * adjust test case of calendar component * refactor function change calendar view Co-authored-by: Camille Moussu <cmoussu@linagora.com> Co-authored-by: lethemanh <lethemanh@lethemanhs-MacBook-Pro.local>
128 lines
4.3 KiB
TypeScript
128 lines
4.3 KiB
TypeScript
import { useAppDispatch } from '@/app/hooks'
|
|
import { setView } from '@/features/Settings/SettingsSlice'
|
|
import { computeStartOfTheWeek } from '@/utils/dateUtils'
|
|
import type { CalendarApi } from '@fullcalendar/core'
|
|
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'
|
|
import { DateCalendar } from '@mui/x-date-pickers'
|
|
import { AdapterMoment } from '@mui/x-date-pickers/AdapterMoment'
|
|
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider'
|
|
import moment from 'moment'
|
|
import { useEffect, useState } from 'react'
|
|
import { useI18n } from 'twake-i18n'
|
|
import { CALENDAR_VIEWS } from './utils/constants'
|
|
|
|
export function MiniCalendar({
|
|
calendarRef,
|
|
selectedDate,
|
|
setSelectedMiniDate
|
|
}: {
|
|
calendarRef: React.MutableRefObject<CalendarApi | null>
|
|
selectedDate: Date
|
|
setSelectedMiniDate: (d: Date) => void
|
|
}) {
|
|
const dispatch = useAppDispatch()
|
|
const [visibleDate, setVisibleDate] = useState(selectedDate)
|
|
const { t } = useI18n()
|
|
|
|
useEffect(() => {
|
|
const handleVisibleDateChange = () => {
|
|
setVisibleDate(selectedDate)
|
|
}
|
|
handleVisibleDateChange()
|
|
}, [selectedDate])
|
|
return (
|
|
<LocalizationProvider
|
|
dateAdapter={AdapterMoment}
|
|
adapterLocale={t('locale') ?? 'en-gb'}
|
|
>
|
|
<DateCalendar
|
|
value={moment(visibleDate)}
|
|
onChange={async (dateMoment, selectionState) => {
|
|
if (!dateMoment) return
|
|
const date = dateMoment.toDate()
|
|
if (selectionState === 'finish') {
|
|
await dispatch(setView('calendar'))
|
|
setSelectedMiniDate(date)
|
|
calendarRef.current?.gotoDate(date)
|
|
}
|
|
}}
|
|
showDaysOutsideCurrentMonth
|
|
onMonthChange={month => {
|
|
setVisibleDate(month.toDate())
|
|
}}
|
|
views={['month', 'day']}
|
|
slots={{
|
|
switchViewIcon: KeyboardArrowDownIcon
|
|
}}
|
|
sx={{
|
|
width: '100%',
|
|
height: '300px',
|
|
'& .MuiPickersCalendarHeader-root': {
|
|
marginTop: 3
|
|
}
|
|
}}
|
|
slotProps={{
|
|
day: ownerState => {
|
|
const date = ownerState.day.toDate()
|
|
const today = new Date()
|
|
today.setHours(0, 0, 0, 0)
|
|
const selected = new Date(selectedDate)
|
|
selected.setHours(0, 0, 0, 0)
|
|
|
|
const isToday = date.getTime() === today.getTime()
|
|
const isSelectedDay =
|
|
calendarRef.current?.view.type === CALENDAR_VIEWS.timeGridDay &&
|
|
date.getTime() === selected.getTime()
|
|
|
|
const isInSelectedWeek =
|
|
calendarRef.current?.view.type === CALENDAR_VIEWS.timeGridWeek ||
|
|
calendarRef.current?.view.type === undefined
|
|
? (() => {
|
|
const startOfWeek = computeStartOfTheWeek(selected)
|
|
const endOfWeek = new Date(startOfWeek)
|
|
endOfWeek.setDate(startOfWeek.getDate() + 6)
|
|
endOfWeek.setHours(23, 59, 59, 999)
|
|
return date >= startOfWeek && date <= endOfWeek
|
|
})()
|
|
: false
|
|
|
|
const classNames = [
|
|
isToday ? 'today' : '',
|
|
isSelectedDay ? 'selectedDay' : '',
|
|
isInSelectedWeek ? 'selectedWeek' : ''
|
|
].join(' ')
|
|
|
|
return {
|
|
className: classNames,
|
|
selected: classNames.includes('selectedWeek'),
|
|
outsideCurrentMonth: ownerState.isDayOutsideMonth,
|
|
disableMargin: false,
|
|
style: {
|
|
backgroundColor: 'transparent',
|
|
position: 'relative',
|
|
flexDirection: 'column',
|
|
border: 0
|
|
},
|
|
sx: {
|
|
'&.Mui-selected': {
|
|
color: 'inherit !important',
|
|
fontWeight: 'inherit !important'
|
|
},
|
|
'&.selectedDay': {
|
|
backgroundColor: 'lightgray !important'
|
|
},
|
|
'&.today': {
|
|
background: 'orange !important',
|
|
color: 'white !important'
|
|
}
|
|
},
|
|
'data-testid': `date-${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`,
|
|
children: <>{ownerState.day.date()}</>
|
|
}
|
|
}
|
|
}}
|
|
/>
|
|
</LocalizationProvider>
|
|
)
|
|
}
|