diff --git a/app/Models/Album.php b/app/Models/Album.php index d78b605..d4b9a20 100644 --- a/app/Models/Album.php +++ b/app/Models/Album.php @@ -5,12 +5,26 @@ namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Support\Collection; class Album extends Model { use HasFactory; public function category() : BelongsTo { - $this->belongsTo(Category::class); + return $this->belongsTo(Category::class); + } + + public function images() : HasMany { + return $this->hasMany(Image::class); + } + + public function media() : Collection { + return $this->images; + } + + public function getThumbnailAttribute() : ?string { + return $this->images()->where('isCover', 1)->first()?->getThumbnail(); } } diff --git a/bootstrap/providers.php b/bootstrap/providers.php index 6662165..e8b44c0 100644 --- a/bootstrap/providers.php +++ b/bootstrap/providers.php @@ -3,4 +3,5 @@ return [ App\Providers\AppServiceProvider::class, App\Providers\LivewireAssetProvider::class, + App\Providers\TelescopeServiceProvider::class, ]; diff --git a/composer.json b/composer.json index a11fd4e..2fd7012 100644 --- a/composer.json +++ b/composer.json @@ -7,6 +7,7 @@ "require": { "php": "^8.2", "laravel/framework": "^11.0", + "laravel/telescope": "^5.0", "laravel/tinker": "^2.9", "livewire/livewire": "^3.4" }, diff --git a/composer.lock b/composer.lock index 7d041ff..5072014 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "3e788d36623f5aa3b9b254a19bb9a8a9", + "content-hash": "26523f4293916dbcb8f8c1260b93b569", "packages": [ { "name": "brick/math", @@ -1367,6 +1367,75 @@ }, "time": "2023-11-08T14:08:06+00:00" }, + { + "name": "laravel/telescope", + "version": "v5.0.5", + "source": { + "type": "git", + "url": "https://github.com/laravel/telescope.git", + "reference": "ae5c28ca1e40a7a66bfc9b2557e7e1d84d95363c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/telescope/zipball/ae5c28ca1e40a7a66bfc9b2557e7e1d84d95363c", + "reference": "ae5c28ca1e40a7a66bfc9b2557e7e1d84d95363c", + "shasum": "" + }, + "require": { + "ext-json": "*", + "laravel/framework": "^8.37|^9.0|^10.0|^11.0", + "php": "^8.0", + "symfony/console": "^5.3|^6.0|^7.0", + "symfony/var-dumper": "^5.0|^6.0|^7.0" + }, + "require-dev": { + "ext-gd": "*", + "guzzlehttp/guzzle": "^6.0|^7.0", + "laravel/octane": "^1.4|^2.0|dev-develop", + "orchestra/testbench": "^6.40|^7.37|^8.17|^9.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.0|^10.5" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Telescope\\TelescopeServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Telescope\\": "src/", + "Laravel\\Telescope\\Database\\Factories\\": "database/factories/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Mohamed Said", + "email": "mohamed@laravel.com" + } + ], + "description": "An elegant debug assistant for the Laravel framework.", + "keywords": [ + "debugging", + "laravel", + "monitoring" + ], + "support": { + "issues": "https://github.com/laravel/telescope/issues", + "source": "https://github.com/laravel/telescope/tree/v5.0.5" + }, + "time": "2024-05-09T17:09:01+00:00" + }, { "name": "laravel/tinker", "version": "v2.9.0", @@ -8216,5 +8285,5 @@ "php": "^8.2" }, "platform-dev": [], - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.3.0" } diff --git a/config/filesystems.php b/config/filesystems.php index 44fe9c8..b2064d6 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -36,6 +36,12 @@ return [ 'throw' => false, ], + 'images' => [ + 'driver' => 'local', + 'root' => storage_path('app/images'), + 'throw' => false, + ], + 'public' => [ 'driver' => 'local', 'root' => storage_path('app/public'), diff --git a/database/factories/AlbumFactory.php b/database/factories/AlbumFactory.php index d592398..a01f16f 100644 --- a/database/factories/AlbumFactory.php +++ b/database/factories/AlbumFactory.php @@ -20,7 +20,6 @@ class AlbumFactory extends Factory { return [ 'name' => fake()->sentence(2), - 'cover' => './covers/image-'.rand(1,12).'-big.jpg', 'category_id' => Category::all()->random(1)->first()->id, ]; } diff --git a/database/factories/CategoryFactory.php b/database/factories/CategoryFactory.php index 34944b8..1f17900 100644 --- a/database/factories/CategoryFactory.php +++ b/database/factories/CategoryFactory.php @@ -34,6 +34,4 @@ class CategoryFactory extends Factory 'cover' => './covers/image-'.rand(1,12).'-big.jpg', ]; } - - } diff --git a/database/migrations/2024_04_28_204503_create_albums_table.php b/database/migrations/2024_04_28_204503_create_albums_table.php index 111373f..de0bfda 100644 --- a/database/migrations/2024_04_28_204503_create_albums_table.php +++ b/database/migrations/2024_04_28_204503_create_albums_table.php @@ -15,7 +15,6 @@ return new class extends Migration Schema::create('albums', function (Blueprint $table) { $table->id(); $table->string('name'); - $table->string('cover'); $table->foreignIdFor(Category::class); $table->timestamps(); }); diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index 8c51742..ae114a1 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -17,6 +17,7 @@ class DatabaseSeeder extends Seeder TagSeeder::class, CategorySeeder::class, AlbumSeeder::class, + ImageSeeder::class, ]); } } diff --git a/package-lock.json b/package-lock.json index 1df8f1c..055310e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,15 @@ "requires": true, "packages": { "": { + "dependencies": { + "filepond": "^4.31.1", + "filepond-plugin-file-validate-size": "^2.2.8", + "filepond-plugin-file-validate-type": "^1.2.9", + "filepond-plugin-image-edit": "^1.6.3", + "filepond-plugin-image-exif-orientation": "^1.0.11", + "filepond-plugin-image-preview": "^4.6.12", + "filepond-plugin-image-transform": "^3.8.7" + }, "devDependencies": { "@tailwindcss/forms": "^0.5.7", "autoprefixer": "^10.4.19", @@ -1157,6 +1166,59 @@ "reusify": "^1.0.4" } }, + "node_modules/filepond": { + "version": "4.31.1", + "resolved": "https://registry.npmjs.org/filepond/-/filepond-4.31.1.tgz", + "integrity": "sha512-yWYK91Ky72L2AG7BlI8Cb0UjvJz+DjuYdLN1JbkJg8qmoiZ9AU5b5MuOkHmExk/9jQ5R7tRT+H+b8wDiFEJlxQ==" + }, + "node_modules/filepond-plugin-file-validate-size": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/filepond-plugin-file-validate-size/-/filepond-plugin-file-validate-size-2.2.8.tgz", + "integrity": "sha512-yzb8scATmkWqPTP7oKQz6L8WwJm6Xmgc/fuq6DFGRaLz0I7372BUvBsxagBk/hypMIjvieNzhggm33Y60x3rcw==", + "peerDependencies": { + "filepond": ">=3.1.2 <5.x" + } + }, + "node_modules/filepond-plugin-file-validate-type": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/filepond-plugin-file-validate-type/-/filepond-plugin-file-validate-type-1.2.9.tgz", + "integrity": "sha512-Tzv07aNdZvjUXDRA3XL16QMEvh6llDrXlcZ6W0eTHQ+taHaVg/JKJTFs/AViO+6ZcpPCcQStbhYEL2HoS+vldw==", + "peerDependencies": { + "filepond": ">=1.x <5.x" + } + }, + "node_modules/filepond-plugin-image-edit": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/filepond-plugin-image-edit/-/filepond-plugin-image-edit-1.6.3.tgz", + "integrity": "sha512-5q3RDaVlfvyI346ckF1DfKw4uN5rfAmUCv7HCG30jBZcGmepg8hFyjVM71uZXYeb4AgLhpCkSPP8Immwig8bzw==", + "peerDependencies": { + "filepond": ">=3.7.2 <5.x" + } + }, + "node_modules/filepond-plugin-image-exif-orientation": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/filepond-plugin-image-exif-orientation/-/filepond-plugin-image-exif-orientation-1.0.11.tgz", + "integrity": "sha512-hLBc12Fk6Zkj3L8mSAn+elugHOqT5rLUbgVXQQIQjMe0FsGjtpoxqeVR6jt4IWHGat2L9sFAgU2TGmd1mqosCg==", + "peerDependencies": { + "filepond": ">=3.x <5.x" + } + }, + "node_modules/filepond-plugin-image-preview": { + "version": "4.6.12", + "resolved": "https://registry.npmjs.org/filepond-plugin-image-preview/-/filepond-plugin-image-preview-4.6.12.tgz", + "integrity": "sha512-Y8ETX5QVV0mbPB0586UH8AUmG9tZg8PuN5bdEAIlZVJFTct5ebViJ7+Am94/VhTPjLqZjBf1zmDq5JU6XRsZKw==", + "peerDependencies": { + "filepond": ">=4.x <5.x" + } + }, + "node_modules/filepond-plugin-image-transform": { + "version": "3.8.7", + "resolved": "https://registry.npmjs.org/filepond-plugin-image-transform/-/filepond-plugin-image-transform-3.8.7.tgz", + "integrity": "sha512-vgKwyIDG2y5twanf7YpqZvxkaLudTjwd9vRcoq5sQDB8egUlX5/NA0bQ0823pocrm0fjbFeetICu44mkqeDkIA==", + "peerDependencies": { + "filepond": ">=3.6.0 <5.x" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", diff --git a/package.json b/package.json index da56607..f5c8ac0 100644 --- a/package.json +++ b/package.json @@ -13,5 +13,13 @@ "postcss": "^8.4.38", "tailwindcss": "^3.4.3", "vite": "^5.0" + }, + "dependencies": { + "filepond": "^4.31.1", + "filepond-plugin-file-validate-size": "^2.2.8", + "filepond-plugin-file-validate-type": "^1.2.9", + "filepond-plugin-image-exif-orientation": "^1.0.11", + "filepond-plugin-image-preview": "^4.6.12", + "filepond-plugin-image-transform": "^3.8.7" } } diff --git a/resources/css/app.css b/resources/css/app.css index f515b5b..7ce27dd 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -1,3 +1,6 @@ +@import 'filepond/dist/filepond.min.css'; +@import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.css'; + @tailwind base; @tailwind components; @tailwind utilities; @@ -7,3 +10,23 @@ animation-play-state: paused; } } + +@media screen(sm) { + .filepond--item { + width: calc(50% - 0.5em); + } +} + +@media screen(md) { + .filepond--item { + width: calc(25% - 1em); + } +} + +.filepond--panel-root { + @apply bg-gray-50 dark:bg-gray-700 !important; +} + +.filepond--drop-label { + @apply text-gray-900 dark:text-white; +} \ No newline at end of file diff --git a/resources/js/app.js b/resources/js/app.js index e59d6a0..d19a23d 100644 --- a/resources/js/app.js +++ b/resources/js/app.js @@ -1 +1,25 @@ import './bootstrap'; +import * as FilePond from 'filepond'; +import FilePondPluginImageExifOrientation from 'filepond-plugin-image-exif-orientation'; +import FilePondPluginImagePreview from 'filepond-plugin-image-preview'; +import FilePondPluginFileValidateSize from 'filepond-plugin-file-validate-size'; +import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type'; +import FilePondPluginImageTransform from 'filepond-plugin-image-transform'; + +FilePond.registerPlugin(FilePondPluginImageExifOrientation); +FilePond.registerPlugin(FilePondPluginImagePreview); +FilePond.registerPlugin(FilePondPluginFileValidateSize); +FilePond.registerPlugin(FilePondPluginFileValidateType); +FilePond.registerPlugin(FilePondPluginImageTransform); + +window.FilePond = FilePond; + +document.addEventListener('alpine:init', () => { + Alpine.store('uploader', { + states: {}, + setState(state, value) { + console.log(state, value); + this.states[state] = value; + }, + }) +}); \ No newline at end of file diff --git a/resources/views/category/show.blade.php b/resources/views/category/show.blade.php index 406b8fb..2849692 100644 --- a/resources/views/category/show.blade.php +++ b/resources/views/category/show.blade.php @@ -5,17 +5,19 @@