Files
HKSingleParty/03_source/frontend/src/sections/calendar/calendar-toolbar.tsx

148 lines
4.1 KiB
TypeScript

import type { IDateValue } from 'src/types/common';
import type { ICalendarView } from 'src/types/calendar';
import { usePopover } from 'minimal-shared/hooks';
import Box from '@mui/material/Box';
import Badge from '@mui/material/Badge';
import Button from '@mui/material/Button';
import MenuList from '@mui/material/MenuList';
import MenuItem from '@mui/material/MenuItem';
import IconButton from '@mui/material/IconButton';
import Typography from '@mui/material/Typography';
import LinearProgress from '@mui/material/LinearProgress';
import { Iconify } from 'src/components/iconify';
import { CustomPopover } from 'src/components/custom-popover';
// ----------------------------------------------------------------------
const VIEW_OPTIONS = [
{ value: 'dayGridMonth', label: 'Month', icon: 'mingcute:calendar-month-line' },
{ value: 'timeGridWeek', label: 'Week', icon: 'mingcute:calendar-week-line' },
{ value: 'timeGridDay', label: 'Day', icon: 'mingcute:calendar-day-line' },
{ value: 'listWeek', label: 'Agenda', icon: 'custom:calendar-agenda-outline' },
] as const;
// ----------------------------------------------------------------------
type Props = {
loading: boolean;
canReset: boolean;
view: ICalendarView;
date: IDateValue;
onToday: () => void;
onNextDate: () => void;
onPrevDate: () => void;
onOpenFilters: () => void;
onChangeView: (newView: ICalendarView) => void;
};
export function CalendarToolbar({
date,
view,
loading,
onToday,
canReset,
onNextDate,
onPrevDate,
onChangeView,
onOpenFilters,
}: Props) {
const menuActions = usePopover();
const selectedItem = VIEW_OPTIONS.filter((item) => item.value === view)[0];
const renderMenuActions = () => (
<CustomPopover
open={menuActions.open}
anchorEl={menuActions.anchorEl}
onClose={menuActions.onClose}
slotProps={{ arrow: { placement: 'top-left' } }}
>
<MenuList>
{VIEW_OPTIONS.map((viewOption) => (
<MenuItem
key={viewOption.value}
selected={viewOption.value === view}
onClick={() => {
menuActions.onClose();
onChangeView(viewOption.value);
}}
>
<Iconify icon={viewOption.icon} />
{viewOption.label}
</MenuItem>
))}
</MenuList>
</CustomPopover>
);
return (
<>
<Box
sx={{
p: 2.5,
pr: 2,
display: 'flex',
position: 'relative',
alignItems: 'center',
justifyContent: 'space-between',
}}
>
<Button
size="small"
color="inherit"
onClick={menuActions.onOpen}
startIcon={<Iconify icon={selectedItem.icon} />}
endIcon={<Iconify icon="eva:arrow-ios-downward-fill" sx={{ ml: -0.5 }} />}
sx={{ display: { xs: 'none', sm: 'inline-flex' } }}
>
{selectedItem.label}
</Button>
<Box sx={{ gap: 1, display: 'flex', alignItems: 'center' }}>
<IconButton onClick={onPrevDate}>
<Iconify icon="eva:arrow-ios-back-fill" />
</IconButton>
{/* FIXME: no raw json output in html */}
<Typography variant="h6">{JSON.stringify({ date })}</Typography>
<IconButton onClick={onNextDate}>
<Iconify icon="eva:arrow-ios-forward-fill" />
</IconButton>
</Box>
<Box sx={{ gap: 1, display: 'flex', alignItems: 'center' }}>
<Button size="small" color="error" variant="contained" onClick={onToday}>
Today
</Button>
<IconButton onClick={onOpenFilters}>
<Badge color="error" variant="dot" invisible={!canReset}>
<Iconify icon="ic:round-filter-list" />
</Badge>
</IconButton>
</Box>
{loading && (
<LinearProgress
color="inherit"
sx={{
left: 0,
width: 1,
height: 2,
bottom: 0,
borderRadius: 0,
position: 'absolute',
}}
/>
)}
</Box>
{renderMenuActions()}
</>
);
}