3f48c0bc7c
- Mueve la ruta /storage/{path} fuera del middleware de auth para que
sea pública; necesario para que los servidores de WhatsApp y el navegador
puedan cargar imágenes de promociones sin autenticación
- Dockerfile: agrega 'rm -rf public/storage' antes de storage:link para
evitar que COPY copie la junction de Windows y deje el symlink roto en el contenedor
- Crea .dockerignore: excluye public/storage, .git, .env y artefactos de
build del contexto de Docker para builds más limpios y seguros
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
203 lines
13 KiB
PHP
203 lines
13 KiB
PHP
<?php
|
|
|
|
use App\Events\MessageSent;
|
|
use App\Http\Controllers\AlumnoController;
|
|
use App\Http\Controllers\AnuncioController;
|
|
use App\Http\Controllers\AreaCodeController;
|
|
use App\Http\Controllers\AreaController;
|
|
use App\Http\Controllers\CampanController;
|
|
use App\Http\Controllers\CarreraController;
|
|
use App\Http\Controllers\ChatController;
|
|
use App\Http\Controllers\FileController;
|
|
use App\Http\Controllers\FriendshipController;
|
|
use App\Http\Controllers\PostController;
|
|
use App\Http\Controllers\SocialProfileController;
|
|
use App\Http\Controllers\UserSearchController;
|
|
use App\Http\Controllers\CodeController;
|
|
use App\Http\Controllers\ConceptoController;
|
|
use App\Http\Controllers\DocenteController;
|
|
use App\Http\Controllers\EntregaController;
|
|
use App\Http\Controllers\EvaluacionController;
|
|
use App\Http\Controllers\EvaluacionReporteController;
|
|
use App\Http\Controllers\EvaluacionResponderController;
|
|
use App\Http\Controllers\TareaController;
|
|
use App\Http\Controllers\DocumentoController;
|
|
use App\Http\Controllers\DocumentoTipoController;
|
|
use App\Http\Controllers\DurationController;
|
|
use App\Http\Controllers\GrupoController;
|
|
use App\Http\Controllers\HorarioController;
|
|
use App\Http\Controllers\MailController;
|
|
use App\Http\Controllers\MaterialController;
|
|
use App\Http\Controllers\MedioController;
|
|
use App\Http\Controllers\NivelController;
|
|
use App\Http\Controllers\NoteController;
|
|
use App\Http\Controllers\PagoController;
|
|
use App\Http\Controllers\PermissionController;
|
|
use App\Http\Controllers\PlanController;
|
|
use App\Http\Controllers\PlaneController;
|
|
use App\Http\Controllers\PlantelController;
|
|
use App\Http\Controllers\PromocionController;
|
|
use App\Http\Controllers\RoleController;
|
|
use App\Http\Controllers\WhatsAppAnalyticsController;
|
|
use App\Http\Controllers\WhatsAppChatController;
|
|
use App\Http\Controllers\StripeWebhookController;
|
|
use App\Http\Controllers\TurnoController;
|
|
use App\Http\Controllers\UnsubscribeController;
|
|
use App\Http\Controllers\UserController;
|
|
use App\Models\Documento;
|
|
use Illuminate\Support\Facades\Route;
|
|
use Laravel\Jetstream\Http\Controllers\Livewire\UserProfileController;
|
|
|
|
Route::match(['GET','POST'],'/unsubscribe', [UnsubscribeController::class,'handle']);
|
|
|
|
Route::get('/',function(){return view('auth.login');});
|
|
Route::get('/prueba',function(){return view('prueba.index');});
|
|
Route::post('/stripe/webhook', [StripeWebhookController::class, 'handle']);
|
|
|
|
Route::get('/webhook/whatsapp', [\App\Http\Controllers\WhatsAppWebhookController::class, 'verify']);
|
|
Route::post('/webhook/whatsapp', [\App\Http\Controllers\WhatsAppWebhookController::class, 'handle'])
|
|
->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]);
|
|
|
|
Route::get('/storage/{path}', function (string $path) {
|
|
$fullPath = storage_path('app/public/' . $path);
|
|
abort_unless(file_exists($fullPath), 404);
|
|
return response()->file($fullPath);
|
|
})->where('path', '.*');
|
|
|
|
Route::middleware(['auth:sanctum',config('jetstream.auth_session'),'verified',
|
|
])->group(function () {
|
|
|
|
Route::middleware(['auth'])->group(function () {
|
|
Route::resource('/alumno',AlumnoController::class);
|
|
Route::resource('/area',AreaController::class);
|
|
Route::resource('/areacode',AreaCodeController::class);
|
|
Route::get('/dashboard', function () {
|
|
$user = auth()->user();
|
|
$roles = $user->getRoleNames()->toArray();
|
|
$anuncios = \App\Models\Anuncio::vigentes()->paraRoles($roles)->latest()->get();
|
|
return view('dashboard', compact('anuncios'));
|
|
})->name('dashboard');
|
|
Route::resource('/campan',CampanController::class);
|
|
Route::resource('/carrera',CarreraController::class);
|
|
Route::resource('/code',CodeController::class);
|
|
Route::resource('/concepto',ConceptoController::class);
|
|
Route::get('/chat', [ChatController::class, 'index'])->name('chat.index');
|
|
Route::get('/chat/{user}', [ChatController::class, 'show'])->name('chat.show');
|
|
Route::post('/chat/send', [ChatController::class, 'send'])->name('chat.send');
|
|
Route::get('/files/{path}', [FileController::class, 'serve'])->where('path', '.*')->name('files.serve');
|
|
Route::post('/notifications/{id}/read', fn($id) => auth()->user()->notifications()->findOrFail($id)->markAsRead())->name('notifications.read');
|
|
Route::post('/notifications/read-all', fn() => auth()->user()->unreadNotifications->markAsRead())->name('notifications.read-all');
|
|
|
|
// Social
|
|
Route::get('/feed', [PostController::class, 'index'])->name('feed');
|
|
Route::post('/feed', [PostController::class, 'store'])->name('posts.store');
|
|
Route::post('/posts/{post}/like', [PostController::class, 'like'])->name('posts.like');
|
|
Route::post('/posts/{post}/comments', [PostController::class, 'comment'])->name('posts.comment');
|
|
Route::delete('/posts/{post}', [PostController::class, 'destroy'])->name('posts.destroy');
|
|
|
|
Route::get('/friends', [FriendshipController::class, 'index'])->name('friendships.index');
|
|
Route::post('/friends/{user}/send', [FriendshipController::class, 'send'])->name('friendships.send');
|
|
Route::post('/friends/{friendship}/accept', [FriendshipController::class, 'accept'])->name('friendships.accept');
|
|
Route::delete('/friends/{friendship}', [FriendshipController::class, 'destroy'])->name('friendships.destroy');
|
|
Route::post('/friends/{user}/toggle', [FriendshipController::class, 'toggle'])->name('friendships.toggle');
|
|
|
|
Route::get('/search', UserSearchController::class)->name('users.search');
|
|
|
|
// Evaluaciones (administración)
|
|
Route::resource('/evaluacion', EvaluacionController::class);
|
|
Route::patch('/evaluacion/{evaluacion}/status', [EvaluacionController::class, 'toggleStatus'])->name('evaluacion.toggleStatus');
|
|
Route::get('/evaluacion/{evaluacion}/reporte', [EvaluacionReporteController::class, 'show'])->name('evaluacion.reporte.show');
|
|
Route::get('/evaluacion/{evaluacion}/reporte/pdf', [EvaluacionReporteController::class, 'pdf'])->name('evaluacion.reporte.pdf');
|
|
|
|
// Evaluaciones (responder — docentes y alumnos)
|
|
Route::get('/mis-evaluaciones', [EvaluacionResponderController::class, 'misEvaluaciones'])->name('evaluacion.mis_evaluaciones');
|
|
Route::get('/evaluacion/{evaluacion}/responder', [EvaluacionResponderController::class, 'show'])->name('evaluacion.responder.show');
|
|
Route::post('/evaluacion/{evaluacion}/responder', [EvaluacionResponderController::class, 'store'])->name('evaluacion.responder.store');
|
|
|
|
// Anuncios (gestión: solo Admin)
|
|
Route::resource('/anuncio', AnuncioController::class);
|
|
Route::patch('/anuncio/{anuncio}/toggle', [AnuncioController::class, 'toggleActive'])->name('anuncio.toggleActive');
|
|
Route::get('/perfil/{user}', [SocialProfileController::class, 'show'])->name('social.profile');
|
|
|
|
Route::resource('/docente',DocenteController::class);
|
|
Route::resource('/documento',DocumentoController::class);
|
|
Route::get('/documento/ver/{id}', function ($id) { $doc = Documento::findOrFail($id); $alumno = auth()->user()->alumnos()->first(); if (!$alumno || $doc->alumno_id !== $alumno->id) { abort(403); } return response()->file( storage_path('app/public/'.$doc->archivo) ); });
|
|
Route::get('/documento/ver/{id}', [DocumentoController::class, 'ver'])->name('documento.ver');
|
|
Route::resource('/documentoTipo',DocumentoTipoController::class);
|
|
Route::resource('/duration',DurationController::class);
|
|
Route::resource('/grupo', GrupoController::class);
|
|
Route::get('/grupo/{grupo}/administrar', [GrupoController::class, 'administrar'])->name('grupo.administrar');
|
|
Route::get('/grupo/{grupo}/ver-materias', [GrupoController::class, 'verMaterias'])->name('grupo.ver.materias');
|
|
|
|
// Tareas (docente)
|
|
Route::get('/grupo/{grupo}/material/{material}/tareas', [TareaController::class, 'index'])->name('grupo.material.tareas');
|
|
Route::get('/grupo/{grupo}/material/{material}/tareas/create', [TareaController::class, 'create'])->name('grupo.material.tareas.create');
|
|
Route::post('/grupo/{grupo}/material/{material}/tareas', [TareaController::class, 'store'])->name('grupo.material.tareas.store');
|
|
Route::get('/grupo/{grupo}/material/{material}/tareas/acta', [TareaController::class, 'acta'])->name('grupo.material.tareas.acta');
|
|
Route::get('/grupo/{grupo}/material/{material}/tareas/{tarea}', [TareaController::class, 'show'])->name('grupo.material.tareas.show');
|
|
Route::get('/grupo/{grupo}/material/{material}/tareas/{tarea}/edit', [TareaController::class, 'edit'])->name('grupo.material.tareas.edit');
|
|
Route::put('/grupo/{grupo}/material/{material}/tareas/{tarea}', [TareaController::class, 'update'])->name('grupo.material.tareas.update');
|
|
Route::delete('/grupo/{grupo}/material/{material}/tareas/{tarea}', [TareaController::class, 'destroy'])->name('grupo.material.tareas.destroy');
|
|
Route::post('/tareas/{tarea}/calificar/{alumno}', [TareaController::class, 'calificar'])->name('tarea.calificar');
|
|
|
|
// Entregas (alumno)
|
|
Route::get('/mis-tareas', [EntregaController::class, 'index'])->name('mis.tareas');
|
|
Route::post('/tareas/{tarea}/entregar', [EntregaController::class, 'store'])->name('tarea.entregar');
|
|
Route::get('/horario', [HorarioController::class, 'index'])->name('horario.index');
|
|
Route::get('/horario/create', [HorarioController::class, 'create'])->name('horario.create');
|
|
Route::post('/horario', [HorarioController::class, 'store'])->name('horario.store');
|
|
Route::get('/horario/{user}', [HorarioController::class, 'show'])->name('horario.show');
|
|
Route::get('/horario/{user}/edit', [HorarioController::class, 'edit'])->name('horario.edit');
|
|
Route::put('/horario/{user}', [HorarioController::class, 'update'])->name('horario.update');
|
|
Route::delete('/horario/{user}', [HorarioController::class, 'destroy'])->name('horario.destroy');
|
|
Route::resource('/material',MaterialController::class);
|
|
Route::resource('/medio',MedioController::class);
|
|
Route::resource('/nivel',NivelController::class);
|
|
Route::resource('/note',NoteController::class);
|
|
Route::resource('/pago',PagoController::class);
|
|
// Route::post('/pagar/{pago}', [StripeController::class, 'pagar'])->name('pagar');
|
|
// Route::get('/pagar/{status}', [StripeController::class, 'show'])->name('pagar.show');
|
|
|
|
Route::post('/pagar/{id}', [PagoController::class, 'pagar'])->name('pagar');
|
|
Route::get('/perfil', [UserProfileController::class, 'show'])->name('perfil');});
|
|
Route::resource('/permission',PermissionController::class);
|
|
Route::resource('/plan',PlanController::class);
|
|
Route::resource('/plane',PlaneController::class);
|
|
Route::resource('/plantel',PlantelController::class);
|
|
Route::get('/registros', [CodeController::class,'registros' ])->name('registros');
|
|
Route::resource('/role',RoleController::class);
|
|
|
|
// Route::get('/test-chat', function () { broadcast(new MessageSent('Hola realtime ')); return 'Mensaje enviado';});
|
|
Route::resource('/turno',TurnoController::class);
|
|
Route::resource('/user',UserController::class);
|
|
Route::resource('/mail',MailController::class);
|
|
Route::get('/mailme/{user}',[MailController::class,'mailme'])->name('mailme');
|
|
|
|
// Promociones WhatsApp
|
|
Route::resource('/promocion', PromocionController::class)->middleware([
|
|
'index' => 'can:promocion.index',
|
|
'create' => 'can:promocion.create',
|
|
'store' => 'can:promocion.create',
|
|
'edit' => 'can:promocion.edit',
|
|
'update' => 'can:promocion.edit',
|
|
'destroy' => 'can:promocion.destroy',
|
|
]);
|
|
Route::patch('/promocion/{promocion}/toggle', [PromocionController::class, 'toggleStatus'])
|
|
->name('promocion.toggle')->middleware('can:promocion.edit');
|
|
Route::post('/promocion/{promocion}/enviar', [PromocionController::class, 'enviar'])
|
|
->name('promocion.enviar')->middleware('can:promocion.enviar');
|
|
|
|
// Chat WhatsApp
|
|
Route::get('/promociones/chat', [WhatsAppChatController::class, 'index'])
|
|
->name('promocion.chat')->middleware('can:promocion.chat');
|
|
Route::get('/promociones/chat/{alumno}', [WhatsAppChatController::class, 'show'])
|
|
->name('promocion.chat.show')->middleware('can:promocion.chat');
|
|
Route::post('/promociones/chat/send', [WhatsAppChatController::class, 'send'])
|
|
->name('promocion.chat.send')->middleware('can:promocion.chat');
|
|
|
|
// Analytics WhatsApp
|
|
Route::get('/promociones/analytics', [WhatsAppAnalyticsController::class, 'index'])
|
|
->name('promocion.analytics')->middleware('can:promocion.analytics');
|
|
|
|
});
|