108 lines
3.9 KiB
React
108 lines
3.9 KiB
React
import { useState } from 'react'
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
Typography,
|
|
Box,
|
|
Chip,
|
|
IconButton,
|
|
Menu,
|
|
MenuItem,
|
|
} from '@mui/material'
|
|
import MoreVertIcon from '@mui/icons-material/MoreVert'
|
|
import { useDeleteSession, useUnblockSession } from './api'
|
|
|
|
function formatDate(d) {
|
|
try {
|
|
return new Date(d).toLocaleString()
|
|
} catch {
|
|
return d
|
|
}
|
|
}
|
|
|
|
export default function SessionCard({ session, onBlock }) {
|
|
const [anchor, setAnchor] = useState(null)
|
|
const deleteMutation = useDeleteSession()
|
|
const unblockMutation = useUnblockSession()
|
|
|
|
const handleDelete = async () => {
|
|
setAnchor(null)
|
|
if (!window.confirm(`¿Eliminar la sesión de ${session.phone || 'desconocido'} y todo su historial de chat?`)) return
|
|
deleteMutation.mutate({ id: session.id, phone: session.phone })
|
|
}
|
|
|
|
const handleUnblock = async () => {
|
|
setAnchor(null)
|
|
if (!window.confirm(`Desbloquear sesión para ${session.phone}?`)) return
|
|
unblockMutation.mutate({ phone: session.phone })
|
|
}
|
|
|
|
const statusColor = session.finished ? 'success' : 'warning'
|
|
const statusText = session.finished ? 'Finalizada' : 'Activa'
|
|
|
|
return (
|
|
<Card sx={{ mb: 2 }}>
|
|
<CardContent>
|
|
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
|
|
<Box sx={{ flex: 1, minWidth: 0 }}>
|
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, flexWrap: 'wrap' }}>
|
|
<Typography variant="subtitle1" sx={{ fontWeight: 600, overflowWrap: 'anywhere' }}>
|
|
{session.name || `Teléfono: ${session.phone || 'desconocido'}`}
|
|
{session.name && session.phone && (
|
|
<Typography component="span" variant="caption" color="text.secondary" sx={{ ml: 1 }}>
|
|
({session.phone})
|
|
</Typography>
|
|
)}
|
|
</Typography>
|
|
<Chip size="small" color={statusColor} label={statusText} />
|
|
{session.block && (
|
|
<Chip size="small" color="error" label="Bloqueada" />
|
|
)}
|
|
</Box>
|
|
<Typography variant="caption" display="block" color="text.secondary" sx={{ mt: 0.5 }}>
|
|
<strong>Resumen:</strong> {session.summary || 'Aún no hay resumen.'}
|
|
</Typography>
|
|
<Typography variant="caption" display="block" color="text.disabled" sx={{ mt: 1, overflowWrap: 'anywhere' }}>
|
|
Campaña: {session.campaign_id?.split('-')[0] || 'N/A'}...
|
|
</Typography>
|
|
<Box sx={{ display: 'flex', gap: 2, mt: 0.5, flexWrap: 'wrap' }}>
|
|
<Typography variant="caption" color="text.disabled">
|
|
Iniciada: {formatDate(session.created_at)}
|
|
</Typography>
|
|
<Typography variant="caption" color="text.disabled">
|
|
Última interacción: {session.last_interaction ? formatDate(session.last_interaction) : 'Ninguna'}
|
|
</Typography>
|
|
</Box>
|
|
<Typography variant="caption" display="block" color="text.disabled" sx={{ mt: 0.5, overflowWrap: 'anywhere' }}>
|
|
ID de sesión: {session.id}
|
|
</Typography>
|
|
</Box>
|
|
<IconButton onClick={(e) => setAnchor(e.currentTarget)}>
|
|
<MoreVertIcon />
|
|
</IconButton>
|
|
</Box>
|
|
</CardContent>
|
|
<Menu anchorEl={anchor} open={Boolean(anchor)} onClose={() => setAnchor(null)}>
|
|
{session.block ? (
|
|
<MenuItem onClick={handleUnblock} sx={{ color: 'error.main' }}>
|
|
Desbloquear
|
|
</MenuItem>
|
|
) : (
|
|
<MenuItem
|
|
onClick={() => {
|
|
setAnchor(null)
|
|
onBlock(session)
|
|
}}
|
|
sx={{ color: 'error.main' }}
|
|
>
|
|
Bloquear
|
|
</MenuItem>
|
|
)}
|
|
<MenuItem onClick={handleDelete} sx={{ color: 'error.main' }}>
|
|
Eliminar
|
|
</MenuItem>
|
|
</Menu>
|
|
</Card>
|
|
)
|
|
}
|