1
0

freezer app completed

This commit is contained in:
2025-03-31 17:22:29 +02:00
parent 04fbfa266f
commit 97377d2c11
14 changed files with 395 additions and 66 deletions

12
app/Models/Item.php Normal file
View File

@@ -0,0 +1,12 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Item extends Model
{
/** @use HasFactory<\Database\Factories\ItemFactory> */
use HasFactory;
}

View File

@@ -10,6 +10,7 @@
"license": "MIT", "license": "MIT",
"require": { "require": {
"php": "^8.2", "php": "^8.2",
"jzonta/faker-restaurant": "^2.0",
"laravel/framework": "^12.0", "laravel/framework": "^12.0",
"laravel/tinker": "^2.10.1" "laravel/tinker": "^2.10.1"
}, },

174
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "169957dd64cb1b1fe48bbed8097aa550", "content-hash": "fcafb5796123bc88493435c346f3619a",
"packages": [ "packages": [
{ {
"name": "brick/math", "name": "brick/math",
@@ -510,6 +510,69 @@
], ],
"time": "2025-03-06T22:45:56+00:00" "time": "2025-03-06T22:45:56+00:00"
}, },
{
"name": "fakerphp/faker",
"version": "v1.24.1",
"source": {
"type": "git",
"url": "https://github.com/FakerPHP/Faker.git",
"reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/FakerPHP/Faker/zipball/e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5",
"reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5",
"shasum": ""
},
"require": {
"php": "^7.4 || ^8.0",
"psr/container": "^1.0 || ^2.0",
"symfony/deprecation-contracts": "^2.2 || ^3.0"
},
"conflict": {
"fzaninotto/faker": "*"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.4.1",
"doctrine/persistence": "^1.3 || ^2.0",
"ext-intl": "*",
"phpunit/phpunit": "^9.5.26",
"symfony/phpunit-bridge": "^5.4.16"
},
"suggest": {
"doctrine/orm": "Required to use Faker\\ORM\\Doctrine",
"ext-curl": "Required by Faker\\Provider\\Image to download images.",
"ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.",
"ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.",
"ext-mbstring": "Required for multibyte Unicode string functionality."
},
"type": "library",
"autoload": {
"psr-4": {
"Faker\\": "src/Faker/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "François Zaninotto"
}
],
"description": "Faker is a PHP library that generates fake data for you.",
"keywords": [
"data",
"faker",
"fixtures"
],
"support": {
"issues": "https://github.com/FakerPHP/Faker/issues",
"source": "https://github.com/FakerPHP/Faker/tree/v1.24.1"
},
"time": "2024-11-21T13:46:39+00:00"
},
{ {
"name": "fruitcake/php-cors", "name": "fruitcake/php-cors",
"version": "v1.3.0", "version": "v1.3.0",
@@ -1054,6 +1117,52 @@
], ],
"time": "2025-02-03T10:55:03+00:00" "time": "2025-02-03T10:55:03+00:00"
}, },
{
"name": "jzonta/faker-restaurant",
"version": "2.0.1",
"source": {
"type": "git",
"url": "https://github.com/jzonta/FakerRestaurant.git",
"reference": "4e10ff08dc8ca08603a3daf7abe48d412b013cf4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jzonta/FakerRestaurant/zipball/4e10ff08dc8ca08603a3daf7abe48d412b013cf4",
"reference": "4e10ff08dc8ca08603a3daf7abe48d412b013cf4",
"shasum": ""
},
"require": {
"fakerphp/faker": "^1.9.1",
"php": ">=7.1"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.17",
"phpstan/phpstan": "^0.12.66",
"phpunit/phpunit": "^9"
},
"type": "library",
"autoload": {
"psr-4": {
"FakerRestaurant\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "João Zonta"
}
],
"description": "Food and Beverage names generate using fakerphp/faker",
"homepage": "https://github.com/jzonta/FakerRestaurant",
"support": {
"issues": "https://github.com/jzonta/FakerRestaurant/issues",
"source": "https://github.com/jzonta/FakerRestaurant/tree/v2.0.1"
},
"time": "2021-11-15T11:21:22+00:00"
},
{ {
"name": "laravel/framework", "name": "laravel/framework",
"version": "v12.4.0", "version": "v12.4.0",
@@ -5925,69 +6034,6 @@
}, },
"time": "2024-12-07T21:18:45+00:00" "time": "2024-12-07T21:18:45+00:00"
}, },
{
"name": "fakerphp/faker",
"version": "v1.24.1",
"source": {
"type": "git",
"url": "https://github.com/FakerPHP/Faker.git",
"reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/FakerPHP/Faker/zipball/e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5",
"reference": "e0ee18eb1e6dc3cda3ce9fd97e5a0689a88a64b5",
"shasum": ""
},
"require": {
"php": "^7.4 || ^8.0",
"psr/container": "^1.0 || ^2.0",
"symfony/deprecation-contracts": "^2.2 || ^3.0"
},
"conflict": {
"fzaninotto/faker": "*"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.4.1",
"doctrine/persistence": "^1.3 || ^2.0",
"ext-intl": "*",
"phpunit/phpunit": "^9.5.26",
"symfony/phpunit-bridge": "^5.4.16"
},
"suggest": {
"doctrine/orm": "Required to use Faker\\ORM\\Doctrine",
"ext-curl": "Required by Faker\\Provider\\Image to download images.",
"ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.",
"ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.",
"ext-mbstring": "Required for multibyte Unicode string functionality."
},
"type": "library",
"autoload": {
"psr-4": {
"Faker\\": "src/Faker/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "François Zaninotto"
}
],
"description": "Faker is a PHP library that generates fake data for you.",
"keywords": [
"data",
"faker",
"fixtures"
],
"support": {
"issues": "https://github.com/FakerPHP/Faker/issues",
"source": "https://github.com/FakerPHP/Faker/tree/v1.24.1"
},
"time": "2024-11-21T13:46:39+00:00"
},
{ {
"name": "fidry/cpu-core-counter", "name": "fidry/cpu-core-counter",
"version": "1.2.0", "version": "1.2.0",

View File

@@ -0,0 +1,29 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Item>
*/
class ItemFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
$faker = \Faker\Factory::create();
$faker->addProvider(new \FakerRestaurant\Provider\en_US\Restaurant($faker));
return [
"name" => $faker->foodName(),
"description" => null,
"in_date" => fake()->date("d-m-Y"),
"quantity" => fake()->numberBetween(1, 5)
];
}
}

