init
This commit is contained in:
151
src/components/common/StatusChangePopup/index.tsx
Normal file
151
src/components/common/StatusChangePopup/index.tsx
Normal file
@@ -0,0 +1,151 @@
|
||||
import * as React from 'react';
|
||||
import { styled, alpha } from '@mui/material/styles';
|
||||
import Menu, { MenuProps } from '@mui/material/Menu';
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import { Box, CircularProgress, IconButton, PopoverOrigin, SvgIcon, Typography } from '@mui/material';
|
||||
import { ArrowDropDown, MoreVert } from '@mui/icons-material';
|
||||
import { getBoxStatusStyles } from '@/theme/getStatusBoxStyles';
|
||||
import { BoxStatus, IBox } from '@/data/box/box.model';
|
||||
import { PartyStatus } from '@/data/party/party.model';
|
||||
import BaseButton from '@/components/ui-kit/BaseButton';
|
||||
|
||||
type PlacementType = {
|
||||
anchorOrigin?: PopoverOrigin;
|
||||
transformOrigin?: PopoverOrigin;
|
||||
};
|
||||
|
||||
const StyledMenu = styled((props: MenuProps & { placement: Required<PlacementType> }) => (
|
||||
<Menu elevation={0} anchorOrigin={props.placement.anchorOrigin} transformOrigin={props.placement.transformOrigin} {...props} />
|
||||
))(({ theme }) => ({
|
||||
'& .MuiPaper-root': {
|
||||
borderRadius: 6,
|
||||
marginTop: theme.spacing(1),
|
||||
minWidth: 180,
|
||||
color: theme.palette.mode === 'light' ? 'rgb(55, 65, 81)' : theme.palette.grey[300],
|
||||
boxShadow:
|
||||
'rgb(255, 255, 255) 0px 0px 0px 0px, rgba(0, 0, 0, 0.05) 0px 0px 0px 1px, rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.05) 0px 4px 6px -2px',
|
||||
'& .MuiMenu-list': {
|
||||
padding: '4px 0',
|
||||
},
|
||||
'& .MuiMenuItem-root': {
|
||||
'& .MuiSvgIcon-root': {
|
||||
fontSize: 18,
|
||||
color: theme.palette.text.secondary,
|
||||
marginRight: theme.spacing(1.5),
|
||||
},
|
||||
'&:active': {
|
||||
backgroundColor: alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity),
|
||||
},
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
type StatusChangePopupProps = {
|
||||
mainIcon?: React.ReactNode;
|
||||
buttons: {
|
||||
icon: React.ReactNode;
|
||||
label: string;
|
||||
onClick: () => void;
|
||||
disabled?: boolean;
|
||||
dontCloseOnClick?: boolean;
|
||||
}[];
|
||||
loading?: boolean;
|
||||
placement?: PlacementType;
|
||||
anchor: {
|
||||
text: React.ReactNode;
|
||||
status: BoxStatus | PartyStatus;
|
||||
};
|
||||
};
|
||||
|
||||
export default function StatusChangePopup({ buttons, mainIcon, placement, anchor, loading }: StatusChangePopupProps) {
|
||||
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
|
||||
const open = Boolean(anchorEl);
|
||||
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
|
||||
setAnchorEl(event.currentTarget);
|
||||
};
|
||||
const handleClose = () => {
|
||||
setAnchorEl(null);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<BaseButton
|
||||
id='demo-customized-button'
|
||||
aria-controls={open ? 'demo-customized-menu' : undefined}
|
||||
aria-haspopup='true'
|
||||
aria-expanded={open ? 'true' : undefined}
|
||||
onClick={handleClick}
|
||||
sx={{ ...getBoxStatusStyles(anchor.status), alignItems: 'center', whiteSpace: 'nowrap' }}
|
||||
endIcon={<ArrowDropDown />}
|
||||
loading={loading}
|
||||
fullWidth
|
||||
>
|
||||
{anchor.text}
|
||||
</BaseButton>
|
||||
<StyledMenu
|
||||
id='demo-customized-menu'
|
||||
MenuListProps={{
|
||||
'aria-labelledby': 'demo-customized-button',
|
||||
}}
|
||||
anchorEl={anchorEl}
|
||||
open={open}
|
||||
onClose={handleClose}
|
||||
placement={{
|
||||
anchorOrigin: placement?.anchorOrigin ?? {
|
||||
vertical: 'bottom',
|
||||
horizontal: 'center',
|
||||
},
|
||||
transformOrigin: placement?.transformOrigin ?? {
|
||||
vertical: 'top',
|
||||
horizontal: 'center',
|
||||
},
|
||||
}}
|
||||
sx={{
|
||||
'.MuiMenu-list': {
|
||||
padding: '4px',
|
||||
borderRadius: '8px',
|
||||
},
|
||||
}}
|
||||
>
|
||||
{buttons.map((btn, index) => {
|
||||
return (
|
||||
<MenuItem
|
||||
onClick={event => {
|
||||
btn.onClick();
|
||||
if (!btn.dontCloseOnClick) handleClose();
|
||||
}}
|
||||
disableRipple
|
||||
key={index}
|
||||
sx={{
|
||||
padding: '8px 12px',
|
||||
gap: '8px',
|
||||
}}
|
||||
>
|
||||
<SvgIcon
|
||||
sx={{
|
||||
width: '16px',
|
||||
height: '16px',
|
||||
padding: 0,
|
||||
}}
|
||||
>
|
||||
{btn.icon}
|
||||
</SvgIcon>
|
||||
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: '14px',
|
||||
fontWeight: 500,
|
||||
lineHeight: '16px',
|
||||
letterSpacing: '-0.4px',
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
{btn.label}
|
||||
</Typography>
|
||||
</MenuItem>
|
||||
);
|
||||
})}
|
||||
</StyledMenu>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user