Compare commits

...

6 Commits

Author SHA1 Message Date
Horux Dev
5dd53cebac chore(usuarios): limpiar debug hardcodeado de supervisorNombre 2026-05-29 19:27:59 +00:00
Horux Dev
0de0df9357 fix(usuarios): mostrar nombre del supervisor en dropdown de forma robusta
- Backend: getSupervisor devuelve supervisorNombre desde Prisma
- Frontend: usa SelectTrigger con renderizado manual del label seleccionado
  en lugar de depender de SelectValue, que no siempre encontraba el texto
  del SelectItem cuando el supervisor no estaba en la lista de carteras
2026-05-29 19:03:36 +00:00
Horux Dev
20fb8ea2db debug(usuarios): agregar console.log para diagnosticar supervisorNombre 2026-05-29 18:10:33 +00:00
Horux Dev
8c9a7b73dc fix(usuarios): agregar import faltante de prisma en getSupervisor 2026-05-29 17:43:13 +00:00
Horux Dev
910c50d870 fix(usuarios): mostrar nombre del supervisor al editar auxiliar
- Backend getSupervisor ahora devuelve supervisorNombre buscando en Prisma
- Frontend usa supervisorNombre para mostrar en Select cuando el supervisor
  no está en la lista de carteras/supervisores
2026-05-29 17:24:18 +00:00
Horux Dev
2f49fdc9b7 fix(contribuyentes): agregar supervisorNombre al tipo Contribuyente 2026-05-29 17:12:58 +00:00
3 changed files with 32 additions and 5 deletions

View File

@@ -3,6 +3,7 @@ import { z } from 'zod';
import * as usuariosService from '../services/usuarios.service.js'; import * as usuariosService from '../services/usuarios.service.js';
import { AppError } from '../middlewares/error.middleware.js'; import { AppError } from '../middlewares/error.middleware.js';
import { isGlobalAdmin as checkGlobalAdmin } from '../utils/global-admin.js'; import { isGlobalAdmin as checkGlobalAdmin } from '../utils/global-admin.js';
import { prisma } from '../config/database.js';
const inviteSchema = z.object({ const inviteSchema = z.object({
email: z.string().email('email inválido'), email: z.string().email('email inválido'),
@@ -139,7 +140,16 @@ export async function getSupervisor(req: Request, res: Response, next: NextFunct
LIMIT 1`, LIMIT 1`,
[userId], [userId],
); );
res.json({ supervisorUserId: rows[0]?.supervisor_user_id ?? null }); const supervisorUserId = rows[0]?.supervisor_user_id ?? null;
let supervisorNombre: string | null = null;
if (supervisorUserId) {
const u = await prisma.user.findUnique({
where: { id: supervisorUserId },
select: { nombre: true },
});
supervisorNombre = u?.nombre ?? null;
}
res.json({ supervisorUserId, supervisorNombre });
} catch (error) { } catch (error) {
next(error); next(error);
} }

View File

@@ -96,15 +96,18 @@ export default function UsuariosPage() {
const [savingAccesos, setSavingAccesos] = useState(false); const [savingAccesos, setSavingAccesos] = useState(false);
// Edit supervisor modal (para auxiliares) // Edit supervisor modal (para auxiliares)
const [editingSupervisorUser, setEditingSupervisorUser] = useState<{ id: string; nombre: string } | null>(null); const [editingSupervisorUser, setEditingSupervisorUser] = useState<{ id: string; nombre: string; supervisorNombre?: string | null } | null>(null);
const [selectedSupervisorId, setSelectedSupervisorId] = useState<string>(''); const [selectedSupervisorId, setSelectedSupervisorId] = useState<string>('');
const [savingSupervisor, setSavingSupervisor] = useState(false); const [savingSupervisor, setSavingSupervisor] = useState(false);
const [currentSupervisorNombre, setCurrentSupervisorNombre] = useState<string>('');
const openEditSupervisor = async (userId: string, nombre: string) => { const openEditSupervisor = async (userId: string, nombre: string) => {
try { try {
const res = await apiClient.get<{ supervisorUserId: string | null }>(`/usuarios/${userId}/supervisor`); const res = await apiClient.get<{ supervisorUserId: string | null; supervisorNombre: string | null }>(`/usuarios/${userId}/supervisor`);
setSelectedSupervisorId(res.data.supervisorUserId ?? ''); setSelectedSupervisorId(res.data.supervisorUserId ?? '');
setEditingSupervisorUser({ id: userId, nombre }); setCurrentSupervisorNombre(res.data.supervisorNombre ?? '');
setEditingSupervisorUser({ id: userId, nombre, supervisorNombre: res.data.supervisorNombre });
} catch { } catch {
alert('Error al cargar supervisor'); alert('Error al cargar supervisor');
} }
@@ -483,7 +486,14 @@ export default function UsuariosPage() {
<div className="space-y-2 py-2"> <div className="space-y-2 py-2">
{supervisores && supervisores.length > 0 ? ( {supervisores && supervisores.length > 0 ? (
<Select value={selectedSupervisorId || 'none'} onValueChange={(v) => setSelectedSupervisorId(v === 'none' ? '' : v)}> <Select value={selectedSupervisorId || 'none'} onValueChange={(v) => setSelectedSupervisorId(v === 'none' ? '' : v)}>
<SelectTrigger><SelectValue placeholder="Selecciona un supervisor..." /></SelectTrigger> <SelectTrigger className="w-full">
{(() => {
if (!selectedSupervisorId || selectedSupervisorId === 'none') return <span className="text-muted-foreground">Sin supervisor asignado</span>;
const s = supervisores?.find(x => x.userId === selectedSupervisorId);
if (s) return <span>{s.nombre} {s.email}</span>;
return <span>{currentSupervisorNombre || editingSupervisorUser?.supervisorNombre || selectedSupervisorId}</span>;
})()}
</SelectTrigger>
<SelectContent> <SelectContent>
<SelectItem value="none">Sin supervisor asignado</SelectItem> <SelectItem value="none">Sin supervisor asignado</SelectItem>
{supervisores.map(s => ( {supervisores.map(s => (
@@ -491,6 +501,12 @@ export default function UsuariosPage() {
{s.nombre} {s.email} {s.nombre} {s.email}
</SelectItem> </SelectItem>
))} ))}
{/* Si el supervisor actual no está en la lista de carteras, mostrarlo igual */}
{selectedSupervisorId && !supervisores.some(s => s.userId === selectedSupervisorId) && (
<SelectItem value={selectedSupervisorId}>
{currentSupervisorNombre || editingSupervisorUser?.supervisorNombre || selectedSupervisorId}
</SelectItem>
)}
</SelectContent> </SelectContent>
</Select> </Select>
) : ( ) : (

View File

@@ -6,6 +6,7 @@ export interface Contribuyente {
nombre: string; nombre: string;
identificador: string; identificador: string;
supervisorUserId: string | null; supervisorUserId: string | null;
supervisorNombre: string | null;
active: boolean; active: boolean;
createdAt: string; createdAt: string;
rfc: string; rfc: string;