diff --git a/back/app/Http/Controllers/Administracion/NoticiaController.php b/back/app/Http/Controllers/Administracion/NoticiaController.php new file mode 100644 index 0000000..d7aa0ef --- /dev/null +++ b/back/app/Http/Controllers/Administracion/NoticiaController.php @@ -0,0 +1,183 @@ +get('per_page', 9); + + $query = Noticia::query(); + + // filtros opcionales + if ($request->filled('publicado')) { + $query->where('publicado', $request->boolean('publicado')); + } + + if ($request->filled('categoria')) { + $query->where('categoria', $request->string('categoria')); + } + + if ($request->filled('q')) { + $q = trim((string) $request->get('q')); + $query->where(function ($sub) use ($q) { + $sub->where('titulo', 'like', "%{$q}%") + ->orWhere('descripcion_corta', 'like', "%{$q}%"); + }); + } + + $data = $query + ->orderByDesc('destacado') + ->orderByDesc('fecha_publicacion') + ->orderByDesc('orden') + ->orderByDesc('id') + ->paginate($perPage); + + return response()->json([ + 'success' => true, + 'data' => $data->items(), + 'meta' => [ + 'current_page' => $data->currentPage(), + 'last_page' => $data->lastPage(), + 'per_page' => $data->perPage(), + 'total' => $data->total(), + ], + ]); + } + + // GET /api/noticias/{noticia} + public function show(Noticia $noticia) + { + return response()->json([ + 'success' => true, + 'data' => $noticia, + ]); + } + // GET /api/noticias/{noticia} +public function showPublic(Noticia $noticia) +{ + abort_unless($noticia->publicado, 404); + + return response()->json([ + 'success' => true, + 'data' => $noticia, + ]); +} + + + // POST /api/noticias (multipart/form-data si viene imagen) + public function store(Request $request) + { + $data = $request->validate([ + 'titulo' => ['required', 'string', 'max:220'], + 'slug' => ['nullable', 'string', 'max:260', 'unique:noticias,slug'], + 'descripcion_corta' => ['nullable', 'string', 'max:500'], + 'contenido' => ['nullable', 'string'], + 'categoria' => ['nullable', 'string', 'max:80'], + 'tag_color' => ['nullable', 'string', 'max:30'], + 'imagen' => ['nullable', 'file', 'mimes:jpg,jpeg,png,webp', 'max:4096'], + 'imagen_path' => ['nullable', 'string', 'max:255'], + 'link_url' => ['nullable', 'string', 'max:600'], + 'link_texto' => ['nullable', 'string', 'max:120'], + 'fecha_publicacion' => ['nullable', 'date'], + 'publicado' => ['nullable', 'boolean'], + 'destacado' => ['nullable', 'boolean'], + 'orden' => ['nullable', 'integer'], + ]); + + // slug por defecto + if (empty($data['slug'])) { + $data['slug'] = Str::slug($data['titulo']); + } + + // subir imagen si viene + if ($request->hasFile('imagen')) { + $path = $request->file('imagen')->store('noticias', 'public'); + $data['imagen_path'] = $path; + } + + // si publican sin fecha, poner ahora + if (!empty($data['publicado']) && empty($data['fecha_publicacion'])) { + $data['fecha_publicacion'] = now(); + } + + $noticia = Noticia::create($data); + + return response()->json([ + 'success' => true, + 'data' => $noticia, + ], 201); + } + + // PUT/PATCH /api/noticias/{noticia} + public function update(Request $request, Noticia $noticia) + { + $data = $request->validate([ + 'titulo' => ['sometimes', 'required', 'string', 'max:220'], + 'slug' => ['sometimes', 'nullable', 'string', 'max:260', 'unique:noticias,slug,' . $noticia->id], + 'descripcion_corta' => ['sometimes', 'nullable', 'string', 'max:500'], + 'contenido' => ['sometimes', 'nullable', 'string'], + 'categoria' => ['sometimes', 'nullable', 'string', 'max:80'], + 'tag_color' => ['sometimes', 'nullable', 'string', 'max:30'], + 'imagen' => ['sometimes', 'nullable', 'file', 'mimes:jpg,jpeg,png,webp', 'max:4096'], + 'imagen_path' => ['sometimes', 'nullable', 'string', 'max:255'], + 'link_url' => ['sometimes', 'nullable', 'string', 'max:600'], + 'link_texto' => ['sometimes', 'nullable', 'string', 'max:120'], + 'fecha_publicacion' => ['sometimes', 'nullable', 'date'], + 'publicado' => ['sometimes', 'boolean'], + 'destacado' => ['sometimes', 'boolean'], + 'orden' => ['sometimes', 'integer'], + ]); + + // si llega imagen, reemplazar + if ($request->hasFile('imagen')) { + if ($noticia->imagen_path && Storage::disk('public')->exists($noticia->imagen_path)) { + Storage::disk('public')->delete($noticia->imagen_path); + } + $path = $request->file('imagen')->store('noticias', 'public'); + $data['imagen_path'] = $path; + } + + // si se marca publicado y no hay fecha, set now + if (array_key_exists('publicado', $data) && $data['publicado'] && empty($noticia->fecha_publicacion) && empty($data['fecha_publicacion'])) { + $data['fecha_publicacion'] = now(); + } + + // si cambian titulo y slug no vino, regenerar slug (opcional) + if (array_key_exists('titulo', $data) && !array_key_exists('slug', $data)) { + $data['slug'] = Str::slug($data['titulo']); + } + + $noticia->update($data); + + return response()->json([ + 'success' => true, + 'data' => $noticia->fresh(), + ]); + } + + // DELETE /api/noticias/{noticia} + public function destroy(Noticia $noticia) + { + // opcional: borrar imagen al eliminar + if ($noticia->imagen_path && Storage::disk('public')->exists($noticia->imagen_path)) { + Storage::disk('public')->delete($noticia->imagen_path); + } + + $noticia->delete(); + + return response()->json([ + 'success' => true, + 'message' => 'Noticia eliminada correctamente', + ]); + } +} diff --git a/back/app/Http/Controllers/Administracion/ProcesoAdmisionDetalleController.php b/back/app/Http/Controllers/Administracion/ProcesoAdmisionDetalleController.php index 1b24b87..1ab61fb 100644 --- a/back/app/Http/Controllers/Administracion/ProcesoAdmisionDetalleController.php +++ b/back/app/Http/Controllers/Administracion/ProcesoAdmisionDetalleController.php @@ -30,6 +30,22 @@ class ProcesoAdmisionDetalleController extends Controller { ProcesoAdmision::findOrFail($procesoId); + // ✅ Convertir JSON string -> array antes de validar (cuando llega desde FormData) + if ($request->has('listas') && is_string($request->input('listas'))) { + $decoded = json_decode($request->input('listas'), true); + if (json_last_error() === JSON_ERROR_NONE) { + $request->merge(['listas' => $decoded]); + } + } + + if ($request->has('meta') && is_string($request->input('meta'))) { + $decoded = json_decode($request->input('meta'), true); + if (json_last_error() === JSON_ERROR_NONE) { + $request->merge(['meta' => $decoded]); + } + } + + $data = $request->validate([ 'tipo' => ['required', Rule::in(['requisitos','pagos','vacantes','cronograma'])], 'titulo_detalle' => ['required','string','max:255'], @@ -69,6 +85,22 @@ class ProcesoAdmisionDetalleController extends Controller { $detalle = ProcesoAdmisionDetalle::findOrFail($id); + // ✅ Convertir JSON string -> array antes de validar (cuando llega desde FormData) + if ($request->has('listas') && is_string($request->input('listas'))) { + $decoded = json_decode($request->input('listas'), true); + if (json_last_error() === JSON_ERROR_NONE) { + $request->merge(['listas' => $decoded]); + } + } + + if ($request->has('meta') && is_string($request->input('meta'))) { + $decoded = json_decode($request->input('meta'), true); + if (json_last_error() === JSON_ERROR_NONE) { + $request->merge(['meta' => $decoded]); + } + } + + $data = $request->validate([ 'tipo' => ['sometimes', Rule::in(['requisitos','pagos','vacantes','cronograma'])], 'titulo_detalle' => ['sometimes','string','max:255'], diff --git a/back/app/Http/Controllers/Controller.php b/back/app/Http/Controllers/Controller.php index 8677cd5..38bdf98 100644 --- a/back/app/Http/Controllers/Controller.php +++ b/back/app/Http/Controllers/Controller.php @@ -4,5 +4,5 @@ namespace App\Http\Controllers; abstract class Controller { - // + } diff --git a/back/app/Http/Controllers/ExamenController.php b/back/app/Http/Controllers/ExamenController.php index fc78ac4..ec76c9b 100644 --- a/back/app/Http/Controllers/ExamenController.php +++ b/back/app/Http/Controllers/ExamenController.php @@ -21,6 +21,7 @@ use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Http; use App\Services\ExamenService; +use Illuminate\Support\Facades\DB; class ExamenController extends Controller { @@ -454,19 +455,34 @@ public function iniciarExamen(Request $request) } + public function finalizarExamen($examenId) { $examen = Examen::findOrFail($examenId); $postulante = request()->user(); - if ($examen->postulante_id !== $postulante->id) { + + // Validar que el examen le pertenezca al postulante autenticado + if ((int) $examen->postulante_id !== (int) $postulante->id) { return response()->json([ 'success' => false, 'message' => 'No autorizado' ], 403); } - $this->examenService->finalizarExamen($examen); + // (Opcional) Evitar finalizar 2 veces + if ($examen->estado === 'finalizado') { + return response()->json([ + 'success' => false, + 'message' => 'El examen ya está finalizado' + ], 409); + } + + // Finalizar examen + $examen->update([ + 'estado' => 'finalizado', + 'hora_fin' => now(), + ]); return response()->json([ 'success' => true, @@ -475,4 +491,256 @@ public function iniciarExamen(Request $request) } + + public function calificarExamen($examenId, Request $request) + { + $postulante = $request->user(); + if (!$postulante) { + return response()->json(['success' => false, 'mensaje' => 'No autenticado.'], 401); + } + + return DB::transaction(function () use ($examenId, $postulante) { + + // 1) Validar examen del postulante + $examen = DB::table('examenes') + ->where('id', $examenId) + ->where('postulante_id', $postulante->id) + ->first(); + + if (!$examen) { + return response()->json([ + 'success' => false, + 'mensaje' => 'No se encontró un examen para este postulante.' + ], 404); + } + + // 2) Si ya está calificado, devolver existente (y opcionalmente recalcular orden) + $existente = DB::table('resultados_examenes') + ->where('examen_id', $examen->id) + ->first(); + + if ($existente) { + // Obtener proceso_id para poder recalcular si deseas (opcional) + $procesoId = DB::table('area_proceso') + ->where('id', $examen->area_proceso_id) + ->value('proceso_id'); + + + if ($procesoId) $this->recalcularOrdenMerito($procesoId); + + return response()->json([ + 'success' => true, + 'mensaje' => 'Examen ya calificado.', + 'total_puntos' => (float)$existente->total_puntos, + 'total_correctas' => (int)$existente->total_correctas, + 'total_incorrectas' => (int)$existente->total_incorrectas, + 'total_nulas' => (int)$existente->total_nulas, + 'porcentaje_correctas' => (float)$existente->porcentaje_correctas, + 'calificacion_sobre_20' => (float)$existente->calificacion_sobre_20, + 'orden_merito' => $existente->orden_merito, + 'correctas_por_curso' => json_decode($existente->correctas_por_curso, true), + 'incorrectas_por_curso' => json_decode($existente->incorrectas_por_curso ?? '[]', true), + 'preguntas_totales_por_curso' => json_decode($existente->preguntas_totales_por_curso ?? '[]', true), + ]); + } + + // 3) Obtener configuración de calificación desde proceso -> calificaciones + $cfg = DB::table('area_proceso as ap') + ->join('procesos as pr', 'pr.id', '=', 'ap.proceso_id') + ->join('calificaciones as ca', 'ca.id', '=', 'pr.calificacion_id') + ->where('ap.id', $examen->area_proceso_id) + ->select( + 'pr.id as proceso_id', + 'ca.puntos_correcta', + 'ca.puntos_incorrecta', + 'ca.puntos_nula', + 'ca.puntaje_maximo' + ) + ->first(); + + if (!$cfg) { + return response()->json([ + 'success' => false, + 'mensaje' => 'No se ha definido un tipo de calificación para este proceso.' + ], 400); + } + + $puntosCorrecta = (float) $cfg->puntos_correcta; + $puntosIncorrecta = (float) $cfg->puntos_incorrecta; + $puntosNula = (float) $cfg->puntos_nula; + $puntajeMaximo = (float) $cfg->puntaje_maximo; + + // 4) Traer preguntas asignadas con su pregunta y curso + $items = DB::table('preguntas_asignadas as pa') + ->join('preguntas as p', 'p.id', '=', 'pa.pregunta_id') + ->join('cursos as c', 'c.id', '=', 'p.curso_id') + ->where('pa.examen_id', $examen->id) + ->select( + 'pa.id as pa_id', + 'pa.estado as pa_estado', + 'pa.respuesta_usuario', + 'p.respuesta_correcta', + 'c.nombre as curso_nombre' + ) + ->get(); + + if ($items->isEmpty()) { + return response()->json([ + 'success' => false, + 'mensaje' => 'El examen no tiene preguntas asignadas.' + ], 422); + } + + // 5) Calificar y actualizar cada pregunta_asignada + $totalPuntos = 0.0; + $totalCorrectas = 0; + $totalIncorrectas = 0; + $totalNulas = 0; + + $correctasPorCurso = []; + $incorrectasPorCurso = []; + $preguntasTotalesPorCurso = []; + + foreach ($items as $row) { + $curso = $row->curso_nombre; + + $preguntasTotalesPorCurso[$curso] = ($preguntasTotalesPorCurso[$curso] ?? 0) + 1; + $correctasPorCurso[$curso] = $correctasPorCurso[$curso] ?? 0; + $incorrectasPorCurso[$curso] = $incorrectasPorCurso[$curso] ?? 0; + + $nuevoEsCorrecta = 2; // 2 = blanco + $nuevoPuntaje = $puntosNula; // nula/blanco + + if ($row->pa_estado === 'anulada') { + // anulada => nula + $nuevoEsCorrecta = 2; + $nuevoPuntaje = $puntosNula; + $totalNulas++; + } else { + $ru = trim((string) $row->respuesta_usuario); + $rc = trim((string) $row->respuesta_correcta); + + if ($ru === '') { + // blanco + $nuevoEsCorrecta = 2; + $nuevoPuntaje = $puntosNula; + $totalNulas++; + } else { + $ruN = mb_strtoupper($ru); + $rcN = mb_strtoupper($rc); + + if ($rcN !== '' && $ruN === $rcN) { + $nuevoEsCorrecta = 1; + $nuevoPuntaje = $puntosCorrecta; + $totalCorrectas++; + $correctasPorCurso[$curso]++; + } else { + $nuevoEsCorrecta = 0; + $nuevoPuntaje = $puntosIncorrecta; + $totalIncorrectas++; + $incorrectasPorCurso[$curso]++; + } + } + } + + $totalPuntos += (float) $nuevoPuntaje; + + DB::table('preguntas_asignadas') + ->where('id', $row->pa_id) + ->update([ + 'es_correcta' => $nuevoEsCorrecta, + 'puntaje' => $nuevoPuntaje, + 'updated_at' => now(), + ]); + } + + // 6) Resumen + $totalPreguntas = (int) $items->count(); + $porcentajeCorrectas = $totalPreguntas > 0 ? ($totalCorrectas / $totalPreguntas) * 100 : 0; + + $calificacionSobre20 = ($puntajeMaximo > 0) + ? ($totalPuntos / $puntajeMaximo) * 20 + : 0; + + $correctasPorCursoFormato = []; + foreach ($correctasPorCurso as $curso => $corr) { + $y = $preguntasTotalesPorCurso[$curso] ?? 0; + $correctasPorCursoFormato[$curso] = "{$corr} de {$y}"; + } + + // 7) Guardar resultado en resultados_examenes + $resultadoId = DB::table('resultados_examenes')->insertGetId([ + 'postulante_id' => $postulante->id, + 'examen_id' => $examen->id, + 'total_puntos' => round($totalPuntos, 3), + 'correctas_por_curso' => json_encode($correctasPorCursoFormato), + 'incorrectas_por_curso' => json_encode($incorrectasPorCurso), + 'preguntas_totales_por_curso' => json_encode($preguntasTotalesPorCurso), + 'total_correctas' => $totalCorrectas, + 'total_incorrectas' => $totalIncorrectas, + 'total_nulas' => $totalNulas, + 'porcentaje_correctas' => round($porcentajeCorrectas, 2), + 'calificacion_sobre_20' => round($calificacionSobre20, 2), + 'created_at' => now(), + 'updated_at' => now(), + ]); + + // 8) Recalcular orden de mérito por proceso + $this->recalcularOrdenMerito($cfg->proceso_id); + + // 9) Leer orden_merito ya asignado (opcional) + $orden = DB::table('resultados_examenes')->where('id', $resultadoId)->value('orden_merito'); + + DB::table('examenes')->where('id', $examen->id)->update([ + 'estado' => 'calificado', + 'hora_fin' => now(), + ]); + return response()->json([ + 'success' => true, + 'mensaje' => 'Examen calificado exitosamente.', + 'examen_id' => $examen->id, + 'proceso_id' => $cfg->proceso_id, + + 'total_puntos' => round($totalPuntos, 2), + 'total_correctas' => $totalCorrectas, + 'total_incorrectas' => $totalIncorrectas, + 'total_nulas' => $totalNulas, + + 'porcentaje_correctas' => round($porcentajeCorrectas, 2), + 'calificacion_sobre_20' => round($calificacionSobre20, 2), + 'orden_merito' => $orden, + + 'correctas_por_curso' => $correctasPorCursoFormato, + 'incorrectas_por_curso' => $incorrectasPorCurso, + 'preguntas_totales_por_curso' => $preguntasTotalesPorCurso, + ]); + }); + } + + + public function recalcularOrdenMerito($procesoId): void + { + DB::statement(" + UPDATE resultados_examenes r + JOIN ( + SELECT + r2.id, + ROW_NUMBER() OVER ( + ORDER BY + r2.total_puntos DESC, + COALESCE(r2.updated_at, r2.created_at) ASC + ) AS nuevo_orden + FROM resultados_examenes r2 + JOIN examenes e ON e.id = r2.examen_id + JOIN area_proceso ap ON ap.id = e.area_proceso_id + WHERE ap.proceso_id = ? + ) x ON x.id = r.id + SET r.orden_merito = x.nuevo_orden + ", [$procesoId]); + } + + + + + } \ No newline at end of file diff --git a/back/app/Http/Controllers/WebController.php b/back/app/Http/Controllers/WebController.php new file mode 100644 index 0000000..4a793b7 --- /dev/null +++ b/back/app/Http/Controllers/WebController.php @@ -0,0 +1,70 @@ +with([ + 'detalles' => function ($query) { + $query->select( + 'id', + 'proceso_admision_id', + 'tipo', + 'titulo_detalle', + 'descripcion', + 'listas', + 'meta', + 'url', + 'imagen_path', + 'imagen_path_2', + 'created_at', + 'updated_at' + ); + } + ]) + ->latest() // 🔥 Esto ordena por created_at DESC + ->get(); + + return response()->json([ + 'success' => true, + 'data' => $procesos + ]); +} + + +} diff --git a/back/app/Models/Examen.php b/back/app/Models/Examen.php index 1a18ae5..9aaf09e 100644 --- a/back/app/Models/Examen.php +++ b/back/app/Models/Examen.php @@ -11,15 +11,22 @@ class Examen extends Model protected $table = 'examenes'; - protected $fillable = [ + protected $fillable = [ 'postulante_id', 'area_proceso_id', - 'pagado', - 'tipo_pago', - 'pago_id', + 'pagado', + 'tipo_pago', + 'pago_id', 'intentos', 'hora_inicio', - + 'estado', + 'hora_fin', + ]; + + protected $casts = [ + 'pagado' => 'boolean', + 'hora_inicio' => 'datetime', + 'hora_fin' => 'datetime', ]; public function postulante() diff --git a/back/app/Models/Noticia.php b/back/app/Models/Noticia.php new file mode 100644 index 0000000..e748d96 --- /dev/null +++ b/back/app/Models/Noticia.php @@ -0,0 +1,55 @@ + 'datetime', + 'publicado' => 'boolean', + 'destacado' => 'boolean', + 'orden' => 'integer', + ]; + + protected $appends = ['imagen_url']; + + public function getImagenUrlAttribute(): ?string + { + if (!$this->imagen_path) return null; + return asset('storage/' . ltrim($this->imagen_path, '/')); + } + + // Auto-generar slug si no viene + protected static function booted(): void + { + static::saving(function (Noticia $noticia) { + if (!$noticia->slug) { + $noticia->slug = Str::slug($noticia->titulo); + } + }); + } +} diff --git a/back/app/Models/ProcesoAdmision.php b/back/app/Models/ProcesoAdmision.php index 4c4af06..106c862 100644 --- a/back/app/Models/ProcesoAdmision.php +++ b/back/app/Models/ProcesoAdmision.php @@ -65,5 +65,7 @@ class ProcesoAdmision extends Model { return $this->hasMany(ResultadoAdmision::class, 'idproceso'); } + + } diff --git a/back/app/Services/ExamenService.php b/back/app/Services/ExamenService.php index 527df22..0c99677 100644 --- a/back/app/Services/ExamenService.php +++ b/back/app/Services/ExamenService.php @@ -158,16 +158,6 @@ public function guardarRespuesta(PreguntaAsignada $pa, ?string $respuesta): arra } - /** - * Finalizar examen - */ - public function finalizarExamen(Examen $examen): void - { - $examen->update([ - 'estado' => 'finalizado', - 'hora_fin' => now() - ]); - } private function mezclarOpciones(?array $opciones): array { diff --git a/back/routes/api.php b/back/routes/api.php index 9d84758..e820897 100644 --- a/back/routes/api.php +++ b/back/routes/api.php @@ -16,9 +16,9 @@ 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; - +use App\Http\Controllers\Administracion\CalificacionController; +use App\Http\Controllers\Administracion\NoticiaController; +use App\Http\Controllers\WebController; Route::get('/user', function (Request $request) { return $request->user(); @@ -65,6 +65,22 @@ Route::middleware(['auth:sanctum'])->prefix('admin')->group(function () { }); +Route::middleware(['auth:sanctum'])->prefix('admin')->group(function () { + + // NOTICIAS + Route::get('/noticias', [NoticiaController::class, 'index']); + Route::get('/noticias/{noticia}', [NoticiaController::class, 'show']); + + Route::post('/noticias', [NoticiaController::class, 'store']); + + // usa SOLO UNA (PUT o PATCH). Aquí dejo PUT: + Route::put('/noticias/{noticia}', [NoticiaController::class, 'update']); + + Route::delete('/noticias/{noticia}', [NoticiaController::class, 'destroy']); +}); +Route::get('/noticias', [NoticiaController::class, 'index']); + Route::get('/noticias/{noticia}', [NoticiaController::class, 'showPublic']); + Route::middleware(['auth:sanctum'])->prefix('admin')->group(function () { Route::get('/cursos', [CursoController::class, 'index']); @@ -178,6 +194,7 @@ Route::middleware(['auth:postulante'])->group(function () { // Finalizar examen Route::post('/examen/{examen}/finalizar', [ExamenController::class, 'finalizarExamen']); + Route::post('/examen/{examenId}/calificar', [ExamenController::class, 'calificarExamen']); }); @@ -203,4 +220,8 @@ Route::middleware('auth:sanctum')->prefix('admin')->group(function () { Route::match(['put','patch'], '/{id}', [ProcesoAdmisionDetalleController::class, 'update'])->name('update'); Route::delete('/{id}', [ProcesoAdmisionDetalleController::class, 'destroy'])->name('destroy'); }); - }); \ No newline at end of file + }); + + + +Route::get('/procesos-admision', [WebController::class, 'GetProcesoAdmision']); diff --git a/front/src/components/WebPage.vue b/front/src/components/WebPage.vue index 61bd441..fb08d37 100644 --- a/front/src/components/WebPage.vue +++ b/front/src/components/WebPage.vue @@ -9,27 +9,18 @@ - + - + - + - - @@ -50,168 +41,9 @@ import StatsSection from './WebPageSections/StatsSection.vue' import NoticiasSection from './WebPageSections/NoticiasSection.vue' import ModalidadesSection from './WebPageSections/ModalidadesSection.vue' import ContactSection from './WebPageSections/ContactSection.vue' -import PreinscripcionModal from './WebPageSections//modal/PreinscripcionModal.vue' - - -import { - MedicineBoxOutlined, - BuildOutlined, - CodeOutlined, - BookOutlined, - TrophyOutlined, - BankOutlined, - ExperimentOutlined, - UserOutlined, -} from "@ant-design/icons-vue" - -const preinscripcionModalVisible = ref(false) - -const facultades = [ - { - id: "1", - nombre: "Ciencias de la Salud", - carreras: [ - { - id: 1, - nombre: "Medicina Humana", - grado: "Bachiller", - descripcion: "Formación médica integral con prácticas desde primer año", - vacantes: 50, - puntaje: "1800+", - icono: markRaw(MedicineBoxOutlined), - }, - { - id: 2, - nombre: "Enfermería", - grado: "Bachiller", - descripcion: "Cuidado integral de la salud", - vacantes: 60, - puntaje: "1500+", - icono: markRaw(UserOutlined), - }, - ], - }, - { - id: "2", - nombre: "Ingenierías", - carreras: [ - { - id: 3, - nombre: "Ingeniería Civil", - grado: "Bachiller", - descripcion: "Diseño y construcción de infraestructura", - vacantes: 80, - puntaje: "1700+", - icono: markRaw(BuildOutlined), - }, - { - id: 4, - nombre: "Ingeniería de Sistemas", - grado: "Bachiller", - descripcion: "Desarrollo de software e inteligencia artificial", - vacantes: 100, - puntaje: "1600+", - icono: markRaw(CodeOutlined), - }, - ], - }, - { - id: "3", - nombre: "Derecho y Humanidades", - carreras: [ - { - id: 5, - nombre: "Derecho", - grado: "Bachiller", - descripcion: "Formación jurídica integral", - vacantes: 120, - puntaje: "1550+", - icono: markRaw(BookOutlined), - }, - { - id: 6, - nombre: "Psicología", - grado: "Bachiller", - descripcion: "Ciencias del comportamiento humano", - vacantes: 70, - puntaje: "1450+", - icono: markRaw(UserOutlined), - }, - ], - }, -] - -const modalidades = [ - { - id: 1, - nombre: "Admisión Ordinaria", - descripcion: "Examen de conocimientos generales", - estado: "Abierto", - estadoColor: "success", - color: "#1890ff", - icono: markRaw(BookOutlined), - }, - { - id: 2, - nombre: "Evaluación de Talentos", - descripcion: "Para deportistas y artistas destacados", - estado: "Próximamente", - estadoColor: "orange", - color: "#faad14", - icono: markRaw(TrophyOutlined), - }, - { - id: 3, - nombre: "Traslado Externo", - descripcion: "Estudiantes de otras universidades", - estado: "Cerrado", - estadoColor: "red", - color: "#ff4d4f", - icono: markRaw(BankOutlined), - }, - { - id: 4, - nombre: "Segunda Carrera", - descripcion: "Para profesionales graduados", - estado: "Abierto", - estadoColor: "success", - color: "#52c41a", - icono: markRaw(ExperimentOutlined), - }, -] - -const noticias = [ - { - id: 1, - titulo: "Nuevo Laboratorio de Investigación", - descripcion: "Inauguramos el moderno laboratorio de ciencias con tecnología de punta.", - fecha: "15 Nov 2023", - categoria: "Infraestructura", - tagColor: "blue", - imagen: - "https://images.unsplash.com/photo-1532094349884-543bc11b234d?auto=format&fit=crop&w=600&q=80", - }, - { - id: 2, - titulo: "Convenio Internacional", - descripcion: "Firmamos acuerdo con universidad europea para intercambio estudiantil.", - fecha: "10 Nov 2023", - categoria: "Internacional", - tagColor: "green", - imagen: - "https://images.unsplash.com/photo-1523050854058-8df90110c9f1?auto=format&fit=crop&w=600&q=80", - }, - { - id: 3, - titulo: "Resultados Publicados", - descripcion: "Consulta los resultados del examen de admisión extraordinario.", - fecha: "5 Nov 2023", - categoria: "Resultados", - tagColor: "red", - imagen: - "https://images.unsplash.com/photo-1562774053-701939374585?auto=format&fit=crop&w=600&q=80", - }, -] + + + const scrollToConvocatoria = () => { const el = document.getElementById("convocatorias") @@ -223,18 +55,6 @@ const openVirtualTour = () => { window.open("https://example.com", "_blank", "noopener,noreferrer") } -const openPreinscripcion = () => { - preinscripcionModalVisible.value = true -} - -const showModal = (type) => { - console.log("Mostrar modal:", type) -} - -const submitPreinscripcion = () => { - message.success("Preinscripción iniciada exitosamente") - preinscripcionModalVisible.value = false -} \ No newline at end of file + diff --git a/front/src/components/WebPageSections/NoticiasSection.vue b/front/src/components/WebPageSections/NoticiasSection.vue index 2fe7c3c..7dca6f2 100644 --- a/front/src/components/WebPageSections/NoticiasSection.vue +++ b/front/src/components/WebPageSections/NoticiasSection.vue @@ -1,7 +1,9 @@ +