diff --git a/Modules/Raffle/app/Http/Controllers/RaffleController.php b/Modules/Raffle/app/Http/Controllers/RaffleController.php index 61a251b..0b35755 100644 --- a/Modules/Raffle/app/Http/Controllers/RaffleController.php +++ b/Modules/Raffle/app/Http/Controllers/RaffleController.php @@ -13,7 +13,11 @@ class RaffleController extends Controller { public function index() { - $raffles = Raffle::with('organizer', 'lottery')->paginate(10); + $user = auth()->user(); + $raffles = Raffle::with('organizer', 'lottery') + ->where('organizer_id', $user->id) + ->paginate(10); + return view('raffle::index', compact('raffles')); } @@ -38,18 +42,17 @@ public function store(Request $request) ]); Raffle::create([ - 'name' => $request->name, - 'organizer_id' => $request->organizer_id, - 'lottery_id' => $request->lottery_id, - - 'total_tickets' => $request->total_tickets, - 'ticket_price' => $request->ticket_price, - 'tickets_sold' => $request->tickets_sold ?? 0, - 'description' => $request->description, - 'start_date' => $request->start_date, - 'end_date' => $request->end_date, - 'total_sales' => 0, // valor predeterminado de total_sales - ]); + 'name' => $request->name, + 'organizer_id' => $request->organizer_id, + 'lottery_id' => $request->lottery_id, + 'total_tickets' => $request->total_tickets, + 'ticket_price' => $request->ticket_price, + 'tickets_sold' => $request->tickets_sold ?? 0, + 'description' => $request->description, + 'start_date' => $request->start_date, + 'end_date' => $request->end_date, + 'total_sales' => 0, // valor predeterminado de total_sales + ]); return redirect()->route('raffles.index')->with('success', 'Rifa creada exitosamente.'); } @@ -64,24 +67,31 @@ public function edit($id) public function update(Request $request, $id) { + $raffle = Raffle::findOrFail($id); + $request->validate([ - 'organizer_id' => 'required|exists:users,id', - 'image' => 'nullable|string', - 'lottery_id' => 'required|exists:lotteries,id', - 'ticket_price' => 'required|numeric|min:0', - 'total_tickets' => 'required|integer|min:1', - 'tickets_sold' => 'nullable|integer|min:0', + 'name' => 'required|string|max:255', 'description' => 'nullable|string', - 'start_date' => 'required|date', 'end_date' => 'required|date|after:start_date', + 'image' => 'nullable|image|max:2048', // Validar si es una imagen ]); - - $raffle = Raffle::findOrFail($id); - $raffle->update($request->all()); - + + // Manejar imagen si se sube un nuevo archivo + if ($request->hasFile('image')) { + $imagePath = $request->file('image')->store('raffle_images', 'public'); + $raffle->image = $imagePath; // Actualizar la ruta de la imagen + } + + // Actualizar otros campos + $raffle->update([ + 'name' => $request->name, + 'description' => $request->description, + 'end_date' => $request->end_date, + ]); + return redirect()->route('raffles.index')->with('success', 'Rifa actualizada exitosamente.'); } - + public function destroy($id) { $raffle = Raffle::findOrFail($id); @@ -121,7 +131,6 @@ public function getLastChanceRaffles() return response()->json($raffles); } - public function getActiveRaffles() { $activeRaffles = Raffle::where('end_date', '>', now())->get(); @@ -133,12 +142,12 @@ public function getFilteredRaffles(Request $request) $filter = $request->input('filter'); $date = $request->input('date'); $query = Raffle::with('organizer', 'lottery'); - + // Aplicar filtro adicional por fecha if ($date) { $query->whereDate('end_date', '>', $date); } - + switch ($filter) { case 'popular': $query->where('tickets_sold', '>=', 50) @@ -154,9 +163,8 @@ public function getFilteredRaffles(Request $request) $query->where('end_date', '>', now()); break; } - + $raffles = $query->paginate(6); return response()->json($raffles); } - -} +} \ No newline at end of file diff --git a/Modules/Raffle/resources/views/create.blade.php b/Modules/Raffle/resources/views/create.blade.php index 6468e08..8da4c0e 100644 --- a/Modules/Raffle/resources/views/create.blade.php +++ b/Modules/Raffle/resources/views/create.blade.php @@ -15,13 +15,11 @@
- + +
+ +
@@ -47,13 +45,13 @@
- +
- +
@@ -63,10 +61,7 @@
-
- - -
+
@@ -75,10 +70,7 @@
-
- - -
+
@@ -112,4 +104,4 @@ function calculateTicketPrice() { } } -@stop +@stop \ No newline at end of file diff --git a/Modules/Raffle/resources/views/edit.blade.php b/Modules/Raffle/resources/views/edit.blade.php index a6f78f3..7c6c512 100644 --- a/Modules/Raffle/resources/views/edit.blade.php +++ b/Modules/Raffle/resources/views/edit.blade.php @@ -1,5 +1,3 @@ - - @extends('adminlte::page') @section('title', 'Editar Rifa') @@ -15,77 +13,37 @@

Editar Rifa

-
+ @csrf @method('PUT') - - -
- - -
- - -
- - -
- - -
- - -
- - + +
- - + +
- - -
- - -
- +
- - -
- - -
- +
- - + +
- + +
+ +
+
@@ -103,7 +61,9 @@ -@stop +@stop \ No newline at end of file diff --git a/Modules/Raffle/resources/views/layouts/master.blade.php b/Modules/Raffle/resources/views/layouts/master.blade.php index 505d3a8..c7e3ea3 100644 --- a/Modules/Raffle/resources/views/layouts/master.blade.php +++ b/Modules/Raffle/resources/views/layouts/master.blade.php @@ -16,6 +16,8 @@ + + {{-- Vite CSS --}} @@ -24,10 +26,13 @@
@yield('content') + @yield('js')
{{-- Alpine.js --}} + + {{-- Vite JS --}} @vite('Modules/Raffle/resources/assets/js/app.js', 'build-raffle') diff --git a/Modules/Raffle/routes/web.php b/Modules/Raffle/routes/web.php index 7f0981f..6a44d9f 100644 --- a/Modules/Raffle/routes/web.php +++ b/Modules/Raffle/routes/web.php @@ -14,7 +14,7 @@ | */ -Route::prefix('raffles')->name('raffles.')->group(function () { +Route::middleware(['auth', 'role:admin|organizador'])->prefix('raffles')->name('raffles.')->group(function () { Route::get('/admin/rifas', [RaffleController::class, 'index'])->name('index'); Route::get('/admin/crear-rifa', [RaffleController::class, 'create'])->name('create'); Route::post('/admin/actualizar-rifa', [RaffleController::class, 'store'])->name('store'); diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 827b637..aa8be08 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -83,23 +83,23 @@ public function update(Request $request, User $user) 'email' => 'required|email|unique:users,email,' . $user->id, 'profile_photo' => 'nullable|image|max:2048', ]); - + // Manejar la foto de perfil if ($request->hasFile('profile_photo')) { // Usa el trait HasProfilePhoto para actualizar la foto de perfil $user->updateProfilePhoto($request->file('profile_photo')); } - + // Actualizar otros datos del usuario $user->update($validated); - + // Responder con el URL de la foto de perfil actualizado return response()->json([ 'message' => 'Usuario actualizado exitosamente.', 'profile_photo_url' => $user->profile_photo_url, ]); } - + /** * Remove the specified resource from storage. @@ -116,94 +116,82 @@ public function showProfile(User $user) if (auth()->id() !== $user->id) { abort(403, 'No tienes permiso para ver este perfil.'); } - + return Inertia::render('Users/Profile', [ 'user' => $user, ]); } public function updateProfilePhoto(Request $request, User $user) -{ - // Validar que se está enviando una imagen - $request->validate([ - 'profile_photo' => 'required|image|max:2048', - ]); - - // Manejar la foto de perfil - if ($request->hasFile('profile_photo')) { - // Eliminar la foto anterior si existe - if ($user->profile_photo_path) { - Storage::disk('public')->delete($user->profile_photo_path); - } - - // Actualizar la foto de perfil usando el trait HasProfilePhoto - $user->updateProfilePhoto($request->file('profile_photo')); - } - - return response()->json([ - 'message' => 'Foto de perfil actualizada exitosamente.', - 'profile_photo_url' => $user->profile_photo_url, - ]); -} - -public function activeRaffles() -{ - $activeRaffles = Raffle::where('end_date', '>', now())->get(); - - return Inertia::render('ActiveRaffles', [ - 'raffles' => $activeRaffles, - ]); -} - -public function registerOrganizer(){ - return Inertia::render('Users/RegisterOrganizer'); -} + { + // Validar que se está enviando una imagen + $request->validate([ + 'profile_photo' => 'required|image|max:2048', + ]); + // Manejar la foto de perfil + if ($request->hasFile('profile_photo')) { + // Eliminar la foto anterior si existe + if ($user->profile_photo_path) { + Storage::disk('public')->delete($user->profile_photo_path); + } -public function storeOrganizer(Request $request) -{ - - // Validar los datos del formulario - $validated = $request->validate([ - 'document' => 'nullable|string', - 'document_type' => 'nullable|string', - 'document_image' => 'required|image|max:2048', - ]); - - // Obtener el usuario autenticado - $user = auth()->user(); - - // Manejar la subida de la imagen del documento - if ($request->hasFile('document_image')) { - // Eliminar la imagen anterior si existe - if ($user->document_image_path) { - Storage::disk('public')->delete($user->document_image_path); + // Actualizar la foto de perfil usando el trait HasProfilePhoto + $user->updateProfilePhoto($request->file('profile_photo')); } - // Guardar la nueva imagen - $documentImagePath = $request->file('document_image')->store('documents', 'public'); - - // Actualizar los campos del usuario autenticado - $user->update([ - 'document' => $validated['document'] ?? $user->document, - 'document_type' => $validated['document_type'] ?? $user->document_type, - 'document_image_path' => $documentImagePath, + return response()->json([ + 'message' => 'Foto de perfil actualizada exitosamente.', + 'profile_photo_url' => $user->profile_photo_url, ]); - - $user->assignRole('organizador'); - -// Redirigir al panel de administración -return response()->json([ - 'success' => true, - 'message' => 'Usuario registrado y rol asignado como organizador.', -]); - } - return response()->json([ - 'error' => 'No se recibió la imagen del documento.', - ], 400); -} + public function activeRaffles() + { + $activeRaffles = Raffle::where('end_date', '>', now())->get(); + return Inertia::render('ActiveRaffles', [ + 'raffles' => $activeRaffles, + ]); + } + public function registerOrganizer() + { + return Inertia::render('Users/RegisterOrganizer'); + } + public function storeOrganizer(Request $request) + { + // Validar los datos del formulario + $validated = $request->validate([ + 'document' => 'nullable|string', + 'document_type' => 'nullable|string', + 'document_image' => 'required|image|max:2048', + ]); + + // Obtener el usuario autenticado + $user = auth()->user(); + + // Manejar la subida de la imagen del documento + if ($request->hasFile('document_image')) { + // Guardar la nueva imagen + $documentImagePath = $request->file('document_image')->store('documents', 'public'); + + // Actualizar los campos del usuario autenticado + $user->update([ + 'document' => $validated['document'] ?? $user->document, + 'document_type' => $validated['document_type'] ?? $user->document_type, + 'document_image_path' => $documentImagePath, + ]); + + // Asignar el rol de organizador + $user->assignRole('organizador'); + + // Redirigir al usuario a la página de rifas + return redirect('/raffles/admin/rifas')->with('success', 'Usuario registrado exitosamente como organizador.'); + } + + // Si no se recibió una imagen, retornar error + return redirect()->back()->withErrors(['document_image' => 'La imagen del documento es requerida.']); + } + } diff --git a/config/adminlte.php b/config/adminlte.php index e6ce39e..43595b1 100644 --- a/config/adminlte.php +++ b/config/adminlte.php @@ -299,99 +299,22 @@ */ 'menu' => [ - // Navbar items: [ - 'type' => 'navbar-search', - 'text' => 'search', - 'topnav_right' => true, - ], - [ - 'type' => 'fullscreen-widget', - 'topnav_right' => true, - ], - - // Sidebar items: - [ - 'type' => 'sidebar-menu-search', - 'text' => 'search', - ], - [ - 'text' => 'blog', - 'url' => 'admin/blog', - 'can' => 'manage-blog', + 'text' => 'Go to the Dashboard', + 'url' => '/dashboard', + 'topnav' => true, + 'icon' => 'fas fa-tachometer-alt', ], [ 'text' => 'Rifas', 'submenu' => [ [ 'text' => 'Crear rifa', - 'url'=> 'admin/crear-rifa' + 'url'=> 'raffles/admin/crear-rifa' ], [ 'text' => 'Listar rifas', - 'url'=> 'admin/rifas' - ], - ], - ], - [ - 'text' => 'Estadisticas', - 'submenu' => [ - [ - 'text' => 'Boletos vendidos', - 'url' => '' - ], - ], - 'icon' => 'far fa-fw fa-file', - 'label' => 4, - 'label_color' => 'success', - ], - - ['header' => 'account_settings'], - [ - 'text' => 'profile', - 'url' => 'admin/settings', - 'icon' => 'fas fa-fw fa-user', - ], - [ - 'text' => 'change_password', - 'url' => 'admin/settings', - 'icon' => 'fas fa-fw fa-lock', - ], - [ - 'text' => 'multilevel', - 'icon' => 'fas fa-fw fa-share', - 'submenu' => [ - [ - 'text' => 'level_one', - 'url' => '#', - ], - [ - 'text' => 'level_one', - 'url' => '#', - 'submenu' => [ - [ - 'text' => 'level_two', - 'url' => '#', - ], - [ - 'text' => 'level_two', - 'url' => '#', - 'submenu' => [ - [ - 'text' => 'level_three', - 'url' => '#', - ], - [ - 'text' => 'level_three', - 'url' => '#', - ], - ], - ], - ], - ], - [ - 'text' => 'level_one', - 'url' => '#', + 'url'=> 'raffles/admin/rifas' ], ], ], diff --git a/resources/js/Components/Dashboard/HeroBanner.vue b/resources/js/Components/Dashboard/HeroBanner.vue index 130ffc2..1bc4b8c 100644 --- a/resources/js/Components/Dashboard/HeroBanner.vue +++ b/resources/js/Components/Dashboard/HeroBanner.vue @@ -26,6 +26,9 @@ - - - \ No newline at end of file +}; + + + \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index 12830fc..f2c1ef8 100644 --- a/routes/web.php +++ b/routes/web.php @@ -16,7 +16,7 @@ use Modules\Raffle\Http\Controllers\RaffleController; use Modules\Ticket\Http\Controllers\TicketController; -// Ruta pública +// Rutas públicas Route::get('/', function () { return Inertia::render('Welcome', [ 'canLogin' => Route::has('login'), @@ -24,83 +24,72 @@ 'laravelVersion' => Application::VERSION, 'phpVersion' => PHP_VERSION, ]); -}); -Route::get('/test-discord', function () { - \App\Helpers\DiscordNotifier::send("Prueba directa de notificación a Discord."); - return "Mensaje enviado."; -}); -// Grupo de rutas autenticadas +})->name('home'); + +Route::get('/about', function () { + return Inertia::render('About'); +})->name('about'); + +// Rutas autenticadas Route::middleware(['auth:sanctum', config('jetstream.auth_session')])->group(function () { Route::get('/dashboard', function () { return Inertia::render('Dashboard'); })->name('dashboard'); }); -// Grupo de rutas para cliente -Route::middleware(['role:client'])->group(function () { +// Rutas para cliente +Route::middleware(['auth', 'role:client'])->group(function () { Route::get('/test-client', function () { return Inertia::render('Profile/TestClient'); }); }); -// Grupo de rutas protegidas por el middleware de verificación de contraseña -Route::middleware(['auth', 'role:admin'])->get('dashboard/admin', function () { - return Inertia::render('Admin/AdminDashboard'); -})->name('admin.dashboard'); - -// Grupo de rutas para la gestión de usuarios +// Rutas para administrador Route::middleware(['auth', 'role:admin'])->group(function () { - Route::get('/users', [UserController::class, 'index'])->name('users.index'); - Route::get('/users/create', [UserController::class, 'create'])->name('users.create'); - Route::get('/users/{user}/edit', [UserController::class, 'edit'] )->name('users.edit'); - Route::put('/users/{user}', [UserController::class, 'update'])->name('users.update'); - Route::delete('/users/{user}', [UserController::class, 'destroy'])->name('users.destroy'); + Route::get('dashboard/admin', function () { + return Inertia::render('Admin/AdminDashboard'); + })->name('admin.dashboard'); + + // Gestión de usuarios + Route::prefix('users')->group(function () { + Route::get('/', [UserController::class, 'index'])->name('users.index'); + Route::get('/create', [UserController::class, 'create'])->name('users.create'); + Route::get('/{user}/edit', [UserController::class, 'edit'])->name('users.edit'); + Route::put('/{user}', [UserController::class, 'update'])->name('users.update'); + Route::delete('/{user}', [UserController::class, 'destroy'])->name('users.destroy'); + }); }); -Route::middleware(['auth'])->get('/profile/{user}', [UserController::class, 'showProfile'])->name('users.profile'); - -Route::get('/about', function () { - return Inertia::render('About'); -})->name('about'); - +// Rutas autenticadas generales Route::middleware(['auth'])->group(function () { - Route::get('/raffles-actives', [RaffleController::class, 'getRaffles'])->name('raffles.actives'); + // Perfil de usuario + Route::get('/profile/{user}', [UserController::class, 'showProfile'])->name('users.profile'); + Route::post('/users/{user}/update-photo', [UserController::class, 'updateProfilePhoto'])->name('user.update-photo'); + // Rifas + Route::get('/raffles-actives', [RaffleController::class, 'getRaffles'])->name('raffles.actives'); Route::get('/raffles-last-chance', [RaffleController::class, 'getLastChanceRaffles'])->name('raffles.last-chance'); - - Route::get('/auth/redirect/github', [AuthController::class, 'redirectToGitHub'])->name('github.login'); - Route::get('/auth/callback/github', [AuthController::class, 'handleGitHubCallback'])->name('github.callback'); - - Route::get('/auth/redirect/google', [AuthController::class, 'redirectToGoogle'])->name('google.login'); - Route::get('/auth/google/callback', [AuthController::class, 'handleGoogleCallback'])->name('google.callback'); - Route::get('/raffles-filtered', [RaffleController::class, 'getFilteredRaffles'])->name('raffles.filtered'); Route::get('/raffles/active', [UserController::class, 'activeRaffles'])->name('raffles.active'); -}); -Route::middleware(['auth'])->group(function () { + // Tickets Route::get('/api/user-tickets/{userId}', [TicketController::class, 'getUserTickets'])->name('user.tickets'); Route::get('/api/active-raffles', [RaffleController::class, 'getActiveRaffles'])->name('raffles.active'); Route::post('/ticket/create', [TicketController::class, 'store']); + + // Registro de organizador Route::get('/registro-organizador', [UserController::class, 'registerOrganizer'])->name('register.organizer'); Route::post('/register-organizer', [UserController::class, 'storeOrganizer'])->name('organizer.register'); + // Autenticación con terceros + Route::get('/auth/redirect/github', [AuthController::class, 'redirectToGitHub'])->name('github.login'); + Route::get('/auth/callback/github', [AuthController::class, 'handleGitHubCallback'])->name('github.callback'); + Route::get('/auth/redirect/google', [AuthController::class, 'redirectToGoogle'])->name('google.login'); + Route::get('/auth/google/callback', [AuthController::class, 'handleGoogleCallback'])->name('google.callback'); }); - -Route::post('/users/{user}/update-photo', [UserController::class, 'updateProfilePhoto'])->name('user.update-photo'); - +// Rutas de pago Route::post('/payment/create', [PaymentController::class, 'create']); Route::post('/payment/createPayment', [PaymentController::class, 'createPayment']); Route::post('/payment/store', [PaymentController::class, 'store']); - -Route::post('/verify-payment', [PaymentVerificationController::class, 'verifyPayment']); - - -Route::get('/test-404', function () { - abort(404); -}); - -Route::get('/test-500', function () { - abort(500); -}); \ No newline at end of file +Route::post('/verify-payment', [PaymentVerificationController::class, 'verifyPayment']); \ No newline at end of file