Skip to content

Commit eb958ae

Browse files
committed
Merge branch 'main' of github.com:dcblogdev/laravel-admintw
# Conflicts: # app/Livewire/Admin/Users/Edit/Profile.php # composer.lock
2 parents 1d38a14 + e3b1582 commit eb958ae

18 files changed

+487
-463
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Actions;
6+
7+
use Carbon\Carbon;
8+
use DateTime;
9+
use Exception;
10+
11+
class GetFormattedDateAction
12+
{
13+
/**
14+
* @throws Exception
15+
*/
16+
public function __invoke(null|string|Carbon $date): string
17+
{
18+
if ($date === null) {
19+
return '';
20+
}
21+
22+
return is_string($date) ? (new DateTime($date))->format('Y-m-d') : $date->format('Y-m-d');
23+
}
24+
}

app/Actions/GetInitialsAction.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Actions;
6+
7+
class GetInitialsAction
8+
{
9+
public function __invoke(?string $name = ''): string
10+
{
11+
if (empty($name)) {
12+
return '';
13+
}
14+
15+
$parts = explode(' ', $name);
16+
17+
$initials = strtoupper($parts[0][0] ?? '');
18+
19+
if (count($parts) > 1) {
20+
$initials .= strtoupper(end($parts)[0] ?? '');
21+
}
22+
23+
return $initials;
24+
}
25+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Actions\Images;
6+
7+
use Illuminate\Support\Facades\Storage;
8+
9+
class DeleteImageAction
10+
{
11+
public function __invoke(string $path, string $disk = 'public'): void
12+
{
13+
Storage::disk($disk)->delete($path);
14+
}
15+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Actions\Images;
6+
7+
use Illuminate\Http\UploadedFile;
8+
use Intervention\Image\Drivers\Gd\Driver;
9+
use Intervention\Image\ImageManager;
10+
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
11+
12+
class ResizeImageAction
13+
{
14+
public function __invoke(string|TemporaryUploadedFile|UploadedFile $image, int $width = 800, ?int $height = null): string
15+
{
16+
$manager = new ImageManager(new Driver);
17+
18+
return $manager
19+
->read($image)
20+
->scale(width: $width, height: $height)
21+
->encode()
22+
->toString();
23+
}
24+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Actions\Images;
6+
7+
use Illuminate\Http\UploadedFile;
8+
use Illuminate\Support\Facades\Storage;
9+
use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;
10+
11+
class StoreUploadedImageAction
12+
{
13+
public function __invoke(TemporaryUploadedFile|UploadedFile $image, string $destinationFolder, string $disk = 'public', int $width = 800, ?int $height = null): string
14+
{
15+
$name = md5(random_int(1, 10).microtime()).'.jpg';
16+
$img = app(ResizeImageAction::class)($image, $width, $height);
17+
18+
$destinationFolder = rtrim($destinationFolder, DIRECTORY_SEPARATOR);
19+
20+
Storage::disk($disk)->put($destinationFolder.DIRECTORY_SEPARATOR.$name, $img);
21+
22+
return $destinationFolder.DIRECTORY_SEPARATOR.$name;
23+
}
24+
}

app/Http/Controllers/Admin/UploadController.php

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@
44

55
namespace App\Http\Controllers\Admin;
66

7+
use App\Actions\Images\StoreUploadedImageAction;
78
use App\Http\Controllers\Controller;
89
use Illuminate\Http\JsonResponse;
910
use Illuminate\Http\Request;
1011
use Illuminate\Http\UploadedFile;
11-
use Illuminate\Support\Facades\Storage;
12-
use Illuminate\Support\Str;
13-
use Intervention\Image\Facades\Image;
1412

1513
class UploadController extends Controller
1614
{
@@ -33,20 +31,11 @@ public function __invoke(Request $request): JsonResponse
3331
return response()->json(['error' => 'Invalid upload'], 400);
3432
}
3533

36-
$originalName = $file->getClientOriginalName();
37-
$extension = $file->getClientOriginalExtension();
38-
39-
$name = Str::slug(date('Y-m-d-h-i-s').'-'.pathinfo($originalName, PATHINFO_FILENAME));
40-
$image = Image::make($file);
41-
42-
$imageString = $image->stream()->__toString();
43-
$name = "$name.$extension";
44-
45-
Storage::disk('images')
46-
->put('uploads/'.$name, $imageString);
34+
/** @var UploadedFile $file */
35+
$image = (new StoreUploadedImageAction)($file, 'images', width: 400);
4736

4837
return response()->json([
49-
'url' => "/images/uploads/$name",
38+
'url' => storage_url($image),
5039
]);
5140
}
5241

app/Http/helpers.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,11 @@ function get_initials(string $name): string
6565
}
6666

6767
if (! function_exists('create_avatar')) {
68-
function create_avatar(string $name, string $filename, string $path): string
68+
function create_avatar(string $name, string $filename, string $path, string $disk = 'public'): string
6969
{
70-
$avatar = new LasseRafn\InitialAvatarGenerator\InitialAvatar;
71-
$source = $avatar->background('#000')->color('#fff')->name($name)->generate()->stream();
70+
Storage::disk($disk)->makeDirectory($path);
7271

73-
Storage::disk('public')->put($path.$filename, $source);
72+
Avatar::create($name)->save(Storage::disk($disk)->path($path.$filename), 100);
7473

7574
return $path.$filename;
7675
}

app/Livewire/Admin/Users/Edit/Profile.php

Lines changed: 32 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44

55
namespace App\Livewire\Admin\Users\Edit;
66

7+
use App\Actions\Images\DeleteImageAction;
8+
use App\Actions\Images\StoreUploadedImageAction;
79
use App\Models\User;
810
use Illuminate\Contracts\View\View;
9-
use Illuminate\Support\Facades\Storage;
1011
use Illuminate\Support\Str;
1112
use Illuminate\Validation\ValidationException;
12-
use Intervention\Image\Facades\Image;
1313
use Livewire\Component;
1414
use Livewire\WithFileUploads;
1515

@@ -34,13 +34,6 @@ class Profile extends Component
3434
*/
3535
protected $listeners = ['refreshProfile' => 'mount'];
3636

37-
/**
38-
* @var array<string, string>
39-
*/
40-
protected array $messages = [
41-
'name.required' => 'Name is required',
42-
];
43-
4437
public function mount(): void
4538
{
4639
$this->name = $this->user->name;
@@ -52,6 +45,29 @@ public function render(): View
5245
return view('livewire.admin.users.edit.profile');
5346
}
5447

48+
/**
49+
* @return array<string, array<int, string>>
50+
*/
51+
protected function rules(): array
52+
{
53+
return [
54+
'name' => [
55+
'required',
56+
'string',
57+
],
58+
'image' => [
59+
'nullable',
60+
'image',
61+
'mimes:png,jpg,gif',
62+
'max:5120',
63+
],
64+
'email' => [
65+
'required',
66+
'email',
67+
],
68+
];
69+
}
70+
5571
/**
5672
* @throws ValidationException
5773
*/
@@ -60,33 +76,21 @@ public function updated(string $propertyName): void
6076
$this->validateOnly($propertyName);
6177
}
6278

63-
public function update(): void
79+
public function update(DeleteImageAction $deleteImageAction, StoreUploadedImageAction $storeUploadedImageAction): void
6480
{
65-
$this->validate();
81+
$validated = $this->validate();
82+
83+
if (! blank($this->image)) {
6684

67-
if ($this->image !== '' && $this->image !== null) {
6885
if ($this->user->image !== null) {
69-
Storage::disk('public')->delete($this->user->image);
86+
$deleteImageAction($this->user->image);
7087
}
7188

72-
$token = md5(random_int(1, 10).microtime());
73-
$name = $token.'.jpg';
74-
$img = Image::make($this->image)->encode('jpg')->resize(100, null, function (object $constraint) {
75-
/** @phpstan-ignore-next-line */
76-
$constraint->aspectRatio();
77-
});
78-
$img->stream();
79-
80-
// @phpstan-ignore-next-line
81-
Storage::disk('public')->put('users/'.$name, $img);
82-
83-
$this->user->image = 'users/'.$name;
89+
$validated['image'] = $storeUploadedImageAction($this->image, 'users', width: 400);
8490
}
8591

86-
$this->user->name = $this->name;
8792
$this->user->slug = Str::slug($this->name);
88-
$this->user->email = $this->email;
89-
$this->user->save();
93+
$this->user->update($validated);
9094

9195
add_user_log([
9296
'title' => 'updated '.$this->name."'s profile",
@@ -100,27 +104,4 @@ public function update(): void
100104

101105
$this->dispatch('refreshAdminSettings');
102106
}
103-
104-
/**
105-
* @return array<string, array<int, string>>
106-
*/
107-
protected function rules(): array
108-
{
109-
return [
110-
'name' => [
111-
'required',
112-
'string',
113-
],
114-
'image' => [
115-
'nullable',
116-
'image',
117-
'mimes:png,jpg,gif',
118-
'max:5120',
119-
],
120-
'email' => [
121-
'required',
122-
'email',
123-
],
124-
];
125-
}
126107
}

app/Livewire/Admin/Users/Invite.php

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,59 @@
44

55
namespace App\Livewire\Admin\Users;
66

7+
use App\Actions\GetInitialsAction;
78
use App\Mail\Users\SendInviteMail;
89
use App\Models\Role;
910
use App\Models\User;
1011
use Illuminate\Contracts\View\View;
1112
use Illuminate\Support\Facades\Mail;
1213
use Illuminate\Support\Str;
1314
use Illuminate\Validation\ValidationException;
14-
use Livewire\Attributes\Rule;
15-
use Livewire\Attributes\Validate;
1615
use Livewire\Component;
1716
use Livewire\WithPagination;
1817

1918
class Invite extends Component
2019
{
2120
use WithPagination;
2221

23-
#[Rule('required', message: 'Please enter a name')]
2422
public string $name = '';
2523

26-
#[Rule('required', as: 'email', message: 'Please enter an email address')]
27-
#[Rule('email', message: 'The email must be a valid email address.')]
28-
#[Rule('unique:users,email')]
2924
public string $email = '';
3025

3126
/**
3227
* @var array<int>
3328
*/
34-
#[Validate('required', 'min:1', as: 'role', message: 'Please select at least one role')]
3529
public array $rolesSelected = [];
3630

31+
/**
32+
* @var array<string, array<int, string>>
33+
*/
34+
protected array $rules = [
35+
'name' => [
36+
'required',
37+
'string',
38+
],
39+
'email' => [
40+
'required',
41+
'string',
42+
'email',
43+
'unique:users,email',
44+
],
45+
'rolesSelected' => [
46+
'required',
47+
'min:1',
48+
],
49+
];
50+
51+
/**
52+
* @var array<string, string>
53+
*/
54+
protected array $messages = [
55+
'name.required' => 'Name is required',
56+
'email.required' => 'Email is required',
57+
'rolesSelected.required' => 'A role is required',
58+
];
59+
3760
/**
3861
* @throws ValidationException
3962
*/
@@ -49,7 +72,7 @@ public function render(): View
4972
return view('livewire.admin.users.invite', compact('roles'));
5073
}
5174

52-
public function store(): void
75+
public function store(GetInitialsAction $getInitialsAction): void
5376
{
5477
$this->validate();
5578

@@ -65,7 +88,7 @@ public function store(): void
6588
]);
6689

6790
// generate image
68-
$name = get_initials($user->name);
91+
$name = $getInitialsAction($user->name);
6992
$id = $user->id.'.png';
7093
$path = 'users/';
7194
$imagePath = create_avatar($name, $id, $path);

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
"blade-ui-kit/blade-heroicons": "^2.6",
1313
"dcblogdev/laravel-junie": "^1.0",
1414
"guzzlehttp/guzzle": "^7.9.3",
15-
"intervention/image": "^2.7.2",
15+
"intervention/image": "^3.7.2",
1616
"laracasts/flash": "^3.2.4",
1717
"laravel/framework": "^12.12.0",
1818
"laravel/sanctum": "^4.1.1",
1919
"laravel/tinker": "^2.10.1",
20-
"lasserafn/php-initial-avatar-generator": "^4.4",
20+
"laravolt/avatar": "^6.2",
2121
"livewire/livewire": "^3.6.3",
2222
"robthree/twofactorauth": "^1.8.2",
2323
"spatie/laravel-permission": "^6.17.0"

0 commit comments

Comments
 (0)