View File

@@ -0,0 +1,31 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('items', function (Blueprint $table) {
$table->id();
$table->string("name");
$table->string("description")->nullable();
$table->date("in_date");
$table->integer("quantity");
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('items');
}
};

View File

@@ -1,5 +1,7 @@
@import 'tailwindcss'; @import 'tailwindcss';
@custom-variant dark (&:where(.dark, .dark *));
@source '../../vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php'; @source '../../vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php';
@source '../../storage/framework/views/*.php'; @source '../../storage/framework/views/*.php';
@source '../**/*.blade.php'; @source '../**/*.blade.php';

View File

@@ -0,0 +1,4 @@
<x-layout>
<h1 class="m-4 text-2xl text-center">Aggiungi elemento</h1>
<x-form method="POST" action="/add"></x-form>
</x-layout>

View File

@@ -0,0 +1,58 @@
<form {{ $attributes }}>
@csrf
<div class="p-4">
<div>
<label for="name"
class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
Nome
</label>
<input required type="text" id="name" name="name"
class="bg-gray-50 border border-gray-300
text-gray-900 text-sm rounded-lg focus:ring-blue-500
focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700
dark:border-gray-600 dark:placeholder-gray-400 dark:text-white
dark:focus:ring-blue-500 dark:focus:border-blue-500">
</div>
<div>
<label for="description"
class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
Descrizione
</label>
<input type="text" id="description" name="description"
class="bg-gray-50 border border-gray-300
text-gray-900 text-sm rounded-lg focus:ring-blue-500
focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700
dark:border-gray-600 dark:placeholder-gray-400 dark:text-white
dark:focus:ring-blue-500 dark:focus:border-blue-500">
</div>
<div>
<label for="in_date"
class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
Data inserimento
</label>
<input required type="date" id="in_date" name="in_date"
class="bg-gray-50 border border-gray-300
text-gray-900 text-sm rounded-lg focus:ring-blue-500
focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700
dark:border-gray-600 dark:placeholder-gray-400 dark:text-white
dark:focus:ring-blue-500 dark:focus:border-blue-500">
</div>
<div>
<label for="quantity"
class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
Quantitá
</label>
<input required type="number" id="quantity" name="quantity"
class="bg-gray-50 border border-gray-300
text-gray-900 text-sm rounded-lg focus:ring-blue-500
focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700
dark:border-gray-600 dark:placeholder-gray-400 dark:text-white
dark:focus:ring-blue-500 dark:focus:border-blue-500">
</div>
<input type="submit" value="Aggiungi"
class="mt-4 text-white bg-sky-700 hover:bg-sky-800
focus:ring-4 focus:outline-none focus:ring-sky-300
font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5
text-center dark:bg-sky-600 dark:hover:bg-sky-700 dark:focus:ring-sky-800">
</div>
</form>

