feat: ✨ adding a field to associate brands with users
This commit is contained in:
parent
fff623144a
commit
8caaff989c
6 changed files with 82 additions and 88 deletions
|
|
@ -5,11 +5,13 @@ namespace App\Http\Controllers\Bo;
|
|||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Users\StoreUserRequest;
|
||||
use App\Http\Requests\Bo\Users\UpdateUserRequest;
|
||||
use App\Models\Brand;
|
||||
use App\Models\User;
|
||||
use App\Traits\Controllers\UpdateModelPublished;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use Uwil\LaravelCommon\Helpers\CollectionHelper;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
|
|
@ -72,7 +74,8 @@ class UserController extends Controller
|
|||
*/
|
||||
public function create(User $user): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.users.create', ['userModel' => $user]);
|
||||
$brandModels = CollectionHelper::paginate(Brand::getUserAssociatedBrands(), $this->jsonItemPerPagination);
|
||||
return view('bo.pages.users.create', ['userModel' => $user, 'brandModels' => $brandModels]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -88,6 +91,7 @@ class UserController extends Controller
|
|||
$user->fill($request->validated());
|
||||
|
||||
if ($user->saveOrFail()) {
|
||||
$user->brands()->sync(collect($request->validated()['brand_id'])->pluck('id')->toArray());
|
||||
return redirect()->route('bo.users.edit', $user)
|
||||
->with('success', __('crud.messages.has_been_created', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
|
|
@ -108,7 +112,8 @@ class UserController extends Controller
|
|||
*/
|
||||
public function edit(User $user): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.users.edit', ['userModel' => $user]);
|
||||
$brandModels = CollectionHelper::paginate(Brand::getUserAssociatedBrands(), $this->jsonItemPerPagination);
|
||||
return view('bo.pages.users.edit', ['userModel' => $user, 'brandModels' => $brandModels]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -124,6 +129,7 @@ class UserController extends Controller
|
|||
$user->fill($request->validated());
|
||||
|
||||
if ($user->saveOrFail()) {
|
||||
$user->brands()->sync(collect($request->validated()['brand_id'])->pluck('id')->toArray());
|
||||
return redirect()->route('bo.users.edit', $user)
|
||||
->with('success', __('crud.messages.has_been_updated', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ namespace App\Http\Requests\Bo\Users;
|
|||
use App\Enums\Users\RoleEnum;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
|
||||
class StoreUserRequest extends FormRequest
|
||||
{
|
||||
|
|
@ -27,7 +26,8 @@ class StoreUserRequest extends FormRequest
|
|||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'published' => $this->published ? true : false
|
||||
'published' => $this->input('published') ? true : false,
|
||||
'brand_id' => $this->input('brand_id') ?: [],
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -39,19 +39,14 @@ class StoreUserRequest extends FormRequest
|
|||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'first_name' => 'required|string|min:3|max:255',
|
||||
'last_name' => 'required|string|min:3|max:255',
|
||||
'email' => 'required|email:rfc,strict,dns,spoof,filter|unique:users,email',
|
||||
'password' => [
|
||||
'required', 'required_with:password_confirmation', 'confirmed', 'max:255', Password::min(8)
|
||||
->letters()
|
||||
->mixedCase()
|
||||
->numbers()
|
||||
->symbols()
|
||||
->uncompromised()
|
||||
],
|
||||
'role' => ['required', new Enum(RoleEnum::class)],
|
||||
'published' => 'required|boolean',
|
||||
'first_name' => 'required|string|min:3|max:255',
|
||||
'last_name' => 'required|string|min:3|max:255',
|
||||
'email' => 'required|email:rfc,strict,dns,spoof,filter|unique:users,email',
|
||||
'role' => ['required', new Enum(RoleEnum::class)],
|
||||
'published' => 'required|boolean',
|
||||
'brand_id' => 'present|array',
|
||||
'brand_id.*' => 'sometimes|nullable|array',
|
||||
'brand_id.*.id' => 'sometimes|nullable|numeric|exists:brands,id',
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -63,12 +58,14 @@ class StoreUserRequest extends FormRequest
|
|||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'first_name' => trans('validation.attributes.first_name'),
|
||||
'last_name' => trans('validation.attributes.last_name'),
|
||||
'email' => trans('validation.attributes.email'),
|
||||
'password' => trans('validation.attributes.password'),
|
||||
'role' => trans('validation.attributes.role'),
|
||||
'published' => trans('validation.custom.publication')
|
||||
'first_name' => trans('validation.attributes.first_name'),
|
||||
'last_name' => trans('validation.attributes.last_name'),
|
||||
'email' => trans('validation.attributes.email'),
|
||||
'role' => trans('validation.attributes.role'),
|
||||
'published' => trans('validation.custom.publication'),
|
||||
'brand_id' => trans('models.classes.brands'),
|
||||
'brand_id.*' => trans('models.classes.brands'),
|
||||
'brand_id.*.id' => trans('models.classes.brands'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace App\Http\Requests\Bo\Users;
|
||||
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
|
||||
class UpdateUserRequest extends StoreUserRequest
|
||||
{
|
||||
/**
|
||||
|
|
@ -14,11 +12,8 @@ class UpdateUserRequest extends StoreUserRequest
|
|||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'published' => $this->published ? true : false,
|
||||
'password' => $this->password ? $this->password : $this->route('user')->password,
|
||||
'password_confirmation' => $this->password_confirmation ?
|
||||
$this->password_confirmation :
|
||||
$this->route('user')->password
|
||||
'published' => $this->input('published') ? true : false,
|
||||
'brand_id' => $this->input('brand_id') ?: [],
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -29,19 +24,15 @@ class UpdateUserRequest extends StoreUserRequest
|
|||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
/** @var \App\Models\User $userModel */
|
||||
$userModel = request()->route()->parameter('user');
|
||||
|
||||
return array_merge(parent::rules(), [
|
||||
'email' => [
|
||||
'required',
|
||||
'string',
|
||||
'email:rfc,strict,dns,spoof,filter',
|
||||
'unique:users,email,' . $this->route('user')->id . ',id',
|
||||
],
|
||||
'password' => [
|
||||
'required', 'required_with:password_confirmation', 'confirmed', 'max:255', Password::min(8)
|
||||
->letters()
|
||||
->mixedCase()
|
||||
->numbers()
|
||||
->symbols()
|
||||
->uncompromised()
|
||||
'unique:users,email,' . $userModel->getKey(),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ class Brand extends Model
|
|||
*/
|
||||
public function users(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(User::class, 'brand_users');
|
||||
return $this->belongsToMany(Brand::class, 'brand_users', 'brand_id', 'user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -122,6 +122,6 @@ class User extends Authenticatable
|
|||
*/
|
||||
public function brands(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Brand::class, 'brand_users');
|
||||
return $this->belongsToMany(Brand::class, 'brand_users', 'user_id', 'brand_id');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,39 +90,6 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- PASSWORD --}}
|
||||
<div class="col-12 mb-3">
|
||||
<fieldset class="h-100 border p-3">
|
||||
<legend>{{ __('Mot de passe') }}</legend>
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
@include('bo.partials.inputs.varchar-password', [
|
||||
'id' => 'userPassword',
|
||||
'label' => __('Mot de passe de l\':model', ['model' => __('models.classes.user')]),
|
||||
'name' => 'password',
|
||||
'hasWordCounter' => true,
|
||||
'required' => !$userModel->exists,
|
||||
'model' => null,
|
||||
'helper' => __(
|
||||
'Doît respecter certaines contraintes (8 caractères minimum, lettres, chiffres, caractères spéciaux).'),
|
||||
])
|
||||
</div>
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
@include('bo.partials.inputs.varchar-password', [
|
||||
'id' => 'userPassword_confirmation',
|
||||
'label' => __('Confirmation du mot de passe de l\':model', [
|
||||
'model' => __('models.classes.user'),
|
||||
]),
|
||||
'name' => 'password_confirmation',
|
||||
'hasWordCounter' => true,
|
||||
'required' => !$userModel->exists,
|
||||
'model' => null,
|
||||
'helper' => __('Doît correspondre au mot de passe saisi précédemment.'),
|
||||
])
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- STATUS --}}
|
||||
<div class="col-12 col-md-6 mb-3">
|
||||
<fieldset class="h-100 border p-3">
|
||||
|
|
@ -140,6 +107,36 @@
|
|||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
{{-- BRAND --}}
|
||||
<div class="col-12 col-md-6 pb-3">
|
||||
<fieldset class="h-100 border p-3" id="userRoleFieldset">
|
||||
<legend>{{ str(__('models.classes.brands'))->ucfirst() }}</legend>
|
||||
<div class="row">
|
||||
@include('bo.partials.inputs.search-belongs-to-dropdown', [
|
||||
'id' => 'questionBrand',
|
||||
'label' => __(':model associées', [
|
||||
'model' => str(__('models.classes.brands'))->ucfirst(),
|
||||
]),
|
||||
'name' => 'brand_id',
|
||||
'relation' => 'brands',
|
||||
'model' => $userModel,
|
||||
'targetClass' => 'App\Models\Brand',
|
||||
'modelListPaginate' => $brandModels ?? [],
|
||||
'constructedRoute' => route('bo.brands.json-paginate'),
|
||||
'fieldName' => 'name',
|
||||
'multiple' => true,
|
||||
'required' => true,
|
||||
'disabled' => false,
|
||||
'placeholder' => __('Rechercher une :model', [
|
||||
'model' => str(__('models.classes.brands'))->singular(),
|
||||
]),
|
||||
'helper' => __('Sélectionner des :model qui seront associées parmis la liste.', [
|
||||
'model' => __('models.classes.brands'),
|
||||
]),
|
||||
])
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col text-center">
|
||||
<p><b>{{ __('* Champs obligatoires') }}</b></p>
|
||||
|
|
@ -151,23 +148,26 @@
|
|||
<script nonce="{{ $nonce }}">
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
// Submit button clone.
|
||||
const submit = document.getElementById('formSubmit')
|
||||
submitClone = document.getElementById('formSubmitClone');
|
||||
const submit = document.getElementById('formSubmit');
|
||||
const submitClone = document.getElementById('formSubmitClone');
|
||||
submitClone.addEventListener('click', (event) => {
|
||||
event.preventDefault();
|
||||
submit.click('');
|
||||
})
|
||||
submit.click();
|
||||
});
|
||||
|
||||
// If we edit the password, the confirmation is required.
|
||||
const passwordInput = document.getElementById('userPassword');
|
||||
const confirmPasswordInput = document.getElementById('userPassword_confirmation');
|
||||
passwordInput.addEventListener('input', () => {
|
||||
if (passwordInput.value !== '') {
|
||||
confirmPasswordInput.required = true;
|
||||
} else {
|
||||
confirmPasswordInput.required = false;
|
||||
}
|
||||
})
|
||||
// If the role is marketing, need brands associated.
|
||||
const selectRole = document.getElementById('userRole');
|
||||
const userRoleFieldset = document.getElementById('userRoleFieldset');
|
||||
selectRole.addEventListener('change', (event) => {
|
||||
updateBrandsFieldsetStatus(Number(event.target.value));
|
||||
});
|
||||
updateBrandsFieldsetStatus(Number("{{ $userModel->role?->value() ?? \App\Enums\Users\RoleEnum::conceptor->value() }}"));
|
||||
function updateBrandsFieldsetStatus(value) {
|
||||
const marketingValue = {{ \App\Enums\Users\RoleEnum::marketing->value() }};
|
||||
const condition = value !== marketingValue;
|
||||
userRoleFieldset.disabled = condition;
|
||||
userRoleFieldset.className = `h-100 border p-3 ${condition ? 'd-none' : ''}`;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue