Proyectos de Subversion LeadersLinked - SPA

Rev

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

Rev Autor Línea Nro. Línea
3692 stevensc 1
import React from 'react';
2
import { useNavigate } from 'react-router-dom';
3
import { useDispatch } from 'react-redux';
3201 stevensc 4
import {
5
  Box,
3710 stevensc 6
  Drawer as MuiDrawer,
3201 stevensc 7
  List,
8
  ListItem,
3692 stevensc 9
  ListItemButton,
3201 stevensc 10
  ListItemIcon,
11
  ListItemText,
12
  Accordion,
13
  AccordionSummary,
14
  AccordionDetails,
3692 stevensc 15
  Typography
16
} from '@mui/material';
3694 stevensc 17
import ExpandMore from '@mui/icons-material/ExpandMore';
3201 stevensc 18
 
3692 stevensc 19
import { axios } from '@app/utils';
20
import { addNotification } from '@app/redux/notification/notification.actions';
3201 stevensc 21
 
3710 stevensc 22
export const Drawer = ({ show = false, items = [], onClose = () => {} }) => {
3201 stevensc 23
  return (
3710 stevensc 24
    <MuiDrawer anchor='right' open={show} onClose={onClose}>
3692 stevensc 25
      <Box role='presentation' onClick={onClose}>
3201 stevensc 26
        <List>
3692 stevensc 27
          {items.map((item) => (
28
            <RenderMenuItem key={item.href} item={item} onClose={onClose} />
29
          ))}
3201 stevensc 30
        </List>
31
      </Box>
3710 stevensc 32
    </MuiDrawer>
3692 stevensc 33
  );
3710 stevensc 34
};
3201 stevensc 35
 
3692 stevensc 36
const RenderMenuItem = ({ item, onClose }) => {
37
  if (item.childs?.length) {
38
    return (
39
      <ListItem sx={{ padding: '0 !important' }}>
40
        <AccordionItem item={item} onClose={onClose} />
41
      </ListItem>
42
    );
43
  }
3201 stevensc 44
 
3692 stevensc 45
  return (
46
    <ListItem sx={{ padding: '8px 16px !important' }}>
47
      <MenuDrawerItem item={item} onClose={onClose} />
48
    </ListItem>
49
  );
50
};
3201 stevensc 51
 
3692 stevensc 52
const MenuDrawerItem = ({ item: { label, href, ajax, icon: Icon }, onClose }) => {
53
  const navigate = useNavigate();
54
  const dispatch = useDispatch();
55
 
56
  const asyncNavigate = async (url) => {
57
    try {
58
      const { data } = await axios.get(url);
59
      if (!data.success) throw new Error('Ha ocurrido un error. Por favor, intente nuevamente.');
60
      navigate(data.data);
61
    } catch (error) {
62
      dispatch(addNotification({ style: 'danger', msg: error.message }));
3201 stevensc 63
    }
3692 stevensc 64
  };
3201 stevensc 65
 
3692 stevensc 66
  const handleClick = (e) => {
67
    e.stopPropagation();
68
    onClose();
69
 
70
    if (ajax) {
71
      e.preventDefault();
72
      asyncNavigate(href);
73
    } else {
74
      navigate(href);
75
    }
76
  };
77
 
3201 stevensc 78
  return (
3692 stevensc 79
    <ListItemButton
80
      onClick={handleClick}
3710 stevensc 81
      sx={{ display: 'flex', alignItems: 'center', gap: 1, width: '100%', padding: 0 }}
3201 stevensc 82
    >
3692 stevensc 83
      {Icon && (
84
        <ListItemIcon>
3201 stevensc 85
          <Icon />
86
        </ListItemIcon>
3692 stevensc 87
      )}
3201 stevensc 88
      <ListItemText primary={label} />
3692 stevensc 89
    </ListItemButton>
90
  );
91
};
3201 stevensc 92
 
3692 stevensc 93
const AccordionItem = ({ item: { label, childs, icon: Icon }, onClose }) => {
94
  const handleAccordionClick = (e) => {
95
    e.stopPropagation();
96
  };
3201 stevensc 97
 
98
  return (
99
    <Accordion
3692 stevensc 100
      disableGutters
101
      elevation={0}
3201 stevensc 102
      sx={{
103
        width: '100%',
104
        '&::before': {
105
          display: 'none'
106
        }
107
      }}
108
    >
109
      <AccordionSummary
110
        expandIcon={<ExpandMore />}
3692 stevensc 111
        onClick={handleAccordionClick}
112
        sx={{
113
          padding: '8px 16px !important',
114
          '& .MuiAccordionSummary-content': {
115
            margin: 0
116
          }
117
        }}
3201 stevensc 118
      >
119
        <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
120
          {Icon && <Icon />}
121
          <Typography margin='0'>{label}</Typography>
122
        </Box>
123
      </AccordionSummary>
124
 
125
      <AccordionDetails sx={{ padding: 0 }}>
3692 stevensc 126
        <List disablePadding>
127
          {childs.map((child) => (
128
            <RenderMenuItem
129
              key={child.href || child.label}
130
              item={child}
131
              onClose={onClose}
132
              isSubItem
133
            />
134
          ))}
135
        </List>
3201 stevensc 136
      </AccordionDetails>
137
    </Accordion>
3692 stevensc 138
  );
139
};
3201 stevensc 140
 
3710 stevensc 141
export default Drawer;