diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index dbaf3e2..fd970d4 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -3,11 +3,23 @@ namespace App\Http\Controllers; use Illuminate\Http\Request; +use App\Models\Product; class HomeController extends Controller { - public function __invoke() // * Controlador con un unico metodo se usa __invoke + public function __invoke(Request $request) { - return view('welcome'); + // Si tuvieras un campo 'sales_count', podrías usar ->orderByDesc('sales_count') + $destacados = Product::where('type', 'bike') + ->latest() // Las más nuevas + ->take(5) + ->get(); + + // Si no hay bicis, traemos cualquier cosa para que no se rompa + if ($destacados->isEmpty()) { + $destacados = Product::take(5)->get(); + } + + return view('welcome', compact('destacados')); } } diff --git a/app/Http/Controllers/ProductosController.php b/app/Http/Controllers/ProductosController.php index 76fb067..5a06fae 100644 --- a/app/Http/Controllers/ProductosController.php +++ b/app/Http/Controllers/ProductosController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers; use App\Models\Product; use Illuminate\Http\Request; use Illuminate\Validation\Rule; // Necesario para validar unicidad al editar +use Illuminate\Support\Facades\Storage; // <--- IMPORTANTE: Agregar esto arriba class ProductosController extends Controller { @@ -54,6 +55,7 @@ class ProductosController extends Controller 'min_stock_alert' => 'required|integer|min:0', 'type' => 'required|in:bike,accessory,service', // Solo permite estos 3 valores 'serial_number' => 'nullable|string|max:100', + 'image' => 'nullable|image|mimes:jpeg,png,jpg,webp|max:2048', ]); // 2. Si no viene SKU, generamos uno automático (Opcional pero útil) @@ -61,6 +63,17 @@ class ProductosController extends Controller $validated['sku'] = 'GEN-' . strtoupper(uniqid()); } + // 3. Validacion de imagenes + if ($request->hasFile('image')) { + // Guarda el archivo en storage/app/public/products y devuelve la ruta + $path = $request->file('image')->store('products', 'public'); + $validated['image_path'] = $path; + } + + unset($validated['image']); + + // Para no romper la logica del supplier + $validated['suppliers_id'] = 1; // 3. Creamos el producto Product::create($validated); @@ -102,8 +115,26 @@ class ProductosController extends Controller 'min_stock_alert' => 'required|integer|min:0', 'type' => 'required|in:bike,accessory,service', 'serial_number' => 'nullable|string|max:100', + + 'image' => 'nullable|image|mimes:jpeg,png,jpg,webp|max:2048', ]); + // 2. Manejo de imagen al actualizar + if ($request->hasFile('image')) { + // Borrar la imagen anterior + if ($product->image_path) { + Storage::disk('public')->delete($product->image_path); + } + + // Guardar la nueva + $path = $request->file('image')->store('products', 'public'); + $validated['image_path'] = $path; + } + unset($validated['image']); + + // Para no romper la logica del supplier + $validated['suppliers_id'] = 1; + $product->update($validated); return redirect()->route('productos.index') diff --git a/database/factories/ProductFactory.php b/database/factories/ProductFactory.php index 2c53073..2ab688a 100644 --- a/database/factories/ProductFactory.php +++ b/database/factories/ProductFactory.php @@ -48,6 +48,7 @@ class ProductFactory extends Factory 'type' => $type, // Nro de serie si es bicicleta 'serial_number' => $type === 'bike' ? strtoupper($this->faker->bothify('##??##??')) : null, + 'suppliers_id'=> 1 ]; } } diff --git a/database/migrations/2025_12_06_182358_create_products_table.php b/database/migrations/2025_12_06_182358_create_products_table.php index 5b743f7..ea3aba5 100644 --- a/database/migrations/2025_12_06_182358_create_products_table.php +++ b/database/migrations/2025_12_06_182358_create_products_table.php @@ -21,12 +21,12 @@ return new class extends Migration $table->decimal('cost', 10, 2)->nullable(); // Costo (solo admin) $table->integer('stock_quantity')->default(0); - $table->integer('min_stock_alert')->default(5); // Alerta + $table->integer('min_stock_alert'); // Alerta $table->enum('type', ['bike', 'accessory', 'service']); $table->string('serial_number')->nullable(); // Solo para bicis - $table->foreignId('suppliers_id')->constrained(); + $table->foreignId('suppliers_id')->constrained()->default(1); $table->timestamps(); }); } diff --git a/database/migrations/2026_01_06_210513_add_image_to_products_table.php b/database/migrations/2026_01_06_210513_add_image_to_products_table.php new file mode 100644 index 0000000..addaf25 --- /dev/null +++ b/database/migrations/2026_01_06_210513_add_image_to_products_table.php @@ -0,0 +1,22 @@ +string('image_path')->nullable()->after('type'); + }); + } + + public function down(): void + { + Schema::table('products', function (Blueprint $table) { + $table->dropColumn('image_path'); + }); + } +}; diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index fe2ec6e..925158c 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -6,6 +6,7 @@ use Illuminate\Database\Seeder; use App\Models\User; use App\Models\Product; use App\Models\Client; +use App\Models\Supplier; use App\Models\Appointment; // use Illuminate\Database\Console\Seeds\WithoutModelEvents; @@ -29,6 +30,12 @@ class DatabaseSeeder extends Seeder 'role' => 'employee', ]); + Supplier::create([ + 'name' => 'Cámara 29 Válvula Auto', + 'phone' => '3434567890', + 'email' => 'suplier@suplier.com' + ]); + //Crear Productos Product::create([ 'name' => 'Cámara 29 Válvula Auto', @@ -37,7 +44,8 @@ class DatabaseSeeder extends Seeder 'cost' => 2500, 'stock_quantity' => 20, 'min_stock_alert' => 5, - 'type' => 'accessory' + 'type' => 'accessory', + 'suppliers_id' => 1 ]); Product::create([ @@ -48,7 +56,8 @@ class DatabaseSeeder extends Seeder 'stock_quantity' => 2, 'min_stock_alert' => 1, 'type' => 'bike', - 'serial_number' => 'VZ998877' + 'serial_number' => 'VZ998877', + 'suppliers_id' => 1 ]); // Generar 10 productos aleatorios más diff --git a/resources/views/components/ui/carrousel.blade.php b/resources/views/components/ui/carrousel.blade.php new file mode 100644 index 0000000..5f1e1a8 --- /dev/null +++ b/resources/views/components/ui/carrousel.blade.php @@ -0,0 +1,141 @@ +@props(['items']) + + + + \ No newline at end of file diff --git a/resources/views/productos/create.blade.php b/resources/views/productos/create.blade.php index 0a333ff..02f9d6b 100644 --- a/resources/views/productos/create.blade.php +++ b/resources/views/productos/create.blade.php @@ -4,7 +4,7 @@
-
+ @csrf @@ -59,6 +59,14 @@
+ +
+ + + {{-- @error('image') {{ $message }} @enderror --}} +
diff --git a/resources/views/welcome.blade.php b/resources/views/welcome.blade.php index 88e088e..e8d5dc3 100644 --- a/resources/views/welcome.blade.php +++ b/resources/views/welcome.blade.php @@ -1,17 +1,10 @@ - -
- - - - - - - - - - + +
+ +
+