View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
@vite('resources/css/app.css')
<title>Document</title>
</head>
<body>
<div class="p-4">
<x-navigation></x-navigation>
{{ $slot }}
</div>
</body>
</html>

View File

@@ -0,0 +1 @@
<a {{ $attributes }} class="m-2 p-2 bg-sky-100 rounded-lg hover:bg-sky-200">{{ $slot }}</a>

View File

@@ -0,0 +1,4 @@
<nav>
<x-link href="/">Home</x-link>
<x-link href="/add">Aggiungi</x-link>
</nav>

View File

@@ -0,0 +1,77 @@
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
<tr>
<th scope="col" class="px-6 py-3">
Id
</th>
<th scope="col" class="px-6 py-3">
Nome
</th>
<th scope="col" class="px-6 py-3">
Descrizione
</th>
<th scope="col" class="px-6 py-3">
Data inserimento
</th>
<th scope="col" class="px-6 py-3">
Quantitá
</th>
<th scope="col" class="px-6 py-3">
Azioni
</th>
</tr>
</thead>
<tbody>
@foreach($items as $item)
<tr class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 border-gray-200">
<td class="px-6 py-4">
{{ $item->id }}
</td>
<td class="px-6 py-4">
{{ $item->name }}
</td>
<td class="px-6 py-4">
{{ $item->description }}
</td>
<td class="px-6 py-4">
{{ $item->in_date }}
</td>
<td class="px-6 py-4">
{{ $item->quantity }}
</td>
<td class="px-6 py-4">
@if ($item->quantity == 0)
<form method="POST" action="/delete/{{ $item->id }}">
@csrf
@method("DELETE")
<input type="submit" class="text-white bg-red-700 hover:bg-red-800
focus:ring-4 focus:outline-none focus:ring-red-300
font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5
text-center dark:bg-red-600 dark:hover:bg-red-700 dark:focus:ring-red-800" value="Cancella">
</form>
@else
<div class="flex row">
<form method="POST" action="/reduce/{{ $item->id }}">
@csrf
@method("PUT")
<input type="submit" class="mr-2 text-white bg-yellow-700 hover:bg-yellow-800
focus:ring-4 focus:outline-none focus:ring-yellow-300
font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5
text-center dark:bg-yellow-600 dark:hover:bg-yellow-700 dark:focus:ring-yellow-800" value="-1">
</form>
<form method="POST" action="/increase/{{ $item->id }}">
@csrf
@method("PUT")
<input type="submit" class="text-white bg-green-700 hover:bg-green-800
focus:ring-4 focus:outline-none focus:ring-green-300
font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5
text-center dark:bg-green-600 dark:hover:bg-green-700 dark:focus:ring-green-800" value="+1">
</form>
</div>
@endif
</td>
</tr>
@endforeach
</tbody>
</table>

View File

@@ -0,0 +1,7 @@
<x-layout>
<h1 class="m-4 text-2xl text-center">Freezer App</h1>
<x-table :items="$items"></x-table>
<div class="mt-2">
{{ $items->links() }}
</div>
</x-layout>

View File

@@ -1,7 +1,48 @@
<?php <?php
use App\Models\Item;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
Route::get('/', function () { Route::get('/laravel', function () {
return view('welcome'); return view('welcome');
}); });
Route::get("/", function () {
$items = Item::orderBy("id", "desc")->simplePaginate(8);
return view("freezer", [
"items" => $items
]);
});
Route::get("/add", function() {
return view("add");
});
Route::post("/add", function(){
Item::insert([
"name"=>request("name"),
"description"=>request("description"),
"in_date"=>request("in_date"),
"quantity"=>request("quantity"),
]);
return redirect("/");
});
Route::put("/reduce/{id}", function($id){
$item = Item::find($id);
$item->quantity = $item->quantity - 1;
$item->save();
return redirect("/");
});
Route::put("/increase/{id}", function($id){
$item = Item::find($id);
$item->quantity = $item->quantity + 1;
$item->save();
return redirect("/");
});
Route::delete("/delete/{id}", function($id){
Item::find($id)->delete();
return redirect("/");
});