From e6839a71c89ae84aefe4538d953f13a449965d25 Mon Sep 17 00:00:00 2001 From: Alexis Gousseau Date: Fri, 25 Jul 2025 13:08:42 +0200 Subject: [PATCH] feat: :sparkles: set authorized countries in settings #42 --- .../Controllers/Fo/Auth/LoginController.php | 30 +- .../Bo/Settings/UpdateSettingsRequest.php | 82 +++--- .../Fo/Customers/CreateAccountRequest.php | 90 +++--- app/Models/Settings.php | 68 +++-- ...authorized_countries_in_settings_table.php | 33 +++ database/seeders/Mandatory/SettingsSeeder.php | 3 +- resources/lang/en/validation.php | 21 +- resources/lang/fr/validation.php | 4 +- .../SelectMultipleEnumComponent.vue | 261 ++++++++++++++++++ .../pages/settings/form-inputs.blade.php | 21 ++ .../inputs/select-multiple-enum.blade.php | 29 +- 11 files changed, 510 insertions(+), 132 deletions(-) create mode 100644 database/migrations/2025_08_05_163038_add_authorized_countries_in_settings_table.php create mode 100644 resources/ts/components/SelectMultipleEnumComponent.vue diff --git a/app/Http/Controllers/Fo/Auth/LoginController.php b/app/Http/Controllers/Fo/Auth/LoginController.php index 01d94eb..7de2e19 100644 --- a/app/Http/Controllers/Fo/Auth/LoginController.php +++ b/app/Http/Controllers/Fo/Auth/LoginController.php @@ -3,10 +3,11 @@ namespace App\Http\Controllers\Fo\Auth; use App\Http\Controllers\Controller; +use App\Models\Customer; +use App\Models\Settings; use App\Providers\RouteServiceProvider; use Illuminate\Contracts\Auth\StatefulGuard; use Illuminate\Contracts\View\View; -use Illuminate\Database\Eloquent\Model; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Foundation\Auth\ThrottlesLogins; use Illuminate\Http\Request; @@ -56,19 +57,30 @@ class LoginController extends Controller } /** - * The user has been authenticated. + * Check if the authenticated user can access the game * - * @param \Illuminate\Http\Request $request - * @param \Illuminate\Database\Eloquent\Model $user + * @param \Illuminate\Http\Request $request + * @param \App\Models\Customer $user * @return void * @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing, Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed */ - protected function authenticated(Request $request, Model $user): void + protected function authenticated(Request $request, Customer $user): void { - /** @var \App\Models\Customer $user */ - $user->last_connection = \now(); - $user->saveOrFail(); - Session::flash('info', trans('Vous êtes à présent connecté')); + /** @var \LDC\LDCCRM\Models\Customer $crmCustomer */ + $crmCustomer = $user->api_data; + + /** @var \App\Models\Settings */ + $settings = app(Settings::class); + $countries = $settings->authorized_countries; + + if (count($countries) && !in_array($crmCustomer->country->value, $countries)) { + $this->logout($request); + Session::flash('info', trans('Ce jeu n\'est pas disponible dans votre pays')); + } else { + $user->last_connection = \now(); + $user->saveOrFail(); + Session::flash('info', trans('Vous êtes à présent connecté')); + } } /** diff --git a/app/Http/Requests/Bo/Settings/UpdateSettingsRequest.php b/app/Http/Requests/Bo/Settings/UpdateSettingsRequest.php index f9b265c..37156d9 100644 --- a/app/Http/Requests/Bo/Settings/UpdateSettingsRequest.php +++ b/app/Http/Requests/Bo/Settings/UpdateSettingsRequest.php @@ -6,6 +6,8 @@ use App\Lib\Helpers\ToolboxHelper; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Support\Arr; use Illuminate\Support\Facades\Gate; +use Illuminate\Validation\Rule; +use LDC\LDCCRM\Enums\Country; class UpdateSettingsRequest extends FormRequest { @@ -14,7 +16,7 @@ class UpdateSettingsRequest extends FormRequest * * @return boolean */ - public function authorize() + public function authorize(): bool { return Gate::check('update', $this->route('settings')); } @@ -25,26 +27,27 @@ class UpdateSettingsRequest extends FormRequest * @return void * @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh */ - protected function prepareForValidation() + protected function prepareForValidation(): void { // phpcs:enable $this->merge([ // Checkboxes. - 'notify_prize_sent' => $this->boolean('notify_prize_sent'), - 'use_ean_codes' => $this->boolean('use_ean_codes'), - 'activated_teaser' => $this->boolean('activated_teaser'), - 'activated_close_page' => $this->boolean('activated_close_page'), - 'discounts_activated' => $this->boolean('discounts_activated'), - 'winning_proof' => $this->boolean('winning_proof'), + 'notify_prize_sent' => $this->boolean('notify_prize_sent'), + 'use_ean_codes' => $this->boolean('use_ean_codes'), + 'activated_teaser' => $this->boolean('activated_teaser'), + 'activated_close_page' => $this->boolean('activated_close_page'), + 'discounts_activated' => $this->boolean('discounts_activated'), + 'winning_proof' => $this->boolean('winning_proof'), // Arrays. - 'notification_emails' => collect($this->input('notification_emails'))->filter()->all(), + 'notification_emails' => collect($this->input('notification_emails'))->filter()->all(), + 'authorized_countries' => collect($this->input('authorized_countries'))->filter()->all(), // Remove some dates if the checkbox is uncheck. 'close_page_active_date' => $this->input('activated_close_page') ? $this->input('close_page_active_date') : null, // Remove discounts datas if the discount checkbox is uncheck. - 'discounts_site' => $this->input('discounts_activated') ? $this->input('discounts_site') : null, - 'discounts_campaign' => $this->input('discounts_activated') ? $this->input('discounts_campaign') : null, - 'web_coupons' => collect($this->input('web_coupons'))->filter()->all(), + 'discounts_site' => $this->input('discounts_activated') ? $this->input('discounts_site') : null, + 'discounts_campaign' => $this->input('discounts_activated') ? $this->input('discounts_campaign') : null, + 'web_coupons' => collect($this->input('web_coupons'))->filter()->all(), ]); } @@ -53,7 +56,7 @@ class UpdateSettingsRequest extends FormRequest * * @return array */ - public function rules() + public function rules(): array { return [ 'name' => 'required|string|min:3|max:255', @@ -105,9 +108,9 @@ class UpdateSettingsRequest extends FormRequest $fail, (object)[ 'maxHeight' => 409, - 'maxWith' => 920, + 'maxWith' => 920, 'minHeight' => 409, - 'minWith' => 920 + 'minWith' => 920 ] ); } @@ -116,6 +119,12 @@ class UpdateSettingsRequest extends FormRequest 'notification_emails' => 'required|array|min:1', 'notification_emails.*' => 'email:rfc,spoof,dns', + 'authorized_countries' => 'sometimes|array|max:' . count(Country::getValidCountries()), + 'authorized_countries.*' => [ + 'sometimes', + Rule::in(Country::getValidCountries()) + ], + 'winning_proof' => 'required|boolean', ]; } @@ -128,33 +137,36 @@ class UpdateSettingsRequest extends FormRequest public function attributes(): array { return [ - 'name' => trans('validation.attributes.name'), - 'company' => trans('validation.custom.company'), - 'start_date' => trans('validation.custom.start_date'), - 'end_date' => trans('validation.custom.end_date'), - 'nb_participation_player' => trans('validation.custom.nb_participation_player'), - 'nb_participation_ip' => trans('validation.custom.nb_participation_ip'), - 'nb_unique_code_use' => trans('validation.custom.nb_unique_code_use'), - 'use_ean_codes' => trans('validation.custom.use_ean_codes'), - 'activated_teaser' => trans('validation.custom.activated_teaser'), - 'activated_close_page' => trans('validation.custom.activated_close_page'), - 'close_page_active_date' => trans('validation.custom.close_page_active_date'), - 'redirect_close' => trans('validation.custom.redirect_close'), - 'winning_proof' => trans('validation.custom.winning_proof'), - 'discounts_activated' => trans('validation.custom.discounts_activated'), - 'discounts_site' => trans('validation.custom.discounts_site'), - 'discounts_campaign' => trans('validation.custom.discounts_campaign'), - 'notify_prize_sent' => trans('validation.custom.notify_prize_sent'), + 'name' => trans('validation.attributes.name'), + 'company' => trans('validation.custom.company'), + 'start_date' => trans('validation.custom.start_date'), + 'end_date' => trans('validation.custom.end_date'), + 'nb_participation_player' => trans('validation.custom.nb_participation_player'), + 'nb_participation_ip' => trans('validation.custom.nb_participation_ip'), + 'nb_unique_code_use' => trans('validation.custom.nb_unique_code_use'), + 'use_ean_codes' => trans('validation.custom.use_ean_codes'), + 'activated_teaser' => trans('validation.custom.activated_teaser'), + 'activated_close_page' => trans('validation.custom.activated_close_page'), + 'close_page_active_date' => trans('validation.custom.close_page_active_date'), + 'redirect_close' => trans('validation.custom.redirect_close'), + 'winning_proof' => trans('validation.custom.winning_proof'), + 'discounts_activated' => trans('validation.custom.discounts_activated'), + 'discounts_site' => trans('validation.custom.discounts_site'), + 'discounts_campaign' => trans('validation.custom.discounts_campaign'), + 'notify_prize_sent' => trans('validation.custom.notify_prize_sent'), - 'web_coupons' => trans('Tableau des coupons'), + 'web_coupons' => trans('Tableau des coupons'), 'web_coupons.*.web_coupon_identifiant' => trans('Identifiant coupon :index'), 'web_coupons.*.percentage' => trans('Pourcentage :index'), 'web_coupons.*.face_value' => trans('Valeur faciale :index'), 'web_coupons.*.valid_on' => trans('Valable sur :index'), 'web_coupons.*.img_name' => trans('Nom image :index'), - 'notification_emails' => trans('Tableau des email à notifier'), - 'notification_emails.*.email' => trans('validation.attributes.email') + 'notification_emails' => trans('Tableau des email à notifier'), + 'notification_emails.*.email' => trans('validation.attributes.email'), + + 'authorized_countries' => trans('Tableau des pays éligibles au jeu'), + 'authorized_countries.*' => trans('validation.custom.authorized_countries'), ]; } } diff --git a/app/Http/Requests/Fo/Customers/CreateAccountRequest.php b/app/Http/Requests/Fo/Customers/CreateAccountRequest.php index e86a953..8fafcbe 100644 --- a/app/Http/Requests/Fo/Customers/CreateAccountRequest.php +++ b/app/Http/Requests/Fo/Customers/CreateAccountRequest.php @@ -2,6 +2,7 @@ namespace App\Http\Requests\Fo\Customers; +use App\Models\Settings; use App\Repositories\Fo\CrmRepository; use App\Rules\IsAdult; use Illuminate\Foundation\Http\FormRequest; @@ -20,7 +21,7 @@ class CreateAccountRequest extends FormRequest * * @return boolean */ - public function authorize() + public function authorize(): bool { return Auth::guard('frontend')->check(); } @@ -30,10 +31,10 @@ class CreateAccountRequest extends FormRequest * * @return void */ - public function prepareForValidation() + public function prepareForValidation(): void { $this->merge([ - 'phone' => $this->input('phone'), + 'phone' => $this->input('phone'), 'opt_in' => $this->boolean('opt_in'), 'ok_cgv' => $this->boolean('ok_cgv') ]); @@ -44,9 +45,12 @@ class CreateAccountRequest extends FormRequest * * @return array */ - public function rules() + public function rules(): array { - /** @var \App\Models\Customer */ + /** @var \App\Models\Settings $settings */ + $settings = app(Settings::class); + + /** @var \App\Models\Customer|null */ $authUser = auth('frontend')->user(); $countryCode = null; @@ -55,43 +59,43 @@ class CreateAccountRequest extends FormRequest (new CrmRepository())->fetchCrmCustomer($authUser)->country->value : 0); $countryRules = match ($countryCode) { Country::belgium()->value => [ - 'phone' => 'phone:BE', + 'phone' => 'phone:BE', 'postal_code' => 'postal_code:BE', ], Country::luxembourg()->value => [ - 'phone' => 'phone:LU', + 'phone' => 'phone:LU', 'postal_code' => 'postal_code:LU', ], default => [ - 'phone' => 'phone:FR', + 'phone' => 'phone:FR', 'postal_code' => 'postal_code:FR', ] }; return [ - 'lastname' => 'required|string|max:255', - 'firstname' => 'required|string|max:255', - 'phone' => [ + 'lastname' => 'required|string|max:255', + 'firstname' => 'required|string|max:255', + 'phone' => [ 'nullable', 'max:255', $countryRules['phone'], ], - 'address' => 'required|string|min:1|max:255', - 'address2' => 'nullable|string|min:1|max:255', + 'address' => 'required|string|min:1|max:255', + 'address2' => 'nullable|string|min:1|max:255', 'postal_code' => [ 'required', 'string', 'min:1', $countryRules['postal_code'], ], - 'city' => 'required|string|min:2|max:255', - 'birth_date' => ['required', new IsAdult(trans('Vous devez être majeur pour vous inscrire.'))], - 'country' => [ + 'city' => 'required|string|min:2|max:255', + 'birth_date' => ['required', new IsAdult(trans('Vous devez être majeur pour vous inscrire.'))], + 'country' => [ 'required', new EnumIsValidRule(Country::class), - Rule::in(Country::getValidCountries()) + Rule::in($settings->getAuthorizedCountries()), ], - 'email' => [ + 'email' => [ 'required', 'email:rfc,dns,spoof', 'max:255', @@ -104,14 +108,14 @@ class CreateAccountRequest extends FormRequest }, 'unique:customers,email', ], - 'password' => [ + 'password' => [ 'required', 'confirmed', Password::min(8)->mixedCase() ->numbers()->symbols()->uncompromised() ], - 'ok_cgv' => 'accepted', - 'opt_in' => 'required|boolean', + 'ok_cgv' => 'accepted', + 'opt_in' => 'required|boolean', ]; } @@ -120,23 +124,23 @@ class CreateAccountRequest extends FormRequest * * @return array */ - public function attributes() + public function attributes(): array { return [ - 'lastname' => trans('validation.attributes.first_name'), - 'firstname' => trans('validation.attributes.first_name'), - 'phone' => trans('validation.attributes.phone'), - 'address' => trans('validation.attributes.line_address_1'), - 'address2' => trans('validation.attributes.line_address_2'), - 'country' => trans('validation.attributes.country'), - 'postal_code' => trans('validation.attributes.postal_code'), - 'city' => trans('validation.attributes.city'), - 'birth_date' => trans('validation.attributes.date_of_birth'), - 'email' => trans('validation.attributes.email'), - 'password' => trans('validation.attributes.password'), + 'lastname' => trans('validation.attributes.first_name'), + 'firstname' => trans('validation.attributes.first_name'), + 'phone' => trans('validation.attributes.phone'), + 'address' => trans('validation.attributes.line_address_1'), + 'address2' => trans('validation.attributes.line_address_2'), + 'country' => trans('validation.attributes.country'), + 'postal_code' => trans('validation.attributes.postal_code'), + 'city' => trans('validation.attributes.city'), + 'birth_date' => trans('validation.attributes.date_of_birth'), + 'email' => trans('validation.attributes.email'), + 'password' => trans('validation.attributes.password'), 'password_confirmation' => trans('validation.attributes.password_confirmation'), - 'ok_cgv' => trans('conditions d\'utilisation'), - 'opt_in' => trans('newsletter'), + 'ok_cgv' => trans('conditions d\'utilisation'), + 'opt_in' => trans('newsletter'), ]; } @@ -145,17 +149,17 @@ class CreateAccountRequest extends FormRequest * * @return array */ - public function messages() + public function messages(): array { $messages = [ - 'postal_code' => trans('validation.postal_code', [ + 'postal_code' => trans('validation.postal_code', [ 'countries' => \implode(', ', Country::getValidCountriesLabel()), - 'examples' => 72000 + 'examples' => 72000 ]), - 'phone.phone' => trans('validation.phone', [ + 'phone.phone' => trans('validation.phone', [ 'countries' => \implode(', ', Country::getValidCountriesLabel()) ]), - 'email.unique' => trans('Un compte existe déjà avec cette adresse.'), + 'email.unique' => trans('Un compte existe déjà avec cette adresse.'), 'ok_cgv.accepted' => trans('Vous devez accepter les conditions d\'utilisation du site pour continuer.') ]; @@ -165,7 +169,7 @@ class CreateAccountRequest extends FormRequest [ 'postal_code' => trans('validation.postal_code', [ 'countries' => Country::belgium()->label, - 'examples' => 1000 + 'examples' => 1000 ]), ] ), @@ -174,7 +178,7 @@ class CreateAccountRequest extends FormRequest [ 'postal_code' => trans('validation.postal_code', [ 'countries' => Country::luxembourg()->label, - 'examples' => 1111 + 'examples' => 1111 ]), ] ), @@ -189,7 +193,7 @@ class CreateAccountRequest extends FormRequest array_search(Country::luxembourg()->label, Country::getValidCountriesLabel()), ] )), - 'examples' => 72000 + 'examples' => 72000 ]), ] ), diff --git a/app/Models/Settings.php b/app/Models/Settings.php index 2cafd35..39b501e 100644 --- a/app/Models/Settings.php +++ b/app/Models/Settings.php @@ -11,6 +11,7 @@ use Carbon\CarbonInterval; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Cache; +use LDC\LDCCRM\Enums\Country; /** * Settings. @@ -36,6 +37,7 @@ use Illuminate\Support\Facades\Cache; * @property string $discounts_campaign Discount MesBr campaign * @property array<\App\Lib\Discount> $web_coupons Array of web coupons * @property array $notification_emails Array of email to notify when there's a winnner + * @property array $authorized_countries All countries eligible to participate. * @property boolean $winning_proof Is the winning proof needed * @property-read \Illuminate\Support\Carbon $created_at Creation Date. * @property-read \Illuminate\Support\Carbon $updated_at Last update Date. @@ -75,6 +77,7 @@ class Settings extends Model 'discounts_site', 'discounts_campaign', 'web_coupons', + 'authorized_countries', 'notification_emails', 'winning_proof', 'analytics', @@ -87,17 +90,18 @@ class Settings extends Model * @var array */ protected $casts = [ - 'notify_prize_sent' => 'bool', - 'use_ean_codes' => 'bool', - 'activated_teaser' => 'bool', - 'activated_close_page' => 'bool', - 'discounts_activated' => 'bool', - 'winning_proof' => 'bool', - 'start_date' => 'datetime', - 'end_date' => 'datetime', + 'notify_prize_sent' => 'bool', + 'use_ean_codes' => 'bool', + 'activated_teaser' => 'bool', + 'activated_close_page' => 'bool', + 'discounts_activated' => 'bool', + 'winning_proof' => 'bool', + 'start_date' => 'datetime', + 'end_date' => 'datetime', 'close_page_active_date' => 'datetime', - 'web_coupons' => AsArrayOfDiscount::class, - 'notification_emails' => 'array', + 'web_coupons' => AsArrayOfDiscount::class, + 'authorized_countries' => 'array', + 'notification_emails' => 'array', ]; // * EVENTS @@ -159,23 +163,23 @@ class Settings extends Model { /** @var \App\Models\Settings */ $settings = app(Settings::class); - if (!(bool)Prize::getCached()->count()) { + if (!(bool) Prize::getCached()->count()) { report(new \RuntimeException('Need prizes to enable the game')); return false; } - if (!(bool)Cache::remember('codes.count', CarbonInterval::day(), fn () => Code::query()->count())) { + if (!(bool) Cache::remember('codes.count', CarbonInterval::day(), fn() => Code::query()->count())) { report(new \RuntimeException('Need codes to enable the game')); return false; } - if (!(bool)InstantWin::getCached()->count()) { + if (!(bool) InstantWin::getCached()->count()) { report(new \RuntimeException('Need instant win to enable the game')); return false; } - if ($settings->use_ean_codes and !(bool)Product::getCached()->count()) { + if ($settings->use_ean_codes and !(bool) Product::getCached()->count()) { report(new \RuntimeException('Need products to enable the game using ean codes')); return false; } - if ($settings->discounts_activated and !(bool)collect($this->web_coupons)->count()) { + if ($settings->discounts_activated and !(bool) collect($this->web_coupons)->count()) { report(new \RuntimeException('Need MesBr coupons to enable the game using discounts')); return false; } @@ -194,7 +198,7 @@ class Settings extends Model public function gameHasBegun(): Attribute { return Attribute::make( - get: fn (): bool => $this->start_date->lte(now()) + get: fn(): bool => $this->start_date->lte(now()) ); } @@ -208,7 +212,7 @@ class Settings extends Model public function gameHasEnded(): Attribute { return Attribute::make( - get: fn (): bool => $this->game_has_begun and $this->end_date->lte(now()) + get: fn(): bool => $this->game_has_begun and $this->end_date->lte(now()) ); } @@ -222,7 +226,7 @@ class Settings extends Model public function gameIsOpen(): Attribute { return Attribute::make( - get: fn (): bool => $this->game_has_begun and !$this->game_has_ended + get: fn(): bool => $this->game_has_begun and !$this->game_has_ended ); } @@ -236,7 +240,7 @@ class Settings extends Model public function shouldDisplayTeaserPage(): Attribute { return Attribute::make( - get: fn (): bool => !$this->game_has_begun and + get: fn(): bool => !$this->game_has_begun and !$this->game_has_ended and $this->activated_teaser ); @@ -252,13 +256,37 @@ class Settings extends Model public function shouldDisplayEndPage(): Attribute { return Attribute::make( - get: fn (): bool => $this->game_has_begun and + get: fn(): bool => $this->game_has_begun and $this->game_has_ended and $this->activated_close_page and $this->close_page_active_date->gte(now()) ); } + /** + * Get all authorized countries. + * + * @return \Illuminate\Support\Collection + */ + public function getAuthorizedCountries(): \Illuminate\Support\Collection + { + /** @var \App\Models\Settings $settings */ + $settings = app(Settings::class); + if (count($settings->authorized_countries)) { + // * Authorized countries defined in settings. + $countries = collect(Country::toArray()) + ->filter(fn($enum) => in_array($enum->value, $settings->authorized_countries)); + } else { + // * Only DROM-COM + France. + $franceCountries = collect(Country::getValidCountries()) + ->filter(fn($enum) => !in_array($enum, [Country::belgium(), Country::luxembourg()])); + $otherCountries = collect(Country::getValidCountries()) + ->filter(fn($enum) => !$franceCountries->contains($enum)); + $countries = $franceCountries->merge($otherCountries); + } + return $countries; + } + // * RELATIONS /** diff --git a/database/migrations/2025_08_05_163038_add_authorized_countries_in_settings_table.php b/database/migrations/2025_08_05_163038_add_authorized_countries_in_settings_table.php new file mode 100644 index 0000000..069e67a --- /dev/null +++ b/database/migrations/2025_08_05_163038_add_authorized_countries_in_settings_table.php @@ -0,0 +1,33 @@ +json('authorized_countries')->after('discounts_campaign') + ->comment('All countries eligible to participate.'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down(): void + { + Schema::table('settings', function (Blueprint $table) { + $table->dropColumn('authorized_countries'); + }); + } +}; diff --git a/database/seeders/Mandatory/SettingsSeeder.php b/database/seeders/Mandatory/SettingsSeeder.php index 7f6af9f..ab0f1ca 100644 --- a/database/seeders/Mandatory/SettingsSeeder.php +++ b/database/seeders/Mandatory/SettingsSeeder.php @@ -30,9 +30,10 @@ class SettingsSeeder extends Seeder $settings->notify_prize_sent = false; $settings->redirect_close = "https://example.test"; $settings->discounts_activated = false; + $settings->authorized_countries = []; $settings->notification_emails = []; - $settings->winning_proof = 0; $settings->web_coupons = []; + $settings->winning_proof = 0; $settings->save(); } } diff --git a/resources/lang/en/validation.php b/resources/lang/en/validation.php index fd2fc21..56ab93d 100644 --- a/resources/lang/en/validation.php +++ b/resources/lang/en/validation.php @@ -220,17 +220,18 @@ return [ 'female' => 'of the ', 'vowel' => 'of the ' ], - 'event' => 'event', - 'model' => 'target element', - 'order' => 'order', - 'publication' => 'publication', - 'activated' => 'activated', - 'target' => 'target', - 'static_page_type' => 'static page type', - 'seo_title' => 'SEO title', - 'seo_description' => 'SEO description', + 'event' => 'event', + 'model' => 'target element', + 'order' => 'order', + 'publication' => 'publication', + 'activated' => 'activated', + 'target' => 'target', + 'static_page_type' => 'static page type', + 'seo_title' => 'SEO title', + 'seo_description' => 'SEO description', + 'authorized_countries' => 'eligible countries at game', - 'postal_code' => 'the :attribute field accepts postal codes from the following + 'postal_code' => 'the :attribute field accepts postal codes from the following :countries such as :examples', ], ]; diff --git a/resources/lang/fr/validation.php b/resources/lang/fr/validation.php index c36d4d3..8ded7fd 100644 --- a/resources/lang/fr/validation.php +++ b/resources/lang/fr/validation.php @@ -108,7 +108,8 @@ return [ 'mixed' => 'Le champ :attribute doit contenir au moins une majuscule et une minuscule.', 'numbers' => 'Le champ :attribute doit contenir au moins un chiffre.', 'symbols' => 'Le champ :attribute doit contenir au moins un symbole.', - 'uncompromised' => 'La valeur du champ :attribute est apparue dans une fuite de données. Veuillez choisir une valeur différente.', + 'uncompromised' => 'La valeur du champ :attribute est apparue dans une fuite de données. + Veuillez choisir une valeur différente.', ], 'present' => 'Le champ :attribute doit être présent.', 'prohibited' => 'Le champ :attribute est interdit.', @@ -274,6 +275,7 @@ return [ 'game_rules' => 'règlement du jeu', 'notify_prize_sent' => 'notification de lot envoyé au participant', 'comment' => 'commentaire', + 'authorized_countries' => 'pays éligibles au jeu', 'barcode' => 'code-barres du produit', 'ticket' => 'ticket de caisse avec la date', diff --git a/resources/ts/components/SelectMultipleEnumComponent.vue b/resources/ts/components/SelectMultipleEnumComponent.vue new file mode 100644 index 0000000..26c0535 --- /dev/null +++ b/resources/ts/components/SelectMultipleEnumComponent.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/resources/views/pages/settings/form-inputs.blade.php b/resources/views/pages/settings/form-inputs.blade.php index 8fecf62..a752eec 100644 --- a/resources/views/pages/settings/form-inputs.blade.php +++ b/resources/views/pages/settings/form-inputs.blade.php @@ -134,6 +134,27 @@ {{-- Force next columns to break to new line --}}
+ {{-- AUTHORIZED_COUNTRIES --}} +
+
+ {{ str(__('validation.custom.authorized_countries'))->ucfirst() }} +
+ @php $itemsList = collect(\LDC\LDCCRM\Enums\Country::getValidCountries())->values(); @endphp + @include('back::partials.inputs.select-multiple-enum', [ + 'name' => 'authorized_countries', + 'label' => str(__('validation.custom.authorized_countries'))->ucfirst(), + 'placeholder' => str(__('rechercher parmi les :field', ['field' => __('validation.custom.authorized_countries')]))->ucfirst(), + 'model' => $settingsModel ?? null, + 'itemsList' => $itemsList, + 'itemLimit' => [0, count($itemsList)], + 'helper' => sprintf('%s %s', __('crud.minicrud.enum_select', [ + 'enum' => str(__('validation.custom.authorized_countries'))->ucfirst(), + ]), __('Laisser vide afin de ne pas appliquer de restrictions.')), + 'required' => false, + ]) +
+
+
{{-- NB_PARTICIPATION_PLAYER --}}
diff --git a/resources/views/partials/inputs/select-multiple-enum.blade.php b/resources/views/partials/inputs/select-multiple-enum.blade.php index c0b7c82..9cda55e 100644 --- a/resources/views/partials/inputs/select-multiple-enum.blade.php +++ b/resources/views/partials/inputs/select-multiple-enum.blade.php @@ -1,16 +1,19 @@ @php -$data = [ - "name" => $name, - "label" => $label, - "value" => $value ?? [], - "placeholder" => $placeholder, - "itemsSelected" => $itemsSelected, - "itemsList" => $itemsList, - "itemLimit" => $itemLimit, - "showSpecificItem" => $showSpecificItem ?? null, - "errors" => $errors->getBag("default")->getMessages() ?? [], - 'helper' => $helper, - 'require' => $require -]; + $values = collect(old($name, $model->{$name} ?? []))->values(); + $itemsSelected = collect($itemsList) + ->filter(fn($item) => $values->filter(fn($value) => intval($value) === $item->value)->count()) + ->values(); + $data = [ + "name" => $name, + "label" => $label, + "placeholder" => $placeholder, + "itemsSelected" => $itemsSelected, + "itemsList" => $itemsList, + "itemLimit" => $itemLimit, + "showSpecificItem" => $showSpecificItem ?? null, + "errors" => $errors->getBag("default")->getMessages() ?? [], + 'helper' => $helper, + 'required' => $required + ]; @endphp