From 3bb3358bf63ed96e0fe2c8253bf1d2cfd910d1c1 Mon Sep 17 00:00:00 2001 From: Josh Manders Date: Fri, 11 Oct 2024 22:47:37 -0500 Subject: [PATCH] implement our own avatars --- app/Http/Controllers/AccountController.php | 6 ++ .../Controllers/DestroyAvatarController.php | 31 +++++++ app/Http/Resources/UserResource.php | 3 +- app/Models/User.php | 2 + composer.json | 1 + composer.lock | 67 ++++++++++++++- .../0001_01_01_000000_create_users_table.php | 2 + .../client/forms/UpdateAccountInformation.vue | 86 ++++++++++++++++++- resources/client/layouts/app.vue | 9 +- routes/web.php | 3 + 10 files changed, 201 insertions(+), 9 deletions(-) create mode 100644 app/Http/Controllers/DestroyAvatarController.php diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index 3b07744..6e07e61 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -7,6 +7,7 @@ use Illuminate\Http\Request; use \Illuminate\Validation\ValidationException; use Inertia\Response; +use NiftyCo\Attachments\Attachment; class AccountController extends Controller { @@ -22,12 +23,17 @@ public function update(Request $request) $request->validate([ 'name' => 'required|string', 'email' => 'required|email:rfc,dns', + 'avatar' => ['nullable', 'mimes:jpg,jpeg,png', 'max:1024'], ]); $user = auth()->user(); $user->fill($request->only('name')); + if ($request->hasFile('avatar')) { + $user->avatar = Attachment::fromFile($request->file('avatar'), folder: 'avatars'); + } + if ($user->email !== $request->email) { $user->fill([ 'confirmed_at' => null, diff --git a/app/Http/Controllers/DestroyAvatarController.php b/app/Http/Controllers/DestroyAvatarController.php new file mode 100644 index 0000000..91ce3ad --- /dev/null +++ b/app/Http/Controllers/DestroyAvatarController.php @@ -0,0 +1,31 @@ +user(); + + if (is_null($user->avatar)) { + return inertia()->location(route('account')); + } + + $avatar = $user->avatar->toArray(); + + Storage::disk($avatar['disk'])->delete($avatar['name']); + + $user->forceFill([ + 'avatar' => null, + ])->save(); + + return inertia()->location(route('account')); + } +} diff --git a/app/Http/Resources/UserResource.php b/app/Http/Resources/UserResource.php index fd4ce1d..7eb276f 100644 --- a/app/Http/Resources/UserResource.php +++ b/app/Http/Resources/UserResource.php @@ -17,7 +17,8 @@ public function toArray(Request $request): array return [ 'id' => $this->id, 'name' => $this->name, - 'email' => $this->email + 'email' => $this->email, + 'avatar' => $this->avatar ? $this->avatar->url : 'https://ui-avatars.com/api/?background=a0a0a0&name=' . urlencode($this->name), ]; } } diff --git a/app/Models/User.php b/app/Models/User.php index 3d79888..9046fd8 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -10,6 +10,7 @@ use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Foundation\Auth\Access\Authorizable; +use NiftyCo\Attachments\Casts\AsAttachment; class User extends Model implements AuthenticatableContract, AuthorizableContract { @@ -27,6 +28,7 @@ protected function casts(): array return [ 'confirmed_at' => 'datetime', 'password' => 'hashed', + 'avatar' => AsAttachment::class, ]; } diff --git a/composer.json b/composer.json index 9772012..cf1d295 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ "require": { "php": "^8.2", "aniftyco/laravel-advanced-db-sessions": "dev-master", + "aniftyco/laravel-attachments": "dev-master", "inertiajs/inertia-laravel": "^1.3", "laravel/framework": "^11.9", "laravel/tinker": "^2.9", diff --git a/composer.lock b/composer.lock index 6591ac4..fdd3e87 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": "aa257b2cbc75b97f75d28e7190524b7d", + "content-hash": "703abdde1807c88599e65936a9032f2b", "packages": [ { "name": "aniftyco/laravel-advanced-db-sessions", @@ -70,6 +70,68 @@ }, "time": "2024-10-10T00:22:52+00:00" }, + { + "name": "aniftyco/laravel-attachments", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/aniftyco/laravel-attachments.git", + "reference": "85f6145e4d05c982ea0275896e4a724563c0688d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aniftyco/laravel-attachments/zipball/85f6145e4d05c982ea0275896e4a724563c0688d", + "reference": "85f6145e4d05c982ea0275896e4a724563c0688d", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "orchestra/testbench": "^9.5", + "pestphp/pest": "^3.3" + }, + "default-branch": true, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "NiftyCo\\Attachments\\ServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "NiftyCo\\Attachments\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "NiftyCo, LLC", + "homepage": "https://aniftyco.com" + }, + { + "name": "Josh Manders", + "homepage": "https://x.com/joshmanders" + } + ], + "description": "Turn any field on your Eloquent models into attachments", + "homepage": "https://github.com/aniftyco/laravel-attachments", + "keywords": [ + "attachments", + "eloquent", + "laravel" + ], + "support": { + "issues": "https://github.com/aniftyco/laravel-attachments/issues", + "source": "https://github.com/aniftyco/laravel-attachments/tree/master" + }, + "time": "2024-10-08T00:24:02+00:00" + }, { "name": "brick/math", "version": "0.12.1", @@ -9446,7 +9508,8 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "aniftyco/laravel-advanced-db-sessions": 20 + "aniftyco/laravel-advanced-db-sessions": 20, + "aniftyco/laravel-attachments": 20 }, "prefer-stable": true, "prefer-lowest": false, diff --git a/database/migrations/0001_01_01_000000_create_users_table.php b/database/migrations/0001_01_01_000000_create_users_table.php index 83dfd67..bef7ff1 100644 --- a/database/migrations/0001_01_01_000000_create_users_table.php +++ b/database/migrations/0001_01_01_000000_create_users_table.php @@ -22,6 +22,8 @@ public function up(): void $table->string('role')->default(UserRole::CUSTOMER)->index(); + $table->jsonb('avatar')->nullable(); + $table->timestamp('confirmed_at')->nullable(); $table->timestamps(); $table->softDeletes(); diff --git a/resources/client/forms/UpdateAccountInformation.vue b/resources/client/forms/UpdateAccountInformation.vue index c61821a..066b56d 100644 --- a/resources/client/forms/UpdateAccountInformation.vue +++ b/resources/client/forms/UpdateAccountInformation.vue @@ -1,24 +1,73 @@