Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6,929 changes: 6,929 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"@emotion/styled": "11.14.1",
"@fontsource/public-sans": "5.2.7",
"@mui/base": "5.0.0-beta.70",
"@mui/icons-material": "^7.3.7",
"@mui/lab": "7.0.1-beta.20",
"@mui/material": "7.3.6",
"@mui/system": "7.3.6",
Expand Down
4 changes: 2 additions & 2 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { RouterProvider } from 'react-router-dom';

// project imports

import router from 'routes';
import ThemeCustomization from 'themes';

import ScrollTop from 'components/ScrollTop';

// ==============================|| APP - THEME, ROUTER, LOCAL ||============================== //


export default function App() {
return (
Expand Down
157 changes: 157 additions & 0 deletions src/components/CustomerTable.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import PropTypes from 'prop-types';

// material-ui
import {
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Chip,
Button,
Stack,
Typography,
Box,
Divider
} from '@mui/material';

// ==============================|| CRM - TABLA DE CLIENTES PREMIUM ||============================== //

export default function CustomerTable({ clientes, setClientes, onDelete }) {

// Mapeo de estilos por estado para mayor limpieza
const getStatusStyle = (estado) => {
const styles = {
'En Proceso': { color: 'primary', label: 'En Seguimiento' },
'Descartado': { color: 'error', label: 'Cerrado / Perdido' },
'Default': { color: 'secondary', label: estado }
};
return styles[estado] || styles['Default'];
};

return (
<Box>
<TableContainer>
<Table sx={{ minWidth: 700 }} aria-label="tabla de prospectos">
<TableHead sx={{ bgcolor: 'grey.50' }}>
<TableRow>
<TableCell sx={{ py: 2 }}>
<Typography variant="overline" sx={{ fontWeight: 700, color: 'text.secondary' }}>
Empresa / Cliente
</Typography>
</TableCell>
<TableCell>
<Typography variant="overline" sx={{ fontWeight: 700, color: 'text.secondary' }}>
Estado Actual
</Typography>
</TableCell>
<TableCell align="right">
<Typography variant="overline" sx={{ fontWeight: 700, color: 'text.secondary' }}>
Valor del Trato
</Typography>
</TableCell>
<TableCell align="center">
<Typography variant="overline" sx={{ fontWeight: 700, color: 'text.secondary' }}>
Flujo de Trabajo
</Typography>
</TableCell>
<TableCell align="right" />
</TableRow>
</TableHead>
<TableBody>
{clientes.map((row) => {
const status = getStatusStyle(row.estado);
return (
<TableRow key={row._id} hover sx={{ '&:last-child td, &:last-child th': { border: 0 } }}>
<TableCell>
<Stack spacing={0.5}>
<Typography variant="subtitle1" sx={{ color: 'primary.main', fontWeight: 600 }}>
{row.nombre}
</Typography>
<Typography variant="caption" color="text.secondary">
ID: {row._id.slice(-6).toUpperCase()}
</Typography>
</Stack>
</TableCell>
<TableCell>
<Chip
label={status.label}
size="small"
color={status.color}
variant="light" // Estilo Mantis: fondo suave, texto fuerte
sx={{ borderRadius: '4px', fontWeight: 600, fontSize: '0.7rem' }}
/>
</TableCell>
<TableCell align="right">
<Typography variant="subtitle1" sx={{ fontFamily: 'monospace', fontWeight: 700 }}>
${row.valor?.toLocaleString('en-US', { minimumFractionDigits: 2 })}
</Typography>
</TableCell>
<TableCell align="center">
<Stack direction="row" spacing={0.5} justifyContent="center">
<Button
size="small"
variant={row.estado === 'En Proceso' ? 'contained' : 'text'}
color="primary"
disableElevation
onClick={() => setClientes(row._id, 'En Proceso')}
sx={{ fontSize: '0.75rem', px: 1 }}
>
Activar
</Button>
<Divider orientation="vertical" flexItem sx={{ mx: 0.5, height: 15, alignSelf: 'center' }} />
<Button
size="small"
variant={row.estado === 'Descartado' ? 'contained' : 'text'}
color="inherit"
onClick={() => setClientes(row._id, 'Descartado')}
sx={{ fontSize: '0.75rem', px: 1, color: 'text.secondary' }}
>
Archivar
</Button>
</Stack>
</TableCell>
<TableCell align="right">
<Button
size="small"
variant="text"
color="error"
onClick={() => onDelete(row._id)}
sx={{
minWidth: 'auto',
fontSize: '0.7rem',
'&:hover': { bgcolor: 'error.lighter', fontWeight: 'bold' }
}}
>
ELIMINAR
</Button>
</TableCell>
</TableRow>
);
})}

{clientes.length === 0 && (
<TableRow>
<TableCell colSpan={5} align="center" sx={{ py: 10 }}>
<Stack alignItems="center" spacing={1}>
<Typography variant="h5" color="text.secondary">📪</Typography>
<Typography variant="body2" color="text.secondary">
No se encontraron registros activos en el sistema.
</Typography>
</Stack>
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</TableContainer>
</Box>
);
}

CustomerTable.propTypes = {
clientes: PropTypes.array.isRequired,
setClientes: PropTypes.func.isRequired,
onDelete: PropTypes.func.isRequired
};
6 changes: 3 additions & 3 deletions src/layout/Dashboard/Header/HeaderContent/Search.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// material-ui

import FormControl from '@mui/material/FormControl';
import InputAdornment from '@mui/material/InputAdornment';
import OutlinedInput from '@mui/material/OutlinedInput';
import Box from '@mui/material/Box';

// assets

import SearchOutlined from '@ant-design/icons/SearchOutlined';

// ==============================|| HEADER CONTENT - SEARCH ||============================== //


export default function Search() {
return (
Expand Down
32 changes: 2 additions & 30 deletions src/layout/Dashboard/Header/HeaderContent/index.jsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,14 @@
// material-ui
import useMediaQuery from '@mui/material/useMediaQuery';
import IconButton from '@mui/material/IconButton';
import Link from '@mui/material/Link';
import Box from '@mui/material/Box';

// project imports
import Search from './Search';
import Profile from './Profile';
import Notification from './Notification';
import MobileSection from './MobileSection';

// project import
import { GithubOutlined } from '@ant-design/icons';

// ==============================|| HEADER - CONTENT ||============================== //

export default function HeaderContent() {
const downLG = useMediaQuery((theme) => theme.breakpoints.down('lg'));

return (
<>
{!downLG && <Search />}
{downLG && <Box sx={{ width: '100%', ml: 1 }} />}
<IconButton
component={Link}
href="https://github.com/codedthemes/mantis-free-react-admin-template"
target="_blank"
disableRipple
color="secondary"
title="Download Free Version"
sx={{ color: 'text.primary', bgcolor: 'grey.100' }}
>
<GithubOutlined />
</IconButton>

<Notification />
{!downLG && <Profile />}
<Box sx={{ width: '100%', ml: 1 }} />
{downLG && <MobileSection />}
</>
);
}
}
14 changes: 7 additions & 7 deletions src/layout/Dashboard/Header/index.jsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
import { useMemo } from 'react';

// material-ui

import useMediaQuery from '@mui/material/useMediaQuery';
import AppBar from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';

// project imports

import AppBarStyled from './AppBarStyled';
import HeaderContent from './HeaderContent';
import IconButton from 'components/@extended/IconButton';

import { handlerDrawerOpen, useGetMenuMaster } from 'api/menu';
import { DRAWER_WIDTH, MINI_DRAWER_WIDTH } from 'config';

// assets

import MenuFoldOutlined from '@ant-design/icons/MenuFoldOutlined';
import MenuUnfoldOutlined from '@ant-design/icons/MenuUnfoldOutlined';

// ==============================|| MAIN LAYOUT - HEADER ||============================== //


export default function Header() {
const downLG = useMediaQuery((theme) => theme.breakpoints.down('lg'));

const { menuMaster } = useGetMenuMaster();
const drawerOpen = menuMaster.isDashboardDrawerOpened;

// header content

const headerContent = useMemo(() => <HeaderContent />, []);

// common header

const mainHeader = (
<Toolbar>
<IconButton
Expand All @@ -49,7 +49,7 @@ export default function Header() {
</Toolbar>
);

// app-bar params

const appBar = {
position: 'fixed',
color: 'inherit',
Expand Down
12 changes: 5 additions & 7 deletions src/menu-items/index.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
// project import

import dashboard from './dashboard';
import pages from './page';
import utilities from './utilities';
import support from './support';

// ==============================|| MENU ITEMS ||============================== //


const menuItems = {
items: [dashboard, pages, utilities, support]

items: [dashboard]
};

export default menuItems;
export default menuItems;
Loading