Added the ability to save user settings.

This commit is contained in:
2023-07-10 21:42:55 +06:00
parent b1c9dac3cc
commit 907bac5586
17 changed files with 278 additions and 8 deletions

View 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
View 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
View 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');
}
}

View File

@@ -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());
}
}

View 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),
);
}
}

View File

@@ -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,
];
/**

View File

@@ -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'));
}
}

View 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()
]);
}
}