diff --git a/admin/src/app/professionals/[id]/page.tsx b/admin/src/app/professionals/[id]/page.tsx
index 4122a98..49bc87b 100644
--- a/admin/src/app/professionals/[id]/page.tsx
+++ b/admin/src/app/professionals/[id]/page.tsx
@@ -21,6 +21,7 @@ interface Professional {
profession?: string; identification?: string; address?: string;
rethus_code?: string; rethus_validated?: boolean;
rate?: number; average_score?: number;
+ identification_picture?: string; certificate_picture?: string; banner_picture?: string;
users?: User; schedules?: Schedule[];
specializations?: Specialization[]; payment_methods?: PaymentMethod[];
}
@@ -138,10 +139,21 @@ export default function ProfessionalDetailPage() {
};
const deny = async () => {
+ if (!confirm('¿Rechazar esta solicitud? Se eliminará el perfil profesional.')) return;
try { await api.post(`/professionals/${id}/deny`); toast.success('Solicitud rechazada'); load(); }
catch { toast.error('Error al rechazar'); }
};
+ const deactivate = async () => {
+ try { await api.post(`/professionals/${id}/deactivate`); toast.success('Profesional desactivado'); load(); }
+ catch { toast.error('Error al desactivar'); }
+ };
+
+ const setPending = async () => {
+ try { await api.post(`/professionals/${id}/set-pending`); toast.success('Puesto en revisión'); load(); }
+ catch { toast.error('Error al cambiar estado'); }
+ };
+
if (loading) return
Cargando...
;
if (error || !professional) return (
@@ -163,9 +175,22 @@ export default function ProfessionalDetailPage() {
ID profesional: {id}
-
- {professional.is_active ? 'Activo' : 'Pendiente'}
-
+
+
+ {professional.is_active ? 'Activo' : 'Pendiente / Inactivo'}
+
+ {professional.is_active ? (
+ <>
+
+
+ >
+ ) : (
+ <>
+
+
+ >
+ )}
+
{/* Datos del usuario */}
@@ -356,6 +381,51 @@ export default function ProfessionalDetailPage() {
+ {/* Documentos subidos */}
+ {(professional.identification_picture || professional.certificate_picture || professional.banner_picture) && (
+
+ Documentos y fotos
+
+ {professional.identification_picture && (
+
+
Foto de cédula
+ {professional.identification_picture.match(/\.(jpg|jpeg|png|webp)$/i) ? (
+
+
+
+ ) : (
+
+ Ver documento
+
+ )}
+
+ )}
+ {professional.certificate_picture && (
+
+
Certificado / Diploma
+ {professional.certificate_picture.match(/\.(jpg|jpeg|png|webp)$/i) ? (
+
+
+
+ ) : (
+
+ Ver documento
+
+ )}
+
+ )}
+ {professional.banner_picture && (
+
+
Foto de perfil / Banner
+
+
+
+
+ )}
+
+
+ )}
+
{/* Métodos de pago */}
{professional.payment_methods && professional.payment_methods.length > 0 && (
diff --git a/backend/src/professionals/professionals.controller.ts b/backend/src/professionals/professionals.controller.ts
index 80e22d0..ff5d9f0 100644
--- a/backend/src/professionals/professionals.controller.ts
+++ b/backend/src/professionals/professionals.controller.ts
@@ -82,6 +82,20 @@ export class ProfessionalsController {
return this.pros.upsert(req.user.sub, dto);
}
+ @Post(':id/deactivate')
+ @UseGuards(JwtAuthGuard)
+ @ApiBearerAuth()
+ deactivate(@Param('id') id: string) {
+ return this.pros.deactivate(id);
+ }
+
+ @Post(':id/set-pending')
+ @UseGuards(JwtAuthGuard)
+ @ApiBearerAuth()
+ setPending(@Param('id') id: string) {
+ return this.pros.setPending(id);
+ }
+
@Patch(':id')
@UseGuards(JwtAuthGuard)
@ApiBearerAuth()
diff --git a/backend/src/professionals/professionals.service.ts b/backend/src/professionals/professionals.service.ts
index 5053c82..7fa742d 100644
--- a/backend/src/professionals/professionals.service.ts
+++ b/backend/src/professionals/professionals.service.ts
@@ -155,6 +155,26 @@ export class ProfessionalsService {
return { message: 'Solicitud rechazada' };
}
+ async deactivate(id: string) {
+ const prof = await this.prisma.professionals.findUnique({ where: { id } });
+ if (!prof) throw new NotFoundException('Profesional no encontrado');
+ await this.prisma.$transaction([
+ this.prisma.professionals.update({ where: { id }, data: { is_active: false } }),
+ this.prisma.users.update({ where: { id: prof.user_id }, data: { pro_state: 3 } }),
+ ]);
+ return { message: 'Profesional desactivado' };
+ }
+
+ async setPending(id: string) {
+ const prof = await this.prisma.professionals.findUnique({ where: { id } });
+ if (!prof) throw new NotFoundException('Profesional no encontrado');
+ await this.prisma.$transaction([
+ this.prisma.professionals.update({ where: { id }, data: { is_active: false } }),
+ this.prisma.users.update({ where: { id: prof.user_id }, data: { pro_state: 1 } }),
+ ]);
+ return { message: 'Profesional puesto en revisión' };
+ }
+
async validateRethus(id: string) {
const prof = await this.prisma.professionals.findUnique({ where: { id } });
if (!prof) throw new NotFoundException('Profesional no encontrado');