Added the ability to save user settings.
This commit is contained in:
24
app/Dto/Request/Private/Profile/UpdateSettings.php
Normal file
24
app/Dto/Request/Private/Profile/UpdateSettings.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace App\Dto\Request\Private\Profile;
|
||||
|
||||
use App\Dto\Request\Dto;
|
||||
use App\Enums\Lang;
|
||||
|
||||
final readonly class UpdateSettings extends Dto
|
||||
{
|
||||
public function __construct(
|
||||
private ?Lang $lang,
|
||||
private ?string $timezone
|
||||
) { }
|
||||
|
||||
public function getLang(): ?Lang
|
||||
{
|
||||
return $this->lang;
|
||||
}
|
||||
|
||||
public function getTimezone(): ?string
|
||||
{
|
||||
return $this->timezone;
|
||||
}
|
||||
}
|
46
app/Enums/Lang.php
Normal file
46
app/Enums/Lang.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
enum Lang: int
|
||||
{
|
||||
case Ru = 1;
|
||||
case En = 2;
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::Ru => 'Русский',
|
||||
self::En => 'English'
|
||||
};
|
||||
}
|
||||
|
||||
public function getLocale(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::Ru => 'ru',
|
||||
self::En => 'en'
|
||||
};
|
||||
}
|
||||
|
||||
public static function toArray(): array
|
||||
{
|
||||
$choices = [];
|
||||
foreach (self::cases() as $lang) {
|
||||
$choices[] = [
|
||||
'name' => $lang->name,
|
||||
'value' => $lang->value,
|
||||
'title' => $lang->getTitle(),
|
||||
'locale' => $lang->getLocale()
|
||||
];
|
||||
}
|
||||
return $choices;
|
||||
}
|
||||
|
||||
public static function toCollection(): Collection
|
||||
{
|
||||
return collect(self::toArray());
|
||||
}
|
||||
}
|
24
app/Helpers/Helpers.php
Normal file
24
app/Helpers/Helpers.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace App\Helpers;
|
||||
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
final readonly class Helpers
|
||||
{
|
||||
public static function getTimeZoneList(): Collection
|
||||
{
|
||||
return Cache::rememberForever('timezones_list_collection', function () {
|
||||
$timezone = [];
|
||||
foreach (timezone_identifiers_list(\DateTimeZone::ALL) as $key => $value) {
|
||||
$timezone[$value] = $value . ' (UTC ' . now($value)->format('P') . ')';
|
||||
}
|
||||
return collect($timezone)->sortKeys();
|
||||
});
|
||||
}
|
||||
|
||||
public static function getUserTimeZone() {
|
||||
return auth()->user()?->timezone ?? config('app.user_timezone');
|
||||
}
|
||||
}
|
@@ -2,8 +2,11 @@
|
||||
|
||||
namespace App\Http\Controllers\Private;
|
||||
|
||||
use App\Enums\Lang;
|
||||
use App\Helpers\Helpers;
|
||||
use App\Http\Requests\Private\Profile\UpdatePasswordRequest;
|
||||
use App\Http\Requests\Private\Profile\UpdateRequest;
|
||||
use App\Http\Requests\Private\Profile\UpdateSettingsRequest;
|
||||
use App\Services\Private\ProfileService;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -25,7 +28,9 @@ final class ProfileController extends Controller
|
||||
public function settings(Request $request): View
|
||||
{
|
||||
return view('private/profile/settings', [
|
||||
'user' => $request->user()
|
||||
'user' => $request->user(),
|
||||
'languages' => Lang::toCollection()->pluck(value: 'title', key: 'value')->toArray(),
|
||||
'timezone' => Helpers::getTimeZoneList()->toArray(),
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -52,4 +57,16 @@ final class ProfileController extends Controller
|
||||
}
|
||||
return redirect()->route('profile.edit')->withSuccess($result->getMessage());
|
||||
}
|
||||
|
||||
public function updateSettings(UpdateSettingsRequest $request): RedirectResponse
|
||||
{
|
||||
$data = $request->getDto();
|
||||
$user = $request->user();
|
||||
|
||||
$result = $this->profileService->updateSettings($data, $user);
|
||||
if ($result->isError()) {
|
||||
return redirect()->back()->withInput()->withErrors($result->getMessage());
|
||||
}
|
||||
return redirect()->route('profile.settings')->withSuccess($result->getMessage());
|
||||
}
|
||||
}
|
||||
|
38
app/Http/Requests/Private/Profile/UpdateSettingsRequest.php
Normal file
38
app/Http/Requests/Private/Profile/UpdateSettingsRequest.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Private\Profile;
|
||||
|
||||
use App\Contracts\FormRequestDto;
|
||||
use App\Dto\Request\Private\Profile\UpdateSettings;
|
||||
use App\Enums\Lang;
|
||||
use App\Helpers\Helpers;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
|
||||
final class UpdateSettingsRequest extends FormRequest implements FormRequestDto
|
||||
{
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'lang' => ['nullable', new Enum(Lang::class)],
|
||||
'timezone' => ['nullable', Rule::in(Helpers::getTimeZoneList()->keys()->toArray())]
|
||||
];
|
||||
}
|
||||
|
||||
public function getDto(): UpdateSettings
|
||||
{
|
||||
$lang = $this->input('lang', null);
|
||||
if (!is_null($lang)) {
|
||||
$lang = Lang::from((int) $lang);
|
||||
}
|
||||
|
||||
return new UpdateSettings(
|
||||
lang: $lang,
|
||||
timezone: $this->input('timezone', null),
|
||||
);
|
||||
}
|
||||
}
|
@@ -3,6 +3,7 @@
|
||||
namespace App\Models;
|
||||
|
||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use App\Enums\Lang;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
@@ -34,7 +35,7 @@ final class User extends Authenticatable
|
||||
'password',
|
||||
'timezone',
|
||||
'is_active',
|
||||
'locale',
|
||||
'lang',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -54,7 +55,8 @@ final class User extends Authenticatable
|
||||
*/
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
'is_active' => 'boolean'
|
||||
'is_active' => 'boolean',
|
||||
'lang' => Lang::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
@@ -4,6 +4,7 @@ namespace App\Services\Private;
|
||||
|
||||
use App\Dto\Request\Private\Profile\Update;
|
||||
use App\Dto\Request\Private\Profile\UpdatePassword;
|
||||
use App\Dto\Request\Private\Profile\UpdateSettings;
|
||||
use App\Models\User;
|
||||
use App\ServiceResults\ServiceResultError;
|
||||
use App\ServiceResults\ServiceResultSuccess;
|
||||
@@ -40,4 +41,19 @@ final class ProfileService extends Service
|
||||
}
|
||||
return $this->ok(__('The password has been changed'));
|
||||
}
|
||||
|
||||
public function updateSettings(UpdateSettings $update, User $user): ServiceResultError | ServiceResultSuccess
|
||||
{
|
||||
try {
|
||||
$data = [
|
||||
'lang' => $update->getLang(),
|
||||
'timezone' => $update->getTimezone(),
|
||||
];
|
||||
$this->userCommandHandler->handleUpdate($user, $data);
|
||||
} catch (\Throwable $e) {
|
||||
report($e->getMessage());
|
||||
return $this->errService($e->getMessage());
|
||||
}
|
||||
return $this->ok(__('The settings have been saved'));
|
||||
}
|
||||
}
|
||||
|
54
app/View/Components/Private/Forms/Select.php
Normal file
54
app/View/Components/Private/Forms/Select.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace App\View\Components\Private\Forms;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\View\View;
|
||||
|
||||
final class Select extends Form
|
||||
{
|
||||
/**
|
||||
* @param string $title
|
||||
* @param string $name
|
||||
* @param array $list = [ [key => value], ... ]
|
||||
* @param null|string $value
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly string $title,
|
||||
private readonly string $name,
|
||||
private readonly array $list,
|
||||
private readonly ?string $value = ''
|
||||
) { }
|
||||
|
||||
protected function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
private function getTitle(): string
|
||||
{
|
||||
return Str::ucfirst($this->title);
|
||||
}
|
||||
|
||||
private function getValue(): string
|
||||
{
|
||||
return (string) old($this->getRequestName(), $this->value);
|
||||
}
|
||||
|
||||
private function getList(): array
|
||||
{
|
||||
return $this->list;
|
||||
}
|
||||
|
||||
public function render(): View
|
||||
{
|
||||
return view('private.components.forms.select', [
|
||||
'title' => $this->getTitle(),
|
||||
'name' => $this->getName(),
|
||||
'requestName' => $this->getRequestName(),
|
||||
'list' => $this->getList(),
|
||||
'value' => $this->getValue()
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user