'use client'; import { useState } from 'react'; import { Button, Card, CardContent, CardHeader, CardTitle, Input, Label, Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Tabs, TabsList, TabsTrigger, TabsContent, cn, } from '@horux/shared-ui'; import { useQueryClient } from '@tanstack/react-query'; import { FolderOpen, Plus, Trash2, ChevronDown, ChevronUp, X, Users, Building2, FolderPlus, UserCog, ClipboardList, } from 'lucide-react'; import { useCarteras, useCreateCartera, useDeleteCartera, useCarteraEntidades, useSubcarteras, useCreateSubcartera, useSupervisores, } from '@/lib/hooks/use-carteras'; import { addEntidadToCartera, removeEntidadFromCartera, } from '@/lib/api/carteras'; import { useContribuyentes } from '@/lib/hooks/use-contribuyentes'; import { useUsuarios } from '@/lib/hooks/use-usuarios'; import { useAuthStore } from '@/stores/auth-store'; import { DashboardShell } from '@/components/layouts/dashboard-shell'; import type { Cartera } from '@/lib/api/carteras'; import SeguimientoAuxiliares from './seguimiento-auxiliares'; /* ------------------------------------------------------------------ */ /* SubcarteraCard */ /* ------------------------------------------------------------------ */ function SubcarteraCard({ sub, usuarios, contribuyentes, parentEntidadIds, onDelete }: { sub: Cartera; usuarios: any[]; contribuyentes: any[]; parentEntidadIds: string[]; onDelete: () => void; }) { const [expanded, setExpanded] = useState(false); const qc = useQueryClient(); const { data: entidadIds, isLoading } = useCarteraEntidades(expanded ? sub.id : null); const [addingEntidad, setAddingEntidad] = useState(false); const [selectedEntidadId, setSelectedEntidadId] = useState(''); const [busy, setBusy] = useState(false); const entidadMap = Object.fromEntries( (contribuyentes ?? []).map((c: any) => [c.id, { rfc: c.rfc, nombre: c.nombre }]) ); const available = (contribuyentes ?? []).filter( (c: any) => (parentEntidadIds ?? []).includes(c.id) && !(entidadIds ?? []).includes(c.id) ); const auxiliarUser = usuarios?.find((u: any) => u.id === sub.auxiliarUserId); const invalidate = () => { qc.invalidateQueries({ queryKey: ['cartera-entidades', sub.id] }); qc.invalidateQueries({ queryKey: ['subcarteras'] }); qc.invalidateQueries({ queryKey: ['carteras'] }); }; const handleAddEntidad = async () => { if (!selectedEntidadId) return; setBusy(true); try { await addEntidadToCartera(sub.id, selectedEntidadId); setSelectedEntidadId(''); setAddingEntidad(false); invalidate(); } finally { setBusy(false); } }; const handleRemoveEntidad = async (entidadId: string) => { setBusy(true); try { await removeEntidadFromCartera(sub.id, entidadId); invalidate(); } finally { setBusy(false); } }; return (
{expanded && (
{!addingEntidad && ( )} {addingEntidad && (
)} {isLoading ? (

Cargando...

) : !entidadIds || entidadIds.length === 0 ? (

Sin RFCs asignados a esta subcartera.

) : ( )}
)}
); } /* ------------------------------------------------------------------ */ /* CarteraDetail */ /* ------------------------------------------------------------------ */ function CarteraDetail({ cartera, canEdit = true, canManageSubcarteras = true }: { cartera: Cartera; canEdit?: boolean; canManageSubcarteras?: boolean }) { const qc = useQueryClient(); const { data: contribuyentes } = useContribuyentes(); const { data: usuarios } = useUsuarios(); const { data: entidadIds, isLoading: loadingEntidades } = useCarteraEntidades(cartera.id); const { data: subcarteras, isLoading: loadingSubs } = useSubcarteras(cartera.id); const createSub = useCreateSubcartera(); const [addingEntidad, setAddingEntidad] = useState(false); const [selectedEntidadId, setSelectedEntidadId] = useState(''); const [showCreateSub, setShowCreateSub] = useState(false); const [subForm, setSubForm] = useState({ nombre: '', auxiliarUserId: '' }); const [busy, setBusy] = useState(false); const entidadMap = Object.fromEntries( (contribuyentes ?? []).map((c) => [c.id, { rfc: c.rfc, nombre: c.nombre }]) ); const available = (contribuyentes ?? []).filter( (c) => !(entidadIds ?? []).includes(c.id) ); // Auxiliares available for subcarteras (those assigned to this supervisor) const auxiliares = (usuarios ?? []).filter((u: any) => u.role === 'auxiliar'); const supervisorUser = usuarios?.find((u: any) => u.id === cartera.supervisorUserId); const invalidate = () => { qc.invalidateQueries({ queryKey: ['cartera-entidades', cartera.id] }); qc.invalidateQueries({ queryKey: ['subcarteras', cartera.id] }); qc.invalidateQueries({ queryKey: ['carteras'] }); }; const handleAddEntidad = async () => { if (!selectedEntidadId) return; setBusy(true); try { await addEntidadToCartera(cartera.id, selectedEntidadId); setSelectedEntidadId(''); setAddingEntidad(false); invalidate(); } finally { setBusy(false); } }; const handleRemoveEntidad = async (entidadId: string) => { setBusy(true); try { await removeEntidadFromCartera(cartera.id, entidadId); invalidate(); } finally { setBusy(false); } }; const handleCreateSubcartera = async () => { if (!subForm.nombre.trim() || !subForm.auxiliarUserId) return; try { await createSub.mutateAsync({ carteraId: cartera.id, nombre: subForm.nombre.trim(), auxiliarUserId: subForm.auxiliarUserId, }); setSubForm({ nombre: '', auxiliarUserId: '' }); setShowCreateSub(false); } catch (err: any) { alert(err.response?.data?.message || 'Error al crear subcartera'); } }; const handleDeleteSubcartera = async (subId: string) => { if (!confirm('¿Eliminar esta subcartera?')) return; try { const { deleteCartera } = await import('@/lib/api/carteras'); await deleteCartera(subId); invalidate(); } catch (err: any) { alert(err.response?.data?.message || 'Error al eliminar'); } }; return (
{/* Supervisor info */} {supervisorUser && (
Supervisor: {supervisorUser.nombre} ({supervisorUser.email})
)} {/* ---- Contribuyentes ---- */}

Contribuyentes ({entidadIds?.length || 0})

{canEdit && !addingEntidad && ( )}
{canEdit && addingEntidad && (
)} {loadingEntidades ? (

Cargando...

) : !entidadIds || entidadIds.length === 0 ? (

Sin contribuyentes asignados.

) : ( )}
{/* ---- Subcarteras ---- */}

Subcarteras ({subcarteras?.length || 0})

{canManageSubcarteras && !showCreateSub && ( )}
{canManageSubcarteras && showCreateSub && (
setSubForm(p => ({ ...p, nombre: e.target.value }))} placeholder="Ej. Cartera de María" className="h-8 text-sm mt-1" />
)} {loadingSubs ? (

Cargando...

) : !subcarteras || subcarteras.length === 0 ? (

Sin subcarteras. Crea una para asignar RFCs a un auxiliar.

) : (
{subcarteras.map(sub => ( handleDeleteSubcartera(sub.id)} /> ))}
)}
); } /* ------------------------------------------------------------------ */ /* CarteraCard */ /* ------------------------------------------------------------------ */ function CarteraCard({ cartera, expanded, onToggle, onDelete, usuarios, canEdit, canManageSubcarteras }: { cartera: Cartera; expanded: boolean; onToggle: () => void; onDelete: () => void; usuarios: any[]; canEdit: boolean; canManageSubcarteras: boolean; }) { const supervisorUser = usuarios?.find((u: any) => u.id === cartera.supervisorUserId); return (
{canEdit && ( )}
{supervisorUser && ( {supervisorUser.nombre} )} {cartera.entidadesCount} RFCs {cartera.subcarterasCount} subcarteras
{expanded && ( )}
); } /* ------------------------------------------------------------------ */ /* Page */ /* ------------------------------------------------------------------ */ export default function CarterasPage() { const { user } = useAuthStore(); const userRole = user?.role || 'visor'; const canCreate = userRole === 'owner'; // Create top-level carteras const canEditCartera = userRole === 'owner'; // Edit/delete top-level carteras + add/remove RFCs const canManageSubcarteras = userRole === 'owner' || userRole === 'supervisor'; // Create subcarteras const isAuxiliar = userRole === 'auxiliar'; const isSupervisor = userRole === 'supervisor'; const isOwner = userRole === 'owner'; const puedeVerSeguimiento = isOwner || isSupervisor; const [activeTab, setActiveTab] = useState('carteras'); const { data: carteras, isLoading } = useCarteras(); const { data: supervisores } = useSupervisores(); const { data: usuarios } = useUsuarios(); const createMut = useCreateCartera(); const deleteMut = useDeleteCartera(); const [expandedId, setExpandedId] = useState(null); const [showCreate, setShowCreate] = useState(false); const [form, setForm] = useState({ nombre: '', descripcion: '', supervisorUserId: '' }); const hasSupervisores = supervisores && supervisores.length > 0; const resetForm = () => { setForm({ nombre: '', descripcion: '', supervisorUserId: '' }); setShowCreate(false); }; const handleCreate = async () => { if (!form.nombre.trim()) return; try { const supervisorUserId = form.supervisorUserId && form.supervisorUserId !== '__self__' ? form.supervisorUserId : undefined; const cartera = await createMut.mutateAsync({ nombre: form.nombre.trim(), descripcion: form.descripcion.trim() || undefined, supervisorUserId, }); resetForm(); setExpandedId(cartera.id); } catch (err: any) { alert(err.response?.data?.message || 'Error al crear cartera'); } }; const handleDelete = async (cartera: Cartera) => { if (!confirm(`¿Eliminar la cartera "${cartera.nombre}"? Se eliminarán también sus subcarteras.`)) return; try { await deleteMut.mutateAsync(cartera.id); if (expandedId === cartera.id) setExpandedId(null); } catch (err: any) { alert(err.response?.data?.message || 'Error al eliminar cartera'); } }; const CarterasList = () => ( <> {isLoading ? (

Cargando...

) : !carteras || carteras.length === 0 ? (

Sin carteras

Crea la primera cartera para organizar tus contribuyentes.

) : (
{carteras.map(cartera => ( setExpandedId(expandedId === cartera.id ? null : cartera.id)} onDelete={() => handleDelete(cartera)} usuarios={usuarios ?? []} canEdit={canEditCartera} canManageSubcarteras={canManageSubcarteras} /> ))}
)} ); return (
{/* Header */}

{isAuxiliar ? 'Carteras asignadas a ti' : 'Organiza contribuyentes en carteras y asigna subcarteras a cada auxiliar'}

{canCreate && activeTab === 'carteras' && ( )}
{puedeVerSeguimiento ? ( Carteras Seguimiento de Auxiliares ) : ( )} {/* Create dialog */} { if (!open) resetForm(); }}> Nueva cartera
setForm(p => ({ ...p, nombre: e.target.value }))} placeholder="Ej. Clientes CDMX" autoFocus />
setForm(p => ({ ...p, descripcion: e.target.value }))} placeholder="Descripcion breve" />
{hasSupervisores ? (

Si no seleccionas, la cartera se asigna a ti.

) : (

No hay supervisores registrados. La cartera se asignará a ti como owner.

)}
); }