From 489cfd8f6ba4fbb6d96eb73f63a7affe5282f5d5 Mon Sep 17 00:00:00 2001 From: elmer-20 <80175046+elmer-20@users.noreply.github.com> Date: Fri, 13 Feb 2026 15:14:47 -0500 Subject: [PATCH 1/4] login2026 --- .../Administracion/CalificacionController.php | 109 ++ .../Administracion/ExamenesController.php | 465 ------ .../Administracion/PostulanteController.php | 64 + .../ReglaAreaProcesoController.php | 2 +- .../app/Http/Controllers/ExamenController.php | 2 +- back/app/Models/PreguntaAsignada.php | 2 +- back/app/Models/ResultadoExamen.php | 37 + back/app/Services/ExamenService.php | 42 +- back/routes/api.php | 23 +- front/src/router/index.js | 11 + front/src/store/examen.store.js | 62 +- .../Procesos/CalificacionTest.vue | 181 +++ .../estudiantes/ListPostulantes.vue | 201 +++ .../src/views/administrador/layout/layout.vue | 17 +- front/src/views/postulante/Dashboard.vue | 797 +++++----- front/src/views/postulante/MisProcesos.vue | 439 ++++-- front/src/views/postulante/Pagos.vue | 581 +++++--- .../src/views/postulante/PreguntasExamen.vue | 1284 +++++++++-------- front/src/views/postulante/Test.vue | 552 +++++-- 19 files changed, 2886 insertions(+), 1985 deletions(-) create mode 100644 back/app/Http/Controllers/Administracion/CalificacionController.php delete mode 100644 back/app/Http/Controllers/Administracion/ExamenesController.php create mode 100644 back/app/Http/Controllers/Administracion/PostulanteController.php create mode 100644 back/app/Models/ResultadoExamen.php create mode 100644 front/src/views/administrador/Procesos/CalificacionTest.vue create mode 100644 front/src/views/administrador/estudiantes/ListPostulantes.vue diff --git a/back/app/Http/Controllers/Administracion/CalificacionController.php b/back/app/Http/Controllers/Administracion/CalificacionController.php new file mode 100644 index 0000000..5b4d2bd --- /dev/null +++ b/back/app/Http/Controllers/Administracion/CalificacionController.php @@ -0,0 +1,109 @@ +json([ + 'success' => true, + 'data' => $calificaciones + ]); + } + + // ✅ Guardar nueva + public function store(Request $request) + { + $request->validate([ + 'nombre' => 'required|string|max:255', + 'puntos_correcta' => 'required|numeric', + 'puntos_incorrecta' => 'required|numeric', + 'puntos_nula' => 'required|numeric', + 'puntaje_maximo' => 'required|numeric', + ]); + + $calificacion = Calificacion::create($request->all()); + + return response()->json([ + 'success' => true, + 'message' => 'Calificación creada correctamente', + 'data' => $calificacion + ]); + } + + // ✅ Mostrar una + public function show($id) + { + $calificacion = Calificacion::find($id); + + if (!$calificacion) { + return response()->json([ + 'success' => false, + 'message' => 'No encontrada' + ], 404); + } + + return response()->json([ + 'success' => true, + 'data' => $calificacion + ]); + } + + // ✅ Actualizar + public function update(Request $request, $id) + { + $calificacion = Calificacion::find($id); + + if (!$calificacion) { + return response()->json([ + 'success' => false, + 'message' => 'No encontrada' + ], 404); + } + + $request->validate([ + 'nombre' => 'required|string|max:255', + 'puntos_correcta' => 'required|numeric', + 'puntos_incorrecta' => 'required|numeric', + 'puntos_nula' => 'required|numeric', + 'puntaje_maximo' => 'required|numeric', + ]); + + $calificacion->update($request->all()); + + return response()->json([ + 'success' => true, + 'message' => 'Calificación actualizada correctamente', + 'data' => $calificacion + ]); + } + + // ✅ Eliminar + public function destroy($id) + { + $calificacion = Calificacion::find($id); + + if (!$calificacion) { + return response()->json([ + 'success' => false, + 'message' => 'No encontrada' + ], 404); + } + + $calificacion->delete(); + + return response()->json([ + 'success' => true, + 'message' => 'Calificación eliminada correctamente' + ]); + } +} \ No newline at end of file diff --git a/back/app/Http/Controllers/Administracion/ExamenesController.php b/back/app/Http/Controllers/Administracion/ExamenesController.php deleted file mode 100644 index 944024b..0000000 --- a/back/app/Http/Controllers/Administracion/ExamenesController.php +++ /dev/null @@ -1,465 +0,0 @@ -user(); - - if (!$user->hasRole('administrador')) { - return response()->json([ - 'success' => false, - 'message' => 'No autorizado' - ], 403); - } - - $academia = Academia::where('admin_academia_id', $user->id)->first(); - - if (!$academia) { - return response()->json([ - 'success' => false, - 'message' => 'Academia no encontrada' - ], 404); - } - - $query = $academia->examenes() - ->withCount(['preguntas', 'intentos' => function($query) { - $query->where('estado', 'finalizado'); - }]) - ->latest(); - - if ($request->has('search')) { - $search = $request->search; - $query->where('titulo', 'like', "%{$search}%"); - } - - if ($request->has('publicado')) { - $query->where('publicado', $request->publicado); - } - - if ($request->has('tipo')) { - $query->where('tipo', $request->tipo); - } - - $examenes = $query->paginate(15); - - return response()->json([ - 'success' => true, - 'data' => $examenes - ]); - - } catch (\Exception $e) { - Log::error('Error obteniendo exámenes', [ - 'error' => $e->getMessage() - ]); - - return response()->json([ - 'success' => false, - 'message' => 'Error al cargar los exámenes' - ], 500); - } - } - - public function crearExamen(Request $request) - { - try { - $user = auth()->user(); - - if (!$user->hasRole('administrador')) { - return response()->json([ - 'success' => false, - 'message' => 'No autorizado' - ], 403); - } - - $academia = Academia::where('admin_academia_id', $user->id)->first(); - - if (!$academia) { - return response()->json([ - 'success' => false, - 'message' => 'Academia no encontrada' - ], 404); - } - - $validator = Validator::make($request->all(), [ - 'titulo' => 'required|string|max:255', - 'descripcion' => 'nullable|string', - 'tipo' => 'required|in:practica,simulacro,evaluacion', - 'dificultad' => 'required|in:facil,medio,dificil,avanzado', - - 'duracion_minutos' => 'required|integer|min:1|max:480', - 'intentos_permitidos' => 'required|integer|min:1|max:10', - 'puntaje_minimo' => 'required|numeric|min:0|max:100', - 'preguntas_aleatorias' => 'boolean', - 'mostrar_resultados' => 'boolean', - 'mostrar_respuestas' => 'boolean', - 'publicado' => 'boolean', - 'fecha_inicio' => 'nullable|date', - 'fecha_fin' => 'nullable|date|after_or_equal:fecha_inicio', - 'configuracion' => 'nullable|array' - ]); - - if ($validator->fails()) { - return response()->json([ - 'success' => false, - 'errors' => $validator->errors() - ], 422); - } - - DB::beginTransaction(); - - $examen = Examen::create([ - 'academia_id' => $academia->id, - 'titulo' => $request->titulo, - 'descripcion' => $request->descripcion, - 'tipo' => $request->tipo, - 'dificultad' => $request->dificultad, - 'duracion_minutos' => $request->duracion_minutos, - 'intentos_permitidos' => $request->intentos_permitidos, - 'puntaje_minimo' => $request->puntaje_minimo, - - 'preguntas_aleatorias' => $request->preguntas_aleatorias ?? 0, - - 'mezclar_opciones' => $request->mezclar_opciones ?? true, - 'mostrar_resultados' => $request->mostrar_resultados ?? true, - 'mostrar_respuestas' => $request->mostrar_respuestas ?? false, - 'mostrar_explicaciones' => $request->mostrar_explicaciones ?? false, - - 'activar_timer' => $request->activar_timer ?? true, - 'permitir_navegacion' => $request->permitir_navegacion ?? true, - 'permitir_revisar' => $request->permitir_revisar ?? true, - - 'publicado' => $request->publicado ?? false, - 'fecha_inicio' => $request->fecha_inicio, - 'fecha_fin' => $request->fecha_fin, - 'orden' => $request->orden ?? 1, - - 'configuracion' => $request->configuracion ?? [] - ]); - - DB::commit(); - - Log::info('Examen creado por admin', [ - 'academia_id' => $academia->id, - 'examen_id' => $examen->id, - 'admin_id' => $user->id - ]); - - return response()->json([ - 'success' => true, - 'message' => 'Examen creado exitosamente', - 'data' => $examen - ], 201); - - } catch (\Exception $e) { - DB::rollBack(); - - Log::error('Error creando examen', [ - 'error' => $e->getMessage() - ]); - - return response()->json([ - 'success' => false, - 'message' => 'Error al crear el examen' - ], 500); - } - } - - public function getExamen($examenId) - { - try { - $user = auth()->user(); - - if (!$user->hasRole('administrador')) { - return response()->json([ - 'success' => false, - 'message' => 'No autorizado' - ], 403); - } - - $academia = Academia::where('admin_academia_id', $user->id)->first(); - - if (!$academia) { - return response()->json([ - 'success' => false, - 'message' => 'Academia no encontrada' - ], 404); - } - - $examen = Examen::where('academia_id', $academia->id) - ->with(['preguntas']) - ->find($examenId); - - if (!$examen) { - return response()->json([ - 'success' => false, - 'message' => 'Examen no encontrado' - ], 404); - } - - $estadisticas = DB::table('intentos_examen') - ->where('examen_id', $examenId) - ->where('estado', 'finalizado') - ->selectRaw('COUNT(*) as total_intentos') - ->selectRaw('AVG(porcentaje) as promedio') - ->selectRaw('SUM(CASE WHEN aprobado = 1 THEN 1 ELSE 0 END) as aprobados') - ->first(); - - return response()->json([ - 'success' => true, - 'data' => [ - 'examen' => $examen, - 'estadisticas' => $estadisticas - ] - ]); - - } catch (\Exception $e) { - Log::error('Error obteniendo examen', [ - 'error' => $e->getMessage() - ]); - - return response()->json([ - 'success' => false, - 'message' => 'Error al cargar el examen' - ], 500); - } - } - - public function actualizarExamen(Request $request, $examenId) - { - try { - $user = auth()->user(); - - if (!$user->hasRole('administrador')) { - return response()->json([ - 'success' => false, - 'message' => 'No autorizado' - ], 403); - } - - $academia = Academia::where('admin_academia_id', $user->id)->first(); - - if (!$academia) { - return response()->json([ - 'success' => false, - 'message' => 'Academia no encontrada' - ], 404); - } - - $examen = Examen::where('academia_id', $academia->id)->find($examenId); - - if (!$examen) { - return response()->json([ - 'success' => false, - 'message' => 'Examen no encontrado' - ], 404); - } - - $validator = Validator::make($request->all(), [ - 'titulo' => 'sometimes|string|max:255', - 'descripcion' => 'nullable|string', - 'tipo' => 'sometimes|in:practica,simulacro,evaluacion', - 'duracion_minutos' => 'sometimes|integer|min:1|max:480', - 'intentos_permitidos' => 'sometimes|integer|min:1|max:10', - 'puntaje_minimo' => 'sometimes|numeric|min:0|max:100', - 'preguntas_aleatorias' => 'boolean', - 'mostrar_resultados' => 'boolean', - 'mostrar_respuestas' => 'boolean', - 'publicado' => 'boolean', - 'fecha_inicio' => 'nullable|date', - 'fecha_fin' => 'nullable|date|after_or_equal:fecha_inicio', - 'configuracion' => 'nullable|array' - ]); - - if ($validator->fails()) { - return response()->json([ - 'success' => false, - 'errors' => $validator->errors() - ], 422); - } - - $examen->update($request->only([ - 'titulo', 'descripcion', 'tipo', 'duracion_minutos', 'intentos_permitidos', - 'puntaje_minimo', 'preguntas_aleatorias', 'mostrar_resultados', - 'mostrar_respuestas', 'publicado', 'fecha_inicio', 'fecha_fin', 'configuracion' - ])); - - Log::info('Examen actualizado por admin', [ - 'academia_id' => $academia->id, - 'examen_id' => $examen->id, - 'admin_id' => $user->id - ]); - - return response()->json([ - 'success' => true, - 'message' => 'Examen actualizado exitosamente', - 'data' => $examen - ]); - - } catch (\Exception $e) { - Log::error('Error actualizando examen', [ - 'error' => $e->getMessage() - ]); - - return response()->json([ - 'success' => false, - 'message' => 'Error al actualizar el examen' - ], 500); - } - } - - public function eliminarExamen($examenId) - { - try { - $user = auth()->user(); - - if (!$user->hasRole('administrador')) { - return response()->json([ - 'success' => false, - 'message' => 'No autorizado' - ], 403); - } - - $academia = Academia::where('admin_academia_id', $user->id)->first(); - - if (!$academia) { - return response()->json([ - 'success' => false, - 'message' => 'Academia no encontrada' - ], 404); - } - - $examen = Examen::where('academia_id', $academia->id)->find($examenId); - - if (!$examen) { - return response()->json([ - 'success' => false, - 'message' => 'Examen no encontrado' - ], 404); - } - - $tieneIntentos = $examen->intentos()->exists(); - - if ($tieneIntentos) { - return response()->json([ - 'success' => false, - 'message' => 'No se puede eliminar un examen con intentos realizados' - ], 400); - } - - $examen->delete(); - - Log::info('Examen eliminado por admin', [ - 'academia_id' => $academia->id, - 'examen_id' => $examenId, - 'admin_id' => $user->id - ]); - - return response()->json([ - 'success' => true, - 'message' => 'Examen eliminado exitosamente' - ]); - - } catch (\Exception $e) { - Log::error('Error eliminando examen', [ - 'error' => $e->getMessage() - ]); - - return response()->json([ - 'success' => false, - 'message' => 'Error al eliminar el examen' - ], 500); - } - } - - public function getResultadosExamen($examenId) - { - try { - $user = auth()->user(); - - if (!$user->hasRole('administrador')) { - return response()->json([ - 'success' => false, - 'message' => 'No autorizado' - ], 403); - } - - $academia = Academia::where('admin_academia_id', $user->id)->first(); - - if (!$academia) { - return response()->json([ - 'success' => false, - 'message' => 'Academia no encontrada' - ], 404); - } - - $examen = Examen::where('academia_id', $academia->id)->find($examenId); - - if (!$examen) { - return response()->json([ - 'success' => false, - 'message' => 'Examen no encontrado' - ], 404); - } - - $resultados = DB::table('intentos_examen') - ->join('users', 'intentos_examen.user_id', '=', 'users.id') - ->where('intentos_examen.examen_id', $examenId) - ->where('intentos_examen.estado', 'finalizado') - ->select( - 'users.id as estudiante_id', - 'users.name as estudiante_nombre', - 'users.email as estudiante_email', - 'intentos_examen.numero_intento', - 'intentos_examen.porcentaje', - 'intentos_examen.aprobado', - 'intentos_examen.tiempo_utilizado', - 'intentos_examen.finalizado_en' - ) - ->orderBy('intentos_examen.porcentaje', 'desc') - ->get(); - - $estadisticas = [ - 'total_estudiantes' => $resultados->groupBy('estudiante_id')->count(), - 'promedio' => $resultados->avg('porcentaje'), - 'aprobados' => $resultados->where('aprobado', true)->count(), - 'reprobados' => $resultados->where('aprobado', false)->count(), - 'tiempo_promedio' => $resultados->avg('tiempo_utilizado') - ]; - - return response()->json([ - 'success' => true, - 'data' => [ - 'resultados' => $resultados, - 'estadisticas' => $estadisticas - ] - ]); - - } catch (\Exception $e) { - Log::error('Error obteniendo resultados', [ - 'error' => $e->getMessage() - ]); - - return response()->json([ - 'success' => false, - 'message' => 'Error al cargar los resultados' - ], 500); - } - } - -} \ No newline at end of file diff --git a/back/app/Http/Controllers/Administracion/PostulanteController.php b/back/app/Http/Controllers/Administracion/PostulanteController.php new file mode 100644 index 0000000..7feb6c0 --- /dev/null +++ b/back/app/Http/Controllers/Administracion/PostulanteController.php @@ -0,0 +1,64 @@ +buscar) { + $query->where(function ($q) use ($request) { + $q->where('name', 'like', "%{$request->buscar}%") + ->orWhere('email', 'like', "%{$request->buscar}%") + ->orWhere('dni', 'like', "%{$request->buscar}%"); + }); + } + + $postulantes = $query->orderBy('id', 'desc') + ->paginate(20); + + return response()->json([ + 'success' => true, + 'data' => $postulantes + ]); + } + + public function actualizarPostulante(Request $request, $id) + { + $postulante = Postulante::findOrFail($id); + + $request->validate([ + 'name' => 'required|string|max:255', + 'email' => 'required|email|unique:postulantes,email,' . $postulante->id, + 'dni' => 'required|string|max:20|unique:postulantes,dni,' . $postulante->id, + 'password' => 'nullable|string|min:6' + ]); + + $postulante->update([ + 'name' => $request->name, + 'email' => $request->email, + 'dni' => $request->dni, + ]); + + // 🔹 Solo si envían nueva contraseña + if ($request->filled('password')) { + $postulante->password = $request->password; + $postulante->save(); + } + + return response()->json([ + 'success' => true, + 'message' => 'Postulante actualizado correctamente', + 'data' => $postulante + ]); + } + + +} diff --git a/back/app/Http/Controllers/Administracion/ReglaAreaProcesoController.php b/back/app/Http/Controllers/Administracion/ReglaAreaProcesoController.php index 691ffdd..8f13db8 100644 --- a/back/app/Http/Controllers/Administracion/ReglaAreaProcesoController.php +++ b/back/app/Http/Controllers/Administracion/ReglaAreaProcesoController.php @@ -11,7 +11,7 @@ use Illuminate\Support\Facades\DB; class ReglaAreaProcesoController extends Controller { -ion areasProcesos() + public function areasProcesos() { $areasProcesos = DB::table('area_proceso as ap') ->leftJoin('reglas_area_proceso as r', 'ap.id', '=', 'r.area_proceso_id') diff --git a/back/app/Http/Controllers/ExamenController.php b/back/app/Http/Controllers/ExamenController.php index 72abdbb..fc78ac4 100644 --- a/back/app/Http/Controllers/ExamenController.php +++ b/back/app/Http/Controllers/ExamenController.php @@ -431,7 +431,7 @@ public function iniciarExamen(Request $request) public function responderPregunta($preguntaAsignadaId, Request $request) { $request->validate([ - 'respuesta' => 'required|string' + 'respuesta' => 'nullable|string' ]); $preguntaAsignada = PreguntaAsignada::with(['examen', 'pregunta']) diff --git a/back/app/Models/PreguntaAsignada.php b/back/app/Models/PreguntaAsignada.php index 1124262..8862954 100644 --- a/back/app/Models/PreguntaAsignada.php +++ b/back/app/Models/PreguntaAsignada.php @@ -21,7 +21,7 @@ class PreguntaAsignada extends Model ]; protected $casts = [ - 'es_correcta' => 'boolean', + 'es_correcta' => 'integer', 'puntaje' => 'decimal:2' ]; diff --git a/back/app/Models/ResultadoExamen.php b/back/app/Models/ResultadoExamen.php new file mode 100644 index 0000000..d8c7ae9 --- /dev/null +++ b/back/app/Models/ResultadoExamen.php @@ -0,0 +1,37 @@ +belongsTo(Postulante::class); + } + + public function examen() + { + return $this->belongsTo(Examen::class); + } +} diff --git a/back/app/Services/ExamenService.php b/back/app/Services/ExamenService.php index daddafd..527df22 100644 --- a/back/app/Services/ExamenService.php +++ b/back/app/Services/ExamenService.php @@ -115,29 +115,49 @@ public function obtenerPreguntasExamen(Examen $examen): array - public function guardarRespuesta(PreguntaAsignada $pa, string $respuesta): array - { - if ($pa->estado === 'respondida') { - return ['success' => false, 'message' => 'Ya respondida']; - } +public function guardarRespuesta(PreguntaAsignada $pa, ?string $respuesta): array +{ + if ($pa->estado === 'respondida') { + return ['success' => false, 'message' => 'Ya respondida']; + } - $esCorrecta = $respuesta === $pa->pregunta->respuesta_correcta; + // 🔹 Si está en blanco + if (empty($respuesta)) { $pa->update([ - 'respuesta_usuario' => $respuesta, - 'es_correcta' => $esCorrecta, - 'puntaje_obtenido' => $esCorrecta ? $pa->puntaje_base : 0, + 'respuesta_usuario' => null, + 'es_correcta' => 2, // 2 = blanco + 'puntaje_obtenido' => 0, 'estado' => 'respondida', 'respondida_at' => now() ]); return [ 'success' => true, - 'correcta' => $esCorrecta, - 'puntaje' => $pa->puntaje_obtenido + 'correcta' => 2, + 'puntaje' => 0 ]; } + // 🔹 Si respondió algo + $esCorrecta = $respuesta === $pa->pregunta->respuesta_correcta; + + $pa->update([ + 'respuesta_usuario' => $respuesta, + 'es_correcta' => $esCorrecta ? 1 : 0, + 'puntaje_obtenido' => $esCorrecta ? $pa->puntaje_base : 0, + 'estado' => 'respondida', + 'respondida_at' => now() + ]); + + return [ + 'success' => true, + 'correcta' => $esCorrecta ? 1 : 0, + 'puntaje' => $pa->puntaje_obtenido + ]; +} + + /** * Finalizar examen */ diff --git a/back/routes/api.php b/back/routes/api.php index c62b744..9d84758 100644 --- a/back/routes/api.php +++ b/back/routes/api.php @@ -6,7 +6,6 @@ use App\Http\Controllers\AuthController; use App\Http\Controllers\AcademiaController; use App\Http\Controllers\VinculacionController; use App\Http\Controllers\Administracion\administradorController; -use App\Http\Controllers\Administracion\ExamenesController; use App\Http\Controllers\Administracion\AreaController; use App\Http\Controllers\Administracion\CursoController; use App\Http\Controllers\Administracion\PreguntaController; @@ -16,8 +15,11 @@ use App\Http\Controllers\ExamenController; use App\Http\Controllers\Administracion\ReglaAreaProcesoController; use App\Http\Controllers\Administracion\ProcesoAdmisionController; use App\Http\Controllers\Administracion\ProcesoAdmisionDetalleController; +use App\Http\Controllers\Administracion\PostulanteController; + use App\Http\Administracion\CalificacionController; use App\Models\ProcesoAdmisionDetalle; + Route::get('/user', function (Request $request) { return $request->user(); })->middleware('auth:sanctum'); @@ -74,6 +76,14 @@ Route::middleware(['auth:sanctum'])->prefix('admin')->group(function () { }); +Route::middleware(['auth:sanctum'])->prefix('admin')->group(function () { + + Route::get('/postulantes', [PostulanteController::class, 'obtenerPostulantes']); + Route::put('/postulantes/{id}', [PostulanteController::class, 'actualizarPostulante']); +}); + + + Route::middleware(['auth:sanctum'])->prefix('admin')->group(function () { @@ -85,6 +95,17 @@ Route::middleware(['auth:sanctum'])->prefix('admin')->group(function () { }); +Route::middleware('auth:sanctum')->group(function () { + + + Route::get('/calificaciones', [CalificacionController::class, 'index']); + Route::post('/calificaciones', [CalificacionController::class, 'store']); + Route::get('/calificaciones/{id}', [CalificacionController::class, 'show']); + Route::put('/calificaciones/{id}', [CalificacionController::class, 'update']); + Route::delete('/calificaciones/{id}', [CalificacionController::class, 'destroy']); + +}); + Route::prefix('postulante')->group(function () { diff --git a/front/src/router/index.js b/front/src/router/index.js index 5e8a0ac..d5fb3ac 100644 --- a/front/src/router/index.js +++ b/front/src/router/index.js @@ -127,6 +127,17 @@ const routes = [ path: '/admin/dashboard/procesos/:id/detalles', name: 'ProcesoAdmisionDetalles', component: () => import('../views/administrador/procesoadmision/ProcesoAdmisionDetalles.vue') + }, + { + path: '/admin/dashboard/lista-calificacion', + name: 'CalificacionList', + component: () => import('../views/administrador/Procesos/CalificacionTest.vue') + }, + + { + path: '/admin/dashboard/lista-postulantes', + name: 'PostulantesList', + component: () => import('../views/administrador/estudiantes/ListPostulantes.vue') } ] }, diff --git a/front/src/store/examen.store.js b/front/src/store/examen.store.js index c8769d0..28c0c3c 100644 --- a/front/src/store/examen.store.js +++ b/front/src/store/examen.store.js @@ -12,17 +12,23 @@ export const useExamenStore = defineStore('examenStore', { error: null, }), actions: { - async fetchProcesos() { - try { - this.cargando = true - const { data } = await api.get('/examen/procesos') - this.procesos = data - } catch (e) { - this.error = e.response?.data?.message || e.message - } finally { - this.cargando = false - } - }, + async fetchProcesos() { + try { + this.cargando = true + const { data } = await api.get('/examen/procesos') + + // ✅ normaliza + this.procesos = (data || []).map(p => ({ + ...p, + requiere_pago: p.requiere_pago === 1 || p.requiere_pago === '1' || p.requiere_pago === true + })) + } catch (e) { + this.error = e.response?.data?.message || e.message + } finally { + this.cargando = false + } + }, + async fetchAreas(proceso_id) { try { @@ -95,17 +101,29 @@ export const useExamenStore = defineStore('examenStore', { }, - async responderPregunta(preguntaId, respuesta) { - try { - const { data } = await api.post(`/examen/pregunta/${preguntaId}/responder`, { respuesta }) - const index = this.preguntas.findIndex(p => p.id === preguntaId) - if (index !== -1) this.preguntas[index].respuesta = respuesta - return data - } catch (e) { - this.error = e.response?.data?.message || e.message - return { success: false, message: this.error } - } - }, +async responderPregunta(preguntaId, respuesta) { + try { + const { data } = await api.post( + `/examen/pregunta/${preguntaId}/responder`, + { respuesta } + ) + + const index = this.preguntas.findIndex(p => p.id === preguntaId) + + if (index !== -1 && data.success) { + this.preguntas[index].respuesta = respuesta + this.preguntas[index].es_correcta = data.correcta // 1, 0 o 2 + this.preguntas[index].puntaje = data.puntaje + } + + return data + + } catch (e) { + this.error = e.response?.data?.message || e.message + return { success: false, message: this.error } + } +}, + async finalizarExamen(examenId) { try { diff --git a/front/src/views/administrador/Procesos/CalificacionTest.vue b/front/src/views/administrador/Procesos/CalificacionTest.vue new file mode 100644 index 0000000..1c91c58 --- /dev/null +++ b/front/src/views/administrador/Procesos/CalificacionTest.vue @@ -0,0 +1,181 @@ + + + + + diff --git a/front/src/views/administrador/estudiantes/ListPostulantes.vue b/front/src/views/administrador/estudiantes/ListPostulantes.vue new file mode 100644 index 0000000..79a10db --- /dev/null +++ b/front/src/views/administrador/estudiantes/ListPostulantes.vue @@ -0,0 +1,201 @@ + + + + + diff --git a/front/src/views/administrador/layout/layout.vue b/front/src/views/administrador/layout/layout.vue index 2da78ef..765ae5d 100644 --- a/front/src/views/administrador/layout/layout.vue +++ b/front/src/views/administrador/layout/layout.vue @@ -24,9 +24,8 @@ - +
-
@@ -138,8 +137,7 @@ Dashboard
- - + @@ -199,6 +197,12 @@ Reglas
+ + + @@ -413,14 +417,13 @@ const handleMenuSelect = ({ key }) => { const routes = { 'dashboard': { name: 'Dashboard' }, - 'estudiantes-lista': { name: 'AcademiaEstudiantes' }, - 'estudiantes-nuevo': { name: 'AcademiaEstudianteNuevo' }, + 'estudiantes-lista': { name: 'PostulantesList' }, + 'examenes-calificaciones-lista': { name: 'CalificacionList' }, 'examenes-proceso-lista': { name: 'Procesos' }, 'examenes-area-lista': { name: 'Areas' }, 'examenes-curso-lista': { name: 'Cursos' }, 'examenes-reglas-lista': { name: 'Reglas' }, - 'procesos-lista': { name: 'ProcesosAdmisionList' }, 'lista-cursos': { name: 'AcademiaCursos' }, 'resultados': { name: 'AcademiaResultados' }, diff --git a/front/src/views/postulante/Dashboard.vue b/front/src/views/postulante/Dashboard.vue index 27add32..6e9ddf4 100644 --- a/front/src/views/postulante/Dashboard.vue +++ b/front/src/views/postulante/Dashboard.vue @@ -1,6 +1,185 @@ + + + -