Proyectos de Subversion LeadersLinked - SPA

Rev

Rev 3694 | Rev 3713 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |

import React from 'react';
import { useNavigate } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import {
  Box,
  Drawer as MuiDrawer,
  List,
  ListItem,
  ListItemButton,
  ListItemIcon,
  ListItemText,
  Accordion,
  AccordionSummary,
  AccordionDetails,
  Typography
} from '@mui/material';
import ExpandMore from '@mui/icons-material/ExpandMore';

import { axios } from '@app/utils';
import { addNotification } from '@app/redux/notification/notification.actions';

export const Drawer = ({ show = false, items = [], onClose = () => {} }) => {
  return (
    <MuiDrawer anchor='right' open={show} onClose={onClose}>
      <Box role='presentation' onClick={onClose}>
        <List>
          {items.map((item) => (
            <RenderMenuItem key={item.href} item={item} onClose={onClose} />
          ))}
        </List>
      </Box>
    </MuiDrawer>
  );
};

const RenderMenuItem = ({ item, onClose }) => {
  if (item.childs?.length) {
    return (
      <ListItem sx={{ padding: '0 !important' }}>
        <AccordionItem item={item} onClose={onClose} />
      </ListItem>
    );
  }

  return (
    <ListItem sx={{ padding: '8px 16px !important' }}>
      <MenuDrawerItem item={item} onClose={onClose} />
    </ListItem>
  );
};

const MenuDrawerItem = ({ item: { label, href, ajax, icon: Icon }, onClose }) => {
  const navigate = useNavigate();
  const dispatch = useDispatch();

  const asyncNavigate = async (url) => {
    try {
      const { data } = await axios.get(url);
      if (!data.success) throw new Error('Ha ocurrido un error. Por favor, intente nuevamente.');
      navigate(data.data);
    } catch (error) {
      dispatch(addNotification({ style: 'danger', msg: error.message }));
    }
  };

  const handleClick = (e) => {
    e.stopPropagation();
    onClose();

    if (ajax) {
      e.preventDefault();
      asyncNavigate(href);
    } else {
      navigate(href);
    }
  };

  return (
    <ListItemButton
      onClick={handleClick}
      sx={{ display: 'flex', alignItems: 'center', gap: 1, width: '100%', padding: 0 }}
    >
      {Icon && (
        <ListItemIcon>
          <Icon />
        </ListItemIcon>
      )}
      <ListItemText primary={label} />
    </ListItemButton>
  );
};

const AccordionItem = ({ item: { label, childs, icon: Icon }, onClose }) => {
  const handleAccordionClick = (e) => {
    e.stopPropagation();
  };

  return (
    <Accordion
      disableGutters
      elevation={0}
      sx={{
        width: '100%',
        '&::before': {
          display: 'none'
        }
      }}
    >
      <AccordionSummary
        expandIcon={<ExpandMore />}
        onClick={handleAccordionClick}
        sx={{
          padding: '8px 16px !important',
          '& .MuiAccordionSummary-content': {
            margin: 0
          }
        }}
      >
        <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
          {Icon && <Icon />}
          <Typography margin='0'>{label}</Typography>
        </Box>
      </AccordionSummary>

      <AccordionDetails sx={{ padding: 0 }}>
        <List disablePadding>
          {childs.map((child) => (
            <RenderMenuItem
              key={child.href || child.label}
              item={child}
              onClose={onClose}
              isSubItem
            />
          ))}
        </List>
      </AccordionDetails>
    </Accordion>
  );
};

export default Drawer;