diff --git a/.env.example b/.env.example index 6e6cd0a..e84f494 100644 --- a/.env.example +++ b/.env.example @@ -60,3 +60,9 @@ VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" # Sentry SENTRY_LARAVEL_DSN= + +# MAILS +MAIL_CONTACT_REMARK="equipe.web@ldc.fr" +MAIL_CONTACT_SPONSORING="equipe.web@ldc.fr" +MAIL_CONTACT_SERVICE="equipe.web@ldc.fr" +MAIL_CONTACT_OTHER="equipe.web@ldc.fr" diff --git a/app/Enums/Listen/ObjectEnum.php b/app/Enums/Listen/ObjectEnum.php new file mode 100644 index 0000000..86d4536 --- /dev/null +++ b/app/Enums/Listen/ObjectEnum.php @@ -0,0 +1,27 @@ +name => 'Contact Commercial ou remarque sur nos produits', + self::sponsoring->name => 'Demande de partenariat ou sponsoring', + self::service->name => 'Proposition de service au fournisseur', + self::other->name => 'Autre demande', + ]; +} diff --git a/app/Http/Controllers/Fo/StaticPageController.php b/app/Http/Controllers/Fo/StaticPageController.php index c26592e..9e0ffd9 100644 --- a/app/Http/Controllers/Fo/StaticPageController.php +++ b/app/Http/Controllers/Fo/StaticPageController.php @@ -2,12 +2,21 @@ namespace App\Http\Controllers\Fo; +use App\Enums\Listen\ObjectEnum; +use App\Enums\Slides\SliderTypeEnum; use App\Enums\StaticPageType; +use App\Enums\Testimonials\TypeEnum; use App\Http\Controllers\Controller; +use App\Http\Requests\Fo\ListenFormRequest; +use App\Mail\SendConfirmationMail; +use App\Mail\SendContactMail; use App\Models\HistoricalMilestone; use App\Models\Section; use App\Models\Site; +use App\Models\Slide; use App\Models\StaticPage; +use App\Models\Testimonial; +use Illuminate\Support\Facades\Mail; class StaticPageController extends Controller { @@ -25,6 +34,102 @@ class StaticPageController extends Controller ->get(); $siteModel = Site::query()->first(); - return view('fo.pages.unveil', compact('staticPageModel', 'sectionModels', 'historicalMilestoneModels', 'siteModel')); + return view('fo.pages.unveil', compact( + 'staticPageModel', + 'sectionModels', + 'historicalMilestoneModels', + 'siteModel' + )); + } + + /** + * Display the 'commitments' page. + * + * @return \Illuminate\Contracts\View\View + */ + public function commit(): \Illuminate\Contracts\View\View + { + $staticPageModel = StaticPage::query()->where('type', StaticPageType::we_commit)->first(); + $sectionModels = Section::query()->where('page_id', $staticPageModel->id)->get(); + $slideModels = Slide::query() + ->whereIn('slider', [SliderTypeEnum::better_life->value, SliderTypeEnum::respect_earth->value]) + ->get(); + $testimonialModels = Testimonial::query() + ->whereIn('type', [ + TypeEnum::breeding->value, + TypeEnum::better_life->value, + TypeEnum::respect_earth->value, + TypeEnum::feed->value, + TypeEnum::volena->value, + ]) + ->get(); + + return view('fo.pages.commitments', compact( + 'staticPageModel', + 'sectionModels', + 'slideModels', + 'testimonialModels' + )); + } + + /** + * Display the 'legals' page. + * + * @return \Illuminate\Contracts\View\View + */ + public function legals(): \Illuminate\Contracts\View\View + { + $staticPageModel = StaticPage::query()->where('type', StaticPageType::legals)->first(); + + return view('fo.pages.legals', compact( + 'staticPageModel', + )); + } + + /** + * Display the 'confidentiality' page. + * + * @return \Illuminate\Contracts\View\View + */ + public function confidentiality(): \Illuminate\Contracts\View\View + { + $staticPageModel = StaticPage::query()->where('type', StaticPageType::confidentiality)->first(); + + return view('fo.pages.confidentiality', compact( + 'staticPageModel', + )); + } + + /** + * Display the 'we_listen' page. + * + * @return \Illuminate\Contracts\View\View + */ + public function listen(): \Illuminate\Contracts\View\View + { + $staticPageModel = StaticPage::query()->where('type', StaticPageType::we_listen)->first(); + + return view('fo.pages.listen', compact( + 'staticPageModel', + )); + } + + /** + * Send listen form data. + * + * @param \App\Http\Requests\Fo\ListenFormRequest $request + * @return \Illuminate\Http\RedirectResponse + */ + public function listenForm(ListenFormRequest $request): \Illuminate\Http\RedirectResponse + { + Mail::to(config('mail.contact.' . ObjectEnum::make(intval($request->validated()['object']))->name())) + ->send(new SendContactMail((object)$request->validated())); + Mail::to($request->validated()['email'])->send(new SendConfirmationMail((object)$request->validated())); + + return redirect()->route('fo.listen') + ->with('success', trans( + 'Bonjour, votre message a bien été transmis, nous vous en remercions. Cordialement, l’équipe :appName.', + ['appName' => config('app.name')] + )); } } diff --git a/app/Http/Requests/Fo/.gitkeep b/app/Http/Requests/Fo/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/app/Http/Requests/Fo/ListenFormRequest.php b/app/Http/Requests/Fo/ListenFormRequest.php new file mode 100644 index 0000000..577eca2 --- /dev/null +++ b/app/Http/Requests/Fo/ListenFormRequest.php @@ -0,0 +1,114 @@ +merge([ + 'country' => $this->post('country') == null ? $this->post('country') : null, + 'accept_rules' => $this->boolean('accept_rules'), + 'send_data' => $this->boolean('send_data'), + ]); + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules(): array + { + ToolboxHelper::validateRecaptcha($this, \config('services.google.recaptcha.version')); + $rules = [ + 'first_name' => 'present|nullable|string|between:3,100', + 'last_name' => 'required|string|between:3,100', + 'society' => 'present|nullable|string|between:3,255', + 'email' => 'required|email:rfc,strict,dns,spoof,filter|max:255', + 'phone' => 'present|nullable|phone:FR|max:25', + 'postal_code' => 'present|nullable|postal_code:FR|max:25', + 'city' => 'present|nullable|string|between:3,20', + 'country' => ['present', 'nullable', new Enum(Country::class)], + 'address' => 'present|nullable|string|between:3,255', + 'object' => ['required', new Enum(ObjectEnum::class)], + 'message' => 'required|min:20|max:35656', + 'accept_rules' => 'required|boolean', + 'send_data' => 'required|boolean', + ]; + if ( + isset(request()->file) and + (request()->file->getClientMimeType() === "image/jpeg" || + request()->file->getClientMimeType() === "image/png") + ) { + $rules = \array_merge($rules, $this->pictureRules( + 'file', + 0, + 0, + 1920, + 1080, + true, + 3000, + )); + } elseif (isset(request()->file) and (request()->file->getClientMimeType() === "application/pdf")) { + $rules = \array_merge($rules, [ + //phpcs:ignore Generic.Files.LineLength.TooLong + 'file' => 'present|nullable|mimes:pdf' + ]); + } elseif ( + isset(request()->file) and + (request()->file->getClientMimeType() !== "application/pdf") and + (request()->file->getClientMimeType() !== "image/jpeg") and + (request()->file->getClientMimeType() !== "image/png") + ) { + $rules = \array_merge($rules, [ + 'file' => [ + // @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed + function ($attribute, $value, $fail) { + $fail(\trans('Le format du fichier doit être .jpg, .png ou .pdf')); + } + ], + ]); + } //end if + return $rules; + } + + /** + * Get custom attributes for validator errors. + * + * @return array + */ + public function attributes(): array + { + return [ + 'first_name' => trans('validation.attributes.first_name'), + 'last_name' => trans('validation.attributes.last_name'), + 'society' => trans('validation.attributes.society'), + 'email' => trans('validation.attributes.email'), + 'phone' => trans('validation.attributes.phone'), + 'postal_code' => trans('validation.attributes.postal_code'), + 'city' => trans('validation.attributes.city'), + 'country' => trans('validation.attributes.country'), + 'address' => trans('validation.attributes.address'), + 'object' => trans('validation.attributes.object'), + 'message' => trans('validation.attributes.message'), + 'file' => trans('validation.attributes.file'), + 'accept_rules' => trans('validation.attributes.custom.accept_rules'), + 'send_data' => trans('validation.attributes.custom.send_data'), + ]; + } +} diff --git a/app/Mail/SendConfirmationMail.php b/app/Mail/SendConfirmationMail.php new file mode 100644 index 0000000..afddc7b --- /dev/null +++ b/app/Mail/SendConfirmationMail.php @@ -0,0 +1,115 @@ +data = clone $data; + $this->sanitizeStringInputs(); + } + + /** + * Sanitizes user message + * + * ! This is not recursive ! + * * Prevent xss injection via markdown interpretation. + * + * La solution devrai etre de filtrer en sortie, mais il n'est pas possible de + * + * @return void + */ + private function sanitizeStringInputs(): void + { + // @phpstan-ignore-next-line + $this->data = (object)Arr::map((array)$this->data, function ($el) { + if (is_string($el)) { + $el = \htmlspecialchars(\strip_tags(Blade::render( + (string)Markdown::parse($el) + ))); + $el = Str::of($el)->replaceMatches( + '/[^\p{L}0-9\n\s\@\.\:\-\_\?\!\;\(\)\+\-\/\\\=]+/us', + '' + )->trim()->wordWrap(75, "\n", true)->toString(); + } + return $el; + }); + } + + /** + * Get the message envelope. + * + * @return \Illuminate\Mail\Mailables\Envelope + */ + public function envelope(): \Illuminate\Mail\Mailables\Envelope + { + return new Envelope( + subject: sprintf( + '%s - %s', + trans('Confirmation d\'envoi'), + config('app.name') + ), + ); + } + + /** + * Get the message content definition. + * + * @return \Illuminate\Mail\Mailables\Content + */ + public function content(): \Illuminate\Mail\Mailables\Content + { + return new Content( + markdown: 'emails.send-confirmation-form', + with: ['data' => $this->data], + ); + } +} + +/** + * @property \App\Enums\Contact\ObjectEnum $type + * @property string|null $first_name + * @property string $last_name + * @property string|null $phone + * @property string $email + * @property string|null $address + * @property string|null $city + * @property string|null $postal_code + * @property string $message + * @property boolean $terms + * @property \Illuminate\Http\UploadedFile|null $file + * @property \App\Models\Product|null $product + * @property \Carbon\Carbon|null $expiration_date + * @property integer|null $batch_number + * @phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses + */ +class ContactConfirmation extends \stdClass +{ +} diff --git a/app/Mail/SendContactMail.php b/app/Mail/SendContactMail.php new file mode 100644 index 0000000..3c42613 --- /dev/null +++ b/app/Mail/SendContactMail.php @@ -0,0 +1,133 @@ +data = clone $data; + $this->sanitizeStringInputs(); + } + + /** + * Sanitizes user message + * + * ! This is not recursive ! + * * Prevent xss injection via markdown interpretation. + * + * La solution devrai etre de filtrer en sortie, mais il n'est pas possible de + * + * @return void + */ + private function sanitizeStringInputs(): void + { + // @phpstan-ignore-next-line + $this->data = (object)Arr::map((array)$this->data, function ($el) { + if (is_string($el)) { + $el = \htmlspecialchars(\strip_tags(Blade::render( + (string)Markdown::parse($el) + ))); + $el = Str::of($el)->replaceMatches( + '/[^\p{L}0-9\n\s\@\.\:\-\_\?\!\;\(\)\+\-\/\\\=]+/us', + '' + )->trim()->wordWrap(75, "\n", true)->toString(); + } + return $el; + }); + } + + /** + * Get the message envelope. + * + * @return \Illuminate\Mail\Mailables\Envelope + */ + public function envelope(): \Illuminate\Mail\Mailables\Envelope + { + return new Envelope( + subject: sprintf( + '%s - %s', + ObjectEnum::make($this->data->object)->label(), + config('app.name') + ), + ); + } + + /** + * Get the message content definition. + * + * @return \Illuminate\Mail\Mailables\Content + */ + public function content(): \Illuminate\Mail\Mailables\Content + { + return new Content( + markdown: 'emails.send-contact-form', + with: ['data' => $this->data], + ); + } + + /** + * Get the attachments for the message. + * + * @return array + */ + public function attachments(): array + { + $attachments = []; + if (isset($this->data->file)) { + $attachments[] = Attachment::fromPath($this->data->file->getRealPath()) + ->as($this->data->file->getClientOriginalName()) + ->withMime($this->data->file->getClientMimeType()); + } + return $attachments; + } +} + +/** + * @property \App\Enums\Contact\ObjectEnum $type + * @property string|null $first_name + * @property string $last_name + * @property string|null $phone + * @property string $email + * @property string|null $address + * @property string|null $city + * @property string|null $postal_code + * @property string $message + * @property boolean $terms + * @property \Illuminate\Http\UploadedFile|null $file + * @property \App\Models\Product|null $product + * @property \Carbon\Carbon|null $expiration_date + * @property integer|null $batch_number + * @phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses + */ +class Contact extends \stdClass +{ +} diff --git a/composer.json b/composer.json index 0a591c1..9451ea5 100644 --- a/composer.json +++ b/composer.json @@ -12,13 +12,15 @@ ], "license": "MIT", "require": { - "php": "^8.3", + "php": "^8.2", + "axlon/laravel-postal-code-validation": "^3.5", "diglactic/laravel-breadcrumbs": "^8.0", "guzzlehttp/guzzle": "^7.2", "laravel/framework": "^10.0", "laravel/tinker": "^2.8", "laravel/ui": "^4.2", "mews/purifier": "^3.4", + "propaganistas/laravel-phone": "^5.1", "sentry/sentry-laravel": "*", "uwil/k8s-laravel": "^1.2" }, diff --git a/composer.lock b/composer.lock index d975051..5c43ad9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,75 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "150318c8c1215216b016bcfd8bf32e38", + "content-hash": "4abc1a69f6a5b3c69fe24c263352b72c", "packages": [ + { + "name": "axlon/laravel-postal-code-validation", + "version": "v3.5.0", + "source": { + "type": "git", + "url": "https://github.com/axlon/laravel-postal-code-validation.git", + "reference": "e8b0d70f0d2d00ca3f3b79f014d5dc1eaddd4746" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/axlon/laravel-postal-code-validation/zipball/e8b0d70f0d2d00ca3f3b79f014d5dc1eaddd4746", + "reference": "e8b0d70f0d2d00ca3f3b79f014d5dc1eaddd4746", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^5.5 || ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0", + "illuminate/support": "^5.5 || ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0", + "illuminate/validation": "^5.5 || ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^6.5 || ^7.0.1", + "mockery/mockery": "^1.3", + "phpunit/phpunit": "^8.5 || ^9.0 || ^10.0", + "symfony/var-exporter": "^4.0" + }, + "type": "library", + "extra": { + "laravel": { + "aliases": { + "PostalCodes": "\\Axlon\\PostalCodeValidation\\Support\\Facades\\PostalCodes" + }, + "providers": [ + "\\Axlon\\PostalCodeValidation\\ValidationServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Axlon\\PostalCodeValidation\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Choraimy Kroonstuiver", + "homepage": "https://github.com/axlon" + } + ], + "description": "Worldwide postal code validation for Laravel and Lumen", + "keywords": [ + "laravel", + "lumen", + "post code", + "postal code", + "validation", + "zip code" + ], + "support": { + "issues": "https://github.com/axlon/laravel-postal-code-validation/issues", + "source": "https://github.com/axlon/laravel-postal-code-validation/tree/v3.5.0" + }, + "time": "2024-01-24T21:58:02+00:00" + }, { "name": "brick/math", "version": "0.11.0", @@ -278,16 +345,16 @@ }, { "name": "doctrine/inflector", - "version": "2.0.9", + "version": "2.0.10", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "2930cd5ef353871c821d5c43ed030d39ac8cfe65" + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/2930cd5ef353871c821d5c43ed030d39ac8cfe65", - "reference": "2930cd5ef353871c821d5c43ed030d39ac8cfe65", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/5817d0659c5b50c9b950feb9af7b9668e2c436bc", + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc", "shasum": "" }, "require": { @@ -349,7 +416,7 @@ ], "support": { "issues": "https://github.com/doctrine/inflector/issues", - "source": "https://github.com/doctrine/inflector/tree/2.0.9" + "source": "https://github.com/doctrine/inflector/tree/2.0.10" }, "funding": [ { @@ -365,7 +432,7 @@ "type": "tidelift" } ], - "time": "2024-01-15T18:05:13+00:00" + "time": "2024-02-18T20:23:39+00:00" }, { "name": "doctrine/lexer", @@ -757,6 +824,132 @@ ], "time": "2023-10-12T05:21:21+00:00" }, + { + "name": "giggsey/libphonenumber-for-php", + "version": "8.13.31", + "source": { + "type": "git", + "url": "https://github.com/giggsey/libphonenumber-for-php.git", + "reference": "a4934bddda4672d12f21728e08bd575913bdc310" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/giggsey/libphonenumber-for-php/zipball/a4934bddda4672d12f21728e08bd575913bdc310", + "reference": "a4934bddda4672d12f21728e08bd575913bdc310", + "shasum": "" + }, + "require": { + "giggsey/locale": "^1.7|^2.0", + "php": ">=5.3.2", + "symfony/polyfill-mbstring": "^1.17" + }, + "require-dev": { + "pear/pear-core-minimal": "^1.9", + "pear/pear_exception": "^1.0", + "pear/versioncontrol_git": "^0.5", + "phing/phing": "^2.7", + "php-coveralls/php-coveralls": "^1.0|^2.0", + "symfony/console": "^2.8|^3.0|^v4.4|^v5.2", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "8.x-dev" + } + }, + "autoload": { + "psr-4": { + "libphonenumber\\": "src/" + }, + "exclude-from-classmap": [ + "/src/data/", + "/src/carrier/data/", + "/src/geocoding/data/", + "/src/timezone/data/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Joshua Gigg", + "email": "giggsey@gmail.com", + "homepage": "https://giggsey.com/" + } + ], + "description": "PHP Port of Google's libphonenumber", + "homepage": "https://github.com/giggsey/libphonenumber-for-php", + "keywords": [ + "geocoding", + "geolocation", + "libphonenumber", + "mobile", + "phonenumber", + "validation" + ], + "support": { + "issues": "https://github.com/giggsey/libphonenumber-for-php/issues", + "source": "https://github.com/giggsey/libphonenumber-for-php" + }, + "time": "2024-02-26T08:31:45+00:00" + }, + { + "name": "giggsey/locale", + "version": "2.5", + "source": { + "type": "git", + "url": "https://github.com/giggsey/Locale.git", + "reference": "e6d4540109a01dd2bc7334cdc842d6a6a67cf239" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/giggsey/Locale/zipball/e6d4540109a01dd2bc7334cdc842d6a6a67cf239", + "reference": "e6d4540109a01dd2bc7334cdc842d6a6a67cf239", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "require-dev": { + "ext-json": "*", + "pear/pear-core-minimal": "^1.9", + "pear/pear_exception": "^1.0", + "pear/versioncontrol_git": "^0.5", + "phing/phing": "^2.7", + "php-coveralls/php-coveralls": "^2.0", + "phpunit/phpunit": "^8.5|^9.5", + "symfony/console": "^5.0|^6.0", + "symfony/filesystem": "^5.0|^6.0", + "symfony/finder": "^5.0|^6.0", + "symfony/process": "^5.0|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Giggsey\\Locale\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joshua Gigg", + "email": "giggsey@gmail.com", + "homepage": "https://giggsey.com/" + } + ], + "description": "Locale functions required by libphonenumber-for-php", + "support": { + "issues": "https://github.com/giggsey/Locale/issues", + "source": "https://github.com/giggsey/Locale/tree/2.5" + }, + "time": "2023-11-01T17:19:48+00:00" + }, { "name": "graham-campbell/result-type", "version": "v1.1.2", @@ -1291,16 +1484,16 @@ }, { "name": "laravel/framework", - "version": "v10.44.0", + "version": "v10.46.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "1199dbe361787bbe9648131a79f53921b4148cf6" + "reference": "5e95946a8283a8d5c015035793f9c61c297e937f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/1199dbe361787bbe9648131a79f53921b4148cf6", - "reference": "1199dbe361787bbe9648131a79f53921b4148cf6", + "url": "https://api.github.com/repos/laravel/framework/zipball/5e95946a8283a8d5c015035793f9c61c297e937f", + "reference": "5e95946a8283a8d5c015035793f9c61c297e937f", "shasum": "" }, "require": { @@ -1493,20 +1686,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-02-13T16:01:16+00:00" + "time": "2024-02-27T16:46:54+00:00" }, { "name": "laravel/prompts", - "version": "v0.1.15", + "version": "v0.1.16", "source": { "type": "git", "url": "https://github.com/laravel/prompts.git", - "reference": "d814a27514d99b03c85aa42b22cfd946568636c1" + "reference": "ca6872ab6aec3ab61db3a61f83a6caf764ec7781" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/prompts/zipball/d814a27514d99b03c85aa42b22cfd946568636c1", - "reference": "d814a27514d99b03c85aa42b22cfd946568636c1", + "url": "https://api.github.com/repos/laravel/prompts/zipball/ca6872ab6aec3ab61db3a61f83a6caf764ec7781", + "reference": "ca6872ab6aec3ab61db3a61f83a6caf764ec7781", "shasum": "" }, "require": { @@ -1548,9 +1741,9 @@ ], "support": { "issues": "https://github.com/laravel/prompts/issues", - "source": "https://github.com/laravel/prompts/tree/v0.1.15" + "source": "https://github.com/laravel/prompts/tree/v0.1.16" }, - "time": "2023-12-29T22:37:42+00:00" + "time": "2024-02-21T19:25:27+00:00" }, { "name": "laravel/serializable-closure", @@ -2570,16 +2763,16 @@ }, { "name": "nikic/php-parser", - "version": "v5.0.0", + "version": "v5.0.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc" + "reference": "2218c2252c874a4624ab2f613d86ac32d227bc69" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4a21235f7e56e713259a6f76bf4b5ea08502b9dc", - "reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/2218c2252c874a4624ab2f613d86ac32d227bc69", + "reference": "2218c2252c874a4624ab2f613d86ac32d227bc69", "shasum": "" }, "require": { @@ -2622,9 +2815,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.1" }, - "time": "2024-01-07T17:17:35+00:00" + "time": "2024-02-21T19:24:10+00:00" }, { "name": "nunomaduro/termwind", @@ -2865,6 +3058,78 @@ ], "time": "2023-11-12T21:59:55+00:00" }, + { + "name": "propaganistas/laravel-phone", + "version": "5.1.1", + "source": { + "type": "git", + "url": "https://github.com/Propaganistas/Laravel-Phone.git", + "reference": "d8c0e5fbde9820e026595616a7a36074233a09c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Propaganistas/Laravel-Phone/zipball/d8c0e5fbde9820e026595616a7a36074233a09c6", + "reference": "d8c0e5fbde9820e026595616a7a36074233a09c6", + "shasum": "" + }, + "require": { + "giggsey/libphonenumber-for-php": "^7.0|^8.0", + "illuminate/contracts": "^9.0|^10.0", + "illuminate/support": "^9.0|^10.0", + "illuminate/validation": "^9.0|^10.0", + "php": "^8.0" + }, + "require-dev": { + "laravel/pint": "^1.4", + "nunomaduro/larastan": "^2.4", + "orchestra/testbench": "*", + "phpunit/phpunit": "^9.5.10" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Propaganistas\\LaravelPhone\\PhoneServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Propaganistas\\LaravelPhone\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Propaganistas", + "email": "Propaganistas@users.noreply.github.com" + } + ], + "description": "Adds phone number functionality to Laravel based on Google's libphonenumber API.", + "keywords": [ + "laravel", + "libphonenumber", + "phone", + "validation" + ], + "support": { + "issues": "https://github.com/Propaganistas/Laravel-Phone/issues", + "source": "https://github.com/Propaganistas/Laravel-Phone/tree/5.1.1" + }, + "funding": [ + { + "url": "https://github.com/Propaganistas", + "type": "github" + } + ], + "time": "2024-01-15T09:23:46+00:00" + }, { "name": "psr/clock", "version": "1.0.0", @@ -3761,16 +4026,16 @@ }, { "name": "symfony/console", - "version": "v6.4.3", + "version": "v6.4.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "2aaf83b4de5b9d43b93e4aec6f2f8b676f7c567e" + "reference": "0d9e4eb5ad413075624378f474c4167ea202de78" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/2aaf83b4de5b9d43b93e4aec6f2f8b676f7c567e", - "reference": "2aaf83b4de5b9d43b93e4aec6f2f8b676f7c567e", + "url": "https://api.github.com/repos/symfony/console/zipball/0d9e4eb5ad413075624378f474c4167ea202de78", + "reference": "0d9e4eb5ad413075624378f474c4167ea202de78", "shasum": "" }, "require": { @@ -3835,7 +4100,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.3" + "source": "https://github.com/symfony/console/tree/v6.4.4" }, "funding": [ { @@ -3851,7 +4116,7 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-02-22T20:27:10+00:00" }, { "name": "symfony/css-selector", @@ -3987,16 +4252,16 @@ }, { "name": "symfony/error-handler", - "version": "v6.4.3", + "version": "v6.4.4", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "6dc3c76a278b77f01d864a6005d640822c6f26a6" + "reference": "c725219bdf2afc59423c32793d5019d2a904e13a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/6dc3c76a278b77f01d864a6005d640822c6f26a6", - "reference": "6dc3c76a278b77f01d864a6005d640822c6f26a6", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/c725219bdf2afc59423c32793d5019d2a904e13a", + "reference": "c725219bdf2afc59423c32793d5019d2a904e13a", "shasum": "" }, "require": { @@ -4042,7 +4307,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.4.3" + "source": "https://github.com/symfony/error-handler/tree/v6.4.4" }, "funding": [ { @@ -4058,7 +4323,7 @@ "type": "tidelift" } ], - "time": "2024-01-29T15:40:36+00:00" + "time": "2024-02-22T20:27:10+00:00" }, { "name": "symfony/event-dispatcher", @@ -4282,16 +4547,16 @@ }, { "name": "symfony/http-foundation", - "version": "v6.4.3", + "version": "v6.4.4", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "5677bdf7cade4619cb17fc9e1e7b31ec392244a9" + "reference": "ebc713bc6e6f4b53f46539fc158be85dfcd77304" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/5677bdf7cade4619cb17fc9e1e7b31ec392244a9", - "reference": "5677bdf7cade4619cb17fc9e1e7b31ec392244a9", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/ebc713bc6e6f4b53f46539fc158be85dfcd77304", + "reference": "ebc713bc6e6f4b53f46539fc158be85dfcd77304", "shasum": "" }, "require": { @@ -4339,7 +4604,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.4.3" + "source": "https://github.com/symfony/http-foundation/tree/v6.4.4" }, "funding": [ { @@ -4355,20 +4620,20 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-02-08T15:01:18+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.4.3", + "version": "v6.4.5", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "9c6ec4e543044f7568a53a76ab1484ecd30637a2" + "reference": "f6947cb939d8efee137797382cb4db1af653ef75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/9c6ec4e543044f7568a53a76ab1484ecd30637a2", - "reference": "9c6ec4e543044f7568a53a76ab1484ecd30637a2", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f6947cb939d8efee137797382cb4db1af653ef75", + "reference": "f6947cb939d8efee137797382cb4db1af653ef75", "shasum": "" }, "require": { @@ -4417,7 +4682,7 @@ "symfony/process": "^5.4|^6.0|^7.0", "symfony/property-access": "^5.4.5|^6.0.5|^7.0", "symfony/routing": "^5.4|^6.0|^7.0", - "symfony/serializer": "^6.3|^7.0", + "symfony/serializer": "^6.4.4|^7.0.4", "symfony/stopwatch": "^5.4|^6.0|^7.0", "symfony/translation": "^5.4|^6.0|^7.0", "symfony/translation-contracts": "^2.5|^3", @@ -4452,7 +4717,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.4.3" + "source": "https://github.com/symfony/http-kernel/tree/v6.4.5" }, "funding": [ { @@ -4468,20 +4733,20 @@ "type": "tidelift" } ], - "time": "2024-01-31T07:21:29+00:00" + "time": "2024-03-04T21:00:47+00:00" }, { "name": "symfony/mailer", - "version": "v6.4.3", + "version": "v6.4.4", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "74412c62f88a85a41b61f0b71ab0afcaad6f03ee" + "reference": "791c5d31a8204cf3db0c66faab70282307f4376b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/74412c62f88a85a41b61f0b71ab0afcaad6f03ee", - "reference": "74412c62f88a85a41b61f0b71ab0afcaad6f03ee", + "url": "https://api.github.com/repos/symfony/mailer/zipball/791c5d31a8204cf3db0c66faab70282307f4376b", + "reference": "791c5d31a8204cf3db0c66faab70282307f4376b", "shasum": "" }, "require": { @@ -4532,7 +4797,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v6.4.3" + "source": "https://github.com/symfony/mailer/tree/v6.4.4" }, "funding": [ { @@ -4548,7 +4813,7 @@ "type": "tidelift" } ], - "time": "2024-01-29T15:01:07+00:00" + "time": "2024-02-03T21:33:47+00:00" }, { "name": "symfony/mime", @@ -5414,16 +5679,16 @@ }, { "name": "symfony/process", - "version": "v6.4.3", + "version": "v6.4.4", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "31642b0818bfcff85930344ef93193f8c607e0a3" + "reference": "710e27879e9be3395de2b98da3f52a946039f297" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/31642b0818bfcff85930344ef93193f8c607e0a3", - "reference": "31642b0818bfcff85930344ef93193f8c607e0a3", + "url": "https://api.github.com/repos/symfony/process/zipball/710e27879e9be3395de2b98da3f52a946039f297", + "reference": "710e27879e9be3395de2b98da3f52a946039f297", "shasum": "" }, "require": { @@ -5455,7 +5720,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.4.3" + "source": "https://github.com/symfony/process/tree/v6.4.4" }, "funding": [ { @@ -5471,7 +5736,7 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:51:35+00:00" + "time": "2024-02-20T12:31:00+00:00" }, { "name": "symfony/psr-http-message-bridge", @@ -5558,16 +5823,16 @@ }, { "name": "symfony/routing", - "version": "v6.4.3", + "version": "v6.4.5", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "3b2957ad54902f0f544df83e3d58b38d7e8e5842" + "reference": "7fe30068e207d9c31c0138501ab40358eb2d49a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/3b2957ad54902f0f544df83e3d58b38d7e8e5842", - "reference": "3b2957ad54902f0f544df83e3d58b38d7e8e5842", + "url": "https://api.github.com/repos/symfony/routing/zipball/7fe30068e207d9c31c0138501ab40358eb2d49a4", + "reference": "7fe30068e207d9c31c0138501ab40358eb2d49a4", "shasum": "" }, "require": { @@ -5621,7 +5886,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v6.4.3" + "source": "https://github.com/symfony/routing/tree/v6.4.5" }, "funding": [ { @@ -5637,7 +5902,7 @@ "type": "tidelift" } ], - "time": "2024-01-30T13:55:02+00:00" + "time": "2024-02-27T12:33:30+00:00" }, { "name": "symfony/service-contracts", @@ -5723,16 +5988,16 @@ }, { "name": "symfony/string", - "version": "v7.0.3", + "version": "v7.0.4", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "524aac4a280b90a4420d8d6a040718d0586505ac" + "reference": "f5832521b998b0bec40bee688ad5de98d4cf111b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/524aac4a280b90a4420d8d6a040718d0586505ac", - "reference": "524aac4a280b90a4420d8d6a040718d0586505ac", + "url": "https://api.github.com/repos/symfony/string/zipball/f5832521b998b0bec40bee688ad5de98d4cf111b", + "reference": "f5832521b998b0bec40bee688ad5de98d4cf111b", "shasum": "" }, "require": { @@ -5789,7 +6054,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.0.3" + "source": "https://github.com/symfony/string/tree/v7.0.4" }, "funding": [ { @@ -5805,20 +6070,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T15:41:16+00:00" + "time": "2024-02-01T13:17:36+00:00" }, { "name": "symfony/translation", - "version": "v6.4.3", + "version": "v6.4.4", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "637c51191b6b184184bbf98937702bcf554f7d04" + "reference": "bce6a5a78e94566641b2594d17e48b0da3184a8e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/637c51191b6b184184bbf98937702bcf554f7d04", - "reference": "637c51191b6b184184bbf98937702bcf554f7d04", + "url": "https://api.github.com/repos/symfony/translation/zipball/bce6a5a78e94566641b2594d17e48b0da3184a8e", + "reference": "bce6a5a78e94566641b2594d17e48b0da3184a8e", "shasum": "" }, "require": { @@ -5884,7 +6149,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v6.4.3" + "source": "https://github.com/symfony/translation/tree/v6.4.4" }, "funding": [ { @@ -5900,7 +6165,7 @@ "type": "tidelift" } ], - "time": "2024-01-29T13:11:52+00:00" + "time": "2024-02-20T13:16:58+00:00" }, { "name": "symfony/translation-contracts", @@ -6056,16 +6321,16 @@ }, { "name": "symfony/var-dumper", - "version": "v6.4.3", + "version": "v6.4.4", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "0435a08f69125535336177c29d56af3abc1f69da" + "reference": "b439823f04c98b84d4366c79507e9da6230944b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/0435a08f69125535336177c29d56af3abc1f69da", - "reference": "0435a08f69125535336177c29d56af3abc1f69da", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/b439823f04c98b84d4366c79507e9da6230944b1", + "reference": "b439823f04c98b84d4366c79507e9da6230944b1", "shasum": "" }, "require": { @@ -6121,7 +6386,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.3" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.4" }, "funding": [ { @@ -6137,7 +6402,7 @@ "type": "tidelift" } ], - "time": "2024-01-23T14:53:30+00:00" + "time": "2024-02-15T11:23:52+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -6774,16 +7039,16 @@ }, { "name": "doctrine/dbal", - "version": "3.8.1", + "version": "3.8.3", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "c9ea252cdce4da324ede3d6c5913dd89f769afd2" + "reference": "db922ba9436b7b18a23d1653a0b41ff2369ca41c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/c9ea252cdce4da324ede3d6c5913dd89f769afd2", - "reference": "c9ea252cdce4da324ede3d6c5913dd89f769afd2", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/db922ba9436b7b18a23d1653a0b41ff2369ca41c", + "reference": "db922ba9436b7b18a23d1653a0b41ff2369ca41c", "shasum": "" }, "require": { @@ -6799,12 +7064,12 @@ "doctrine/coding-standard": "12.0.0", "fig/log-test": "^1", "jetbrains/phpstorm-stubs": "2023.1", - "phpstan/phpstan": "1.10.57", + "phpstan/phpstan": "1.10.58", "phpstan/phpstan-strict-rules": "^1.5", "phpunit/phpunit": "9.6.16", "psalm/plugin-phpunit": "0.18.4", "slevomat/coding-standard": "8.13.1", - "squizlabs/php_codesniffer": "3.8.1", + "squizlabs/php_codesniffer": "3.9.0", "symfony/cache": "^5.4|^6.0|^7.0", "symfony/console": "^4.4|^5.4|^6.0|^7.0", "vimeo/psalm": "4.30.0" @@ -6867,7 +7132,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.8.1" + "source": "https://github.com/doctrine/dbal/tree/3.8.3" }, "funding": [ { @@ -6883,7 +7148,7 @@ "type": "tidelift" } ], - "time": "2024-02-03T17:33:49+00:00" + "time": "2024-03-03T15:55:06+00:00" }, { "name": "doctrine/deprecations", @@ -7454,16 +7719,16 @@ }, { "name": "kitloong/laravel-migrations-generator", - "version": "v6.11.0", + "version": "v6.11.1", "source": { "type": "git", "url": "https://github.com/kitloong/laravel-migrations-generator.git", - "reference": "220b5f17fcb16610a3e9757d68c197319c0f7444" + "reference": "0f007e86dce6e0cfd71dc0b757da18851c376c3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/kitloong/laravel-migrations-generator/zipball/220b5f17fcb16610a3e9757d68c197319c0f7444", - "reference": "220b5f17fcb16610a3e9757d68c197319c0f7444", + "url": "https://api.github.com/repos/kitloong/laravel-migrations-generator/zipball/0f007e86dce6e0cfd71dc0b757da18851c376c3b", + "reference": "0f007e86dce6e0cfd71dc0b757da18851c376c3b", "shasum": "" }, "require": { @@ -7476,8 +7741,8 @@ "require-dev": { "barryvdh/laravel-ide-helper": "^2.5", "friendsofphp/php-cs-fixer": "^2.19.0|^3.1", + "larastan/larastan": "^0.4|^0.5|^0.6|^0.7|^1.0|^2.0", "mockery/mockery": "^1.0", - "nunomaduro/larastan": "^0.4|^0.5|^0.6|^0.7|^1.0|^2.0", "orchestra/testbench": "^3.6|^4.0|^5.0|^6.0|^7.0|^8.0", "phpmd/phpmd": "^2.10", "slevomat/coding-standard": "^6.0|^7.0|^8.5", @@ -7517,7 +7782,7 @@ ], "support": { "issues": "https://github.com/kitloong/laravel-migrations-generator/issues", - "source": "https://github.com/kitloong/laravel-migrations-generator/tree/v6.11.0" + "source": "https://github.com/kitloong/laravel-migrations-generator/tree/v6.11.1" }, "funding": [ { @@ -7525,7 +7790,7 @@ "type": "custom" } ], - "time": "2023-10-10T13:55:26+00:00" + "time": "2024-02-06T14:42:33+00:00" }, { "name": "krlove/code-generator", @@ -7613,16 +7878,16 @@ }, { "name": "larastan/larastan", - "version": "v2.9.0", + "version": "v2.9.2", "source": { "type": "git", "url": "https://github.com/larastan/larastan.git", - "reference": "35fa9cbe1895e76215bbe74571a344f2705fbe01" + "reference": "a79b46b96060504b400890674b83f66aa7f5db6d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/larastan/larastan/zipball/35fa9cbe1895e76215bbe74571a344f2705fbe01", - "reference": "35fa9cbe1895e76215bbe74571a344f2705fbe01", + "url": "https://api.github.com/repos/larastan/larastan/zipball/a79b46b96060504b400890674b83f66aa7f5db6d", + "reference": "a79b46b96060504b400890674b83f66aa7f5db6d", "shasum": "" }, "require": { @@ -7639,6 +7904,7 @@ "phpstan/phpstan": "^1.10.50" }, "require-dev": { + "doctrine/coding-standard": "^12.0", "nikic/php-parser": "^4.17.1", "orchestra/canvas": "^7.11.1 || ^8.11.0 || ^9.0.0", "orchestra/testbench": "^7.33.0 || ^8.13.0 || ^9.0.0", @@ -7690,7 +7956,7 @@ ], "support": { "issues": "https://github.com/larastan/larastan/issues", - "source": "https://github.com/larastan/larastan/tree/v2.9.0" + "source": "https://github.com/larastan/larastan/tree/v2.9.2" }, "funding": [ { @@ -7710,7 +7976,7 @@ "type": "patreon" } ], - "time": "2024-02-13T11:49:22+00:00" + "time": "2024-02-27T03:16:03+00:00" }, { "name": "laravel-lang/attributes", @@ -8237,16 +8503,16 @@ }, { "name": "laravel/pint", - "version": "v1.13.11", + "version": "v1.14.0", "source": { "type": "git", "url": "https://github.com/laravel/pint.git", - "reference": "60a163c3e7e3346a1dec96d3e6f02e6465452552" + "reference": "6b127276e3f263f7bb17d5077e9e0269e61b2a0e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/pint/zipball/60a163c3e7e3346a1dec96d3e6f02e6465452552", - "reference": "60a163c3e7e3346a1dec96d3e6f02e6465452552", + "url": "https://api.github.com/repos/laravel/pint/zipball/6b127276e3f263f7bb17d5077e9e0269e61b2a0e", + "reference": "6b127276e3f263f7bb17d5077e9e0269e61b2a0e", "shasum": "" }, "require": { @@ -8299,20 +8565,20 @@ "issues": "https://github.com/laravel/pint/issues", "source": "https://github.com/laravel/pint" }, - "time": "2024-02-13T17:20:13+00:00" + "time": "2024-02-20T17:38:05+00:00" }, { "name": "laravel/sail", - "version": "v1.27.4", + "version": "v1.28.1", "source": { "type": "git", "url": "https://github.com/laravel/sail.git", - "reference": "3047e1a157fad968cc5f6e620d5cbe5c0867fffd" + "reference": "f84e444a3dbc1811803cd2a050bdd54ff6f5eef8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/sail/zipball/3047e1a157fad968cc5f6e620d5cbe5c0867fffd", - "reference": "3047e1a157fad968cc5f6e620d5cbe5c0867fffd", + "url": "https://api.github.com/repos/laravel/sail/zipball/f84e444a3dbc1811803cd2a050bdd54ff6f5eef8", + "reference": "f84e444a3dbc1811803cd2a050bdd54ff6f5eef8", "shasum": "" }, "require": { @@ -8361,7 +8627,7 @@ "issues": "https://github.com/laravel/sail/issues", "source": "https://github.com/laravel/sail" }, - "time": "2024-02-08T15:24:21+00:00" + "time": "2024-02-23T00:24:47+00:00" }, { "name": "mockery/mockery", @@ -8666,20 +8932,21 @@ }, { "name": "phar-io/manifest", - "version": "2.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "ext-phar": "*", "ext-xmlwriter": "*", "phar-io/version": "^3.0.1", @@ -8720,9 +8987,15 @@ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.3" + "source": "https://github.com/phar-io/manifest/tree/2.0.4" }, - "time": "2021-07-20T11:28:43+00:00" + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" }, { "name": "phar-io/version", @@ -8865,16 +9138,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.25.0", + "version": "1.26.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "bd84b629c8de41aa2ae82c067c955e06f1b00240" + "reference": "231e3186624c03d7e7c890ec662b81e6b0405227" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/bd84b629c8de41aa2ae82c067c955e06f1b00240", - "reference": "bd84b629c8de41aa2ae82c067c955e06f1b00240", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/231e3186624c03d7e7c890ec662b81e6b0405227", + "reference": "231e3186624c03d7e7c890ec662b81e6b0405227", "shasum": "" }, "require": { @@ -8906,22 +9179,22 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.25.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.26.0" }, - "time": "2024-01-04T17:06:16+00:00" + "time": "2024-02-23T16:05:55+00:00" }, { "name": "phpstan/phpstan", - "version": "1.10.58", + "version": "1.10.59", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "a23518379ec4defd9e47cbf81019526861623ec2" + "reference": "e607609388d3a6d418a50a49f7940e8086798281" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/a23518379ec4defd9e47cbf81019526861623ec2", - "reference": "a23518379ec4defd9e47cbf81019526861623ec2", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e607609388d3a6d418a50a49f7940e8086798281", + "reference": "e607609388d3a6d418a50a49f7940e8086798281", "shasum": "" }, "require": { @@ -8970,20 +9243,20 @@ "type": "tidelift" } ], - "time": "2024-02-12T20:02:57+00:00" + "time": "2024-02-20T13:59:13+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "10.1.11", + "version": "10.1.12", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "78c3b7625965c2513ee96569a4dbb62601784145" + "reference": "842f72662d6b9edda84c4b6f13885fd9cd53dc63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/78c3b7625965c2513ee96569a4dbb62601784145", - "reference": "78c3b7625965c2513ee96569a4dbb62601784145", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/842f72662d6b9edda84c4b6f13885fd9cd53dc63", + "reference": "842f72662d6b9edda84c4b6f13885fd9cd53dc63", "shasum": "" }, "require": { @@ -9040,7 +9313,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.11" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.12" }, "funding": [ { @@ -9048,7 +9321,7 @@ "type": "github" } ], - "time": "2023-12-21T15:38:30+00:00" + "time": "2024-03-02T07:22:05+00:00" }, { "name": "phpunit/php-file-iterator", @@ -9295,16 +9568,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.10", + "version": "10.5.11", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "50b8e314b6d0dd06521dc31d1abffa73f25f850c" + "reference": "0d968f6323deb3dbfeba5bfd4929b9415eb7a9a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/50b8e314b6d0dd06521dc31d1abffa73f25f850c", - "reference": "50b8e314b6d0dd06521dc31d1abffa73f25f850c", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0d968f6323deb3dbfeba5bfd4929b9415eb7a9a4", + "reference": "0d968f6323deb3dbfeba5bfd4929b9415eb7a9a4", "shasum": "" }, "require": { @@ -9376,7 +9649,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.10" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.11" }, "funding": [ { @@ -9392,7 +9665,7 @@ "type": "tidelift" } ], - "time": "2024-02-04T09:07:51+00:00" + "time": "2024-02-25T14:05:00+00:00" }, { "name": "psr/cache", @@ -9445,16 +9718,16 @@ }, { "name": "sebastian/cli-parser", - "version": "2.0.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae" + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/efdc130dbbbb8ef0b545a994fd811725c5282cae", - "reference": "efdc130dbbbb8ef0b545a994fd811725c5282cae", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", "shasum": "" }, "require": { @@ -9489,7 +9762,8 @@ "homepage": "https://github.com/sebastianbergmann/cli-parser", "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.0" + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" }, "funding": [ { @@ -9497,7 +9771,7 @@ "type": "github" } ], - "time": "2023-02-03T06:58:15+00:00" + "time": "2024-03-02T07:12:49+00:00" }, { "name": "sebastian/code-unit", @@ -9747,16 +10021,16 @@ }, { "name": "sebastian/diff", - "version": "5.1.0", + "version": "5.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "fbf413a49e54f6b9b17e12d900ac7f6101591b7f" + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/fbf413a49e54f6b9b17e12d900ac7f6101591b7f", - "reference": "fbf413a49e54f6b9b17e12d900ac7f6101591b7f", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", "shasum": "" }, "require": { @@ -9764,7 +10038,7 @@ }, "require-dev": { "phpunit/phpunit": "^10.0", - "symfony/process": "^4.2 || ^5" + "symfony/process": "^6.4" }, "type": "library", "extra": { @@ -9802,7 +10076,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/5.1.0" + "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" }, "funding": [ { @@ -9810,7 +10084,7 @@ "type": "github" } ], - "time": "2023-12-22T10:55:06+00:00" + "time": "2024-03-02T07:15:17+00:00" }, { "name": "sebastian/environment", @@ -9878,16 +10152,16 @@ }, { "name": "sebastian/exporter", - "version": "5.1.1", + "version": "5.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc" + "reference": "955288482d97c19a372d3f31006ab3f37da47adf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/64f51654862e0f5e318db7e9dcc2292c63cdbddc", - "reference": "64f51654862e0f5e318db7e9dcc2292c63cdbddc", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf", + "reference": "955288482d97c19a372d3f31006ab3f37da47adf", "shasum": "" }, "require": { @@ -9944,7 +10218,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.1" + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2" }, "funding": [ { @@ -9952,20 +10226,20 @@ "type": "github" } ], - "time": "2023-09-24T13:22:09+00:00" + "time": "2024-03-02T07:17:12+00:00" }, { "name": "sebastian/global-state", - "version": "6.0.1", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4" + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/7ea9ead78f6d380d2a667864c132c2f7b83055e4", - "reference": "7ea9ead78f6d380d2a667864c132c2f7b83055e4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", "shasum": "" }, "require": { @@ -9999,14 +10273,14 @@ } ], "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.1" + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" }, "funding": [ { @@ -10014,7 +10288,7 @@ "type": "github" } ], - "time": "2023-07-19T07:19:23+00:00" + "time": "2024-03-02T07:19:19+00:00" }, { "name": "sebastian/lines-of-code", @@ -10731,16 +11005,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.8.1", + "version": "3.9.0", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "14f5fff1e64118595db5408e946f3a22c75807f7" + "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/14f5fff1e64118595db5408e946f3a22c75807f7", - "reference": "14f5fff1e64118595db5408e946f3a22c75807f7", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/d63cee4890a8afaf86a22e51ad4d97c91dd4579b", + "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b", "shasum": "" }, "require": { @@ -10807,7 +11081,7 @@ "type": "open_collective" } ], - "time": "2024-01-11T20:47:48+00:00" + "time": "2024-02-16T15:06:51+00:00" }, { "name": "symfony/polyfill-php81", @@ -10958,23 +11232,23 @@ }, { "name": "thedoctor0/laravel-factory-generator", - "version": "1.3.2", + "version": "1.3.3", "source": { "type": "git", "url": "https://github.com/TheDoctor0/laravel-factory-generator.git", - "reference": "7ee56e4229b78d5f6274a4649819b2bca0bd56e3" + "reference": "65d1f1be729e706c264b20c3fa25615d0bf76890" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/TheDoctor0/laravel-factory-generator/zipball/7ee56e4229b78d5f6274a4649819b2bca0bd56e3", - "reference": "7ee56e4229b78d5f6274a4649819b2bca0bd56e3", + "url": "https://api.github.com/repos/TheDoctor0/laravel-factory-generator/zipball/65d1f1be729e706c264b20c3fa25615d0bf76890", + "reference": "65d1f1be729e706c264b20c3fa25615d0bf76890", "shasum": "" }, "require": { "doctrine/dbal": "^2.9|^2.10|^3.0", - "illuminate/console": "^8.0|^9.0|^10.0", - "illuminate/filesystem": "^8.0|^9.0|^10.0", - "illuminate/support": "^8.0|^9.0|^10.0", + "illuminate/console": "^8.0|^9.0|^10.0|^11.0", + "illuminate/filesystem": "^8.0|^9.0|^10.0|^11.0", + "illuminate/support": "^8.0|^9.0|^10.0|^11.0", "php": ">=7.4" }, "type": "library", @@ -11004,7 +11278,7 @@ ], "support": { "issues": "https://github.com/TheDoctor0/laravel-factory-generator/issues", - "source": "https://github.com/TheDoctor0/laravel-factory-generator/tree/1.3.2" + "source": "https://github.com/TheDoctor0/laravel-factory-generator/tree/1.3.3" }, "funding": [ { @@ -11016,20 +11290,20 @@ "type": "github" } ], - "time": "2023-04-21T16:45:43+00:00" + "time": "2024-02-28T08:51:47+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.2", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96" + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96", - "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", "shasum": "" }, "require": { @@ -11058,7 +11332,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.2" + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" }, "funding": [ { @@ -11066,7 +11340,7 @@ "type": "github" } ], - "time": "2023-11-20T00:12:19+00:00" + "time": "2024-03-03T12:36:25+00:00" } ], "aliases": [], @@ -11077,7 +11351,7 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "^8.3" + "php": "^8.2" }, "platform-dev": [], "plugin-api-version": "2.3.0" diff --git a/config/mail.php b/config/mail.php index f3ed01a..d12a80f 100644 --- a/config/mail.php +++ b/config/mail.php @@ -118,4 +118,10 @@ return [ ], ], + 'contact' => [ + 'remark' => env('MAIL_CONTACT_REMARK', 'hello@example.com'), + 'sponsoring' => env('MAIL_CONTACT_SPONSORING', 'hello@example.com'), + 'service' => env('MAIL_CONTACT_SERVICE', 'hello@example.com'), + 'other' => env('MAIL_CONTACT_OTHER', 'hello@example.com'), + ] ]; diff --git a/config/services.php b/config/services.php index 88b9614..23ff02f 100644 --- a/config/services.php +++ b/config/services.php @@ -31,4 +31,15 @@ return [ 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), ], + 'google' => [ + 'recaptcha' => [ + 'public' => env('GOOGLE_RECAPTCHA_PUBLIC'), + 'private' => env('GOOGLE_RECAPTCHA_PRIVATE'), + 'version' => env('GOOGLE_RECAPTCHA_VERSION', "3") === "3" ? true : false + ] + ], + + 'matomo' => [ + 'site_id' => env('MATOMO_SITE_ID') + ] ]; diff --git a/database/seeders/Mandatory/StaticPageSeeder.php b/database/seeders/Mandatory/StaticPageSeeder.php index d884405..9da90b8 100644 --- a/database/seeders/Mandatory/StaticPageSeeder.php +++ b/database/seeders/Mandatory/StaticPageSeeder.php @@ -18,19 +18,6 @@ class StaticPageSeeder extends Seeder { try { StaticPage::unsetEventDispatcher(); - StaticPage::query()->updateOrCreate( - [ - 'type' => StaticPageType::contact, - ], - [ - 'seo_title' => 'Seo title pour la page contactez nous', - 'seo_description' => 'Seo description pour la page contactez nous', - 'title' => 'Contactez-nous', - 'slug' => Str::slug('Contactez-nous'), - 'type' => StaticPageType::contact, - 'content' => \clean(\fake()->randomHtml(6, 7)), - ] - ); StaticPage::query()->updateOrCreate( [ 'type' => StaticPageType::legals, diff --git a/resources/assets/images/others/joindre-fichier.svg b/resources/assets/images/others/joindre-fichier.svg new file mode 100644 index 0000000..c7b2231 --- /dev/null +++ b/resources/assets/images/others/joindre-fichier.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/lang/fr/validation.php b/resources/lang/fr/validation.php index 1a72446..49f94ac 100644 --- a/resources/lang/fr/validation.php +++ b/resources/lang/fr/validation.php @@ -217,7 +217,13 @@ return [ 'updated_at' => 'mis à jour à', 'username' => 'nom d\'utilisateur', 'year' => 'année', + 'custom' => [ + 'accept_rules' => 'acceptation du traitement des données', + 'send_data' => 'acceptation de la politique de confidentialité' + ] ], + 'youtube_id' => ':attribute doit être un ID de vidéo Youtube valide', + 'vimeo_id' => ':attribute doit être un ID de vidéo Vimeo valide', 'custom' => [ 'of_the' => [ 'male' => 'du ', @@ -283,5 +289,8 @@ return [ optimal dans les moteurs de recherche (balise ).', 'seo_description' => 'Doit décrire précisément le contenu de la page (balise <meta> description).', 'required_fields' => '* Champs obligatoires', + 'society' => 'entreprise', + 'object' => 'objet', + 'message' => 'message', ], ]; diff --git a/resources/sass/fo/fo.scss b/resources/sass/fo/fo.scss index 68ca6f4..fc6cee7 100644 --- a/resources/sass/fo/fo.scss +++ b/resources/sass/fo/fo.scss @@ -20,4 +20,5 @@ @import "./pages/homepage"; @import "./pages/unveil"; @import "./pages/site"; +@import "./pages/contact"; diff --git a/resources/sass/fo/pages/.gitkeep b/resources/sass/fo/pages/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/resources/sass/fo/pages/_contact.scss b/resources/sass/fo/pages/_contact.scss new file mode 100644 index 0000000..493ce7b --- /dev/null +++ b/resources/sass/fo/pages/_contact.scss @@ -0,0 +1,80 @@ +#listen { + .btn-outline-primary { + text-transform: initial; + } + + #wrapper-listen-form { + @include media-breakpoint-up(md) { + background-color: rgb(var(--bs-eight-rgb)); + } + } + + #listen-form { + @include media-breakpoint-up(md) { + background-color: rgb(var(--bs-seven-rgb)); + } + + .form-control { + @include media-breakpoint-up(md) { + /* stylelint-disable-next-line color-function-notation */ + box-shadow: inset 0 -1px rgba(var(--bs-tertiary-rgb), 60%); + } + + &:focus { + @include media-breakpoint-up(md) { + /* stylelint-disable-next-line color-function-notation */ + box-shadow: inset 0 -1px rgba(var(--bs-tertiary-rgb), 100%); + } + } + } + + /* stylelint-disable-next-line selector-no-qualifying-type */ + .form-floating > input.form-control, select { + height: 56px; + } + + /* stylelint-disable-next-line selector-no-qualifying-type */ + .form-floating > input.form-control:focus ~ label::after, + .form-floating > input.form-control:not(:placeholder-shown) ~ label::after { + background-color: transparent !important; + } + + .listen-message { + @include media-breakpoint-up(md) { + background-color: rgb(var(--bs-white-rgb)); + } + + @include media-breakpoint-up(xl) { + position: absolute; + top: 0; + right: 0; + height: 100%; + } + + #contact-file-icon { + display: block; + width: 1rem; + height: 1rem; + background-image: url("@/images/others/joindre-fichier.svg"); + background-position: center; + background-repeat: no-repeat; + background-size: contain; + } + } + } + + .ck-content p { + @include media-breakpoint-up(xl) { + margin: 0; + } + } + + .badge-logo { + width: 6rem; + height: 6rem; + background-image: url("@/images/footer/volena-logo.svg"); + background-position: center; + background-repeat: no-repeat; + background-size: 80%; + } +} diff --git a/resources/sass/fo/utilities/_bootstrap-variables.scss b/resources/sass/fo/utilities/_bootstrap-variables.scss index 1b343ff..3db062c 100644 --- a/resources/sass/fo/utilities/_bootstrap-variables.scss +++ b/resources/sass/fo/utilities/_bootstrap-variables.scss @@ -8,6 +8,8 @@ $tertiary: $color-tertiary; $quad: $color-quad; $quint: $color-quint; $sixt: $color-sixt; +$seven: $color-seven; +$eight: $color-eight; $success: $color-success; $info: $color-info; $warning: $color-warning; @@ -33,6 +35,8 @@ $custom-theme-colors: map.merge($theme-colors, 'quad': $quad, 'quint': $quint, 'sixt': $sixt, + 'seven': $seven, + 'eight': $eight, )); $theme-colors: map.merge($theme-colors, $custom-theme-colors); $theme-colors-rgb: map-loop($theme-colors, to-rgb, '$value'); diff --git a/resources/sass/fo/utilities/_variables.scss b/resources/sass/fo/utilities/_variables.scss index bf22957..0c5fdad 100644 --- a/resources/sass/fo/utilities/_variables.scss +++ b/resources/sass/fo/utilities/_variables.scss @@ -18,6 +18,8 @@ $color-tertiary: #23628a; $color-quad: #d36738; $color-quint: #4c764b; $color-sixt: #b94c73; +$color-seven: #C3DFE9; +$color-eight: #EDF9FD; // * BACKGROUNDS COLORS $bg-body: $color-white; diff --git a/resources/sass/fo/vendor/_cookie-notice.scss b/resources/sass/fo/vendor/_cookie-notice.scss index ef6df23..e34385c 100644 --- a/resources/sass/fo/vendor/_cookie-notice.scss +++ b/resources/sass/fo/vendor/_cookie-notice.scss @@ -1 +1,5 @@ +$ck-background-color: $bg-body; +$ck-btn-background-color: $bg-body; +$ck-title-font: $font-default-family-base; + @import "@ldc-web/cookie-notice"; diff --git a/resources/views/emails/send-confirmation-form.blade.php b/resources/views/emails/send-confirmation-form.blade.php new file mode 100644 index 0000000..9715ee2 --- /dev/null +++ b/resources/views/emails/send-confirmation-form.blade.php @@ -0,0 +1,14 @@ +{{-- blade-formatter-disable --}} +@component('mail::message') +# {{ __('Bonjour,') }} + +{{ __('Nous avons bien reçu votre demande.') }} + +{{ __('Nous vous remercions de l\'attention que vous nous portez.') }} + +{{ __('Nous vous répondrons dans les meilleurs délais.') }} + +{{ __('Cordialement,') }} + +{{ __('L\'équipe :appName.', ['appName' => config('app.name')]) }} +@endcomponent diff --git a/resources/views/emails/send-contact-form.blade.php b/resources/views/emails/send-contact-form.blade.php new file mode 100644 index 0000000..d08d40f --- /dev/null +++ b/resources/views/emails/send-contact-form.blade.php @@ -0,0 +1,35 @@ +{{-- blade-formatter-disable --}} +@component('mail::message') +# {{ __('Message contact :') }} + +{{ __('Voici un message envoyé depuis :siteName :', ['siteName' => config('app.name')]) }} + +{{ __('Expéditeur :') }} @if ($data->first_name) __{{ $data->first_name }}__ @endif __{{ $data->last_name }}__ + +{{ __('E-mail :') }} __{{ $data->email }}__ + +@if ($data->phone) +{{ __('Téléphone :') }} __{{ $data->phone }}__ +@endif + +@if ($data->address) +{{ __('Adresse :') }} __{{ $data->address }}__ +@endif + +@if ($data->city) +{{ __('Ville :') }} __{{ $data->city }}__ +@endif + +@if ($data->postal_code) +{{ __('Code postal :') }} __{{ $data->postal_code }}__ +@endif + +{{ __('Message :') }} +@component('mail::panel') +``` +{{ $data->message }} +``` +@endcomponent + +{{ config('app.name') }}. +@endcomponent diff --git a/resources/views/fo/layout.blade.php b/resources/views/fo/layout.blade.php index 1a5f299..811a21c 100644 --- a/resources/views/fo/layout.blade.php +++ b/resources/views/fo/layout.blade.php @@ -15,7 +15,7 @@ <main class="@yield('bg-color') pt-2"> <div class="container-fluid"> <div class="row justify-content-center"> - <div class="col col-md-6"> + <div class="col-12 col-md-10 col-xl-6"> @include('modules.flash-messages') </div> </div> diff --git a/resources/views/fo/layouts/footer-links.blade.php b/resources/views/fo/layouts/footer-links.blade.php index 76a9dc5..c1e8b60 100644 --- a/resources/views/fo/layouts/footer-links.blade.php +++ b/resources/views/fo/layouts/footer-links.blade.php @@ -23,7 +23,8 @@ </li> <li class="list-inline-item"><span @class($separatorClassList)>{{ $separator }}</span></li> <li class="list-inline-item"> - <a href="FIXME:#cookier" title="{{ __('Ouvrir le panneau de Gestion des cookies') }}" @class($linkClassList)> + <a class="cn-cookie-link link-primary" href="#" title="{{ __('Ouvrir le panneau de Gestion des cookies') }}" + @class($linkClassList)> {{ __('Gestion des cookies') }} </a> </li> diff --git a/resources/views/fo/layouts/footer.blade.php b/resources/views/fo/layouts/footer.blade.php index 1cda2f7..e480e3c 100644 --- a/resources/views/fo/layouts/footer.blade.php +++ b/resources/views/fo/layouts/footer.blade.php @@ -31,7 +31,7 @@ <div class="col text-center"> <span>©{{ __('Voléna') }}</span> <span>-</span> - <span>2023</span> + <span>{{ date('Y') }}</span> </div> </div> <div class="row pb-5"> diff --git a/resources/views/fo/layouts/nav-menu.blade.php b/resources/views/fo/layouts/nav-menu.blade.php index eee4790..bc8c70c 100644 --- a/resources/views/fo/layouts/nav-menu.blade.php +++ b/resources/views/fo/layouts/nav-menu.blade.php @@ -65,8 +65,8 @@ </li> <li class="nav-item mb-1"> @php $activePage = false; @endphp - <a class="nav-link @if ($activePage) active @endif" data-bs-toggle="tooltip" href="#FIXME:route" - title="{{ __('Aller sur la page On vous écoute') }}" + <a class="nav-link @if ($activePage) active @endif" data-bs-toggle="tooltip" + href="{{ route('fo.listen') }}" title="{{ __('Aller sur la page On vous écoute') }}" @if ($activePage) aria-current="page" @endif> {{ __('On vous écoute') }} </a> diff --git a/resources/views/fo/pages/listen.blade.php b/resources/views/fo/pages/listen.blade.php new file mode 100644 index 0000000..e8f1d4a --- /dev/null +++ b/resources/views/fo/pages/listen.blade.php @@ -0,0 +1,301 @@ +@extends('fo.layout') + +@section('title', $staticPageModel->seo_title) +@section('description', $staticPageModel->seo_description) +@section('breadcrumb', request()->route()->getName()) + +@section('banner') + @include('fo.layouts.banner', [ + 'h1' => __($staticPageModel->title), + 'asset' => Vite::asset('resources/assets/images/banners/home_reworked.jpg'), + 'title' => __('Paysage d\'un champs de blé au soleil couchant avec une lisière en fond de tableau'), + 'alt' => __('Image de fond'), + 'displayArrow' => true, + ]) +@endsection + +@section('content') + <section class="container mb-5" id="listen"> + <div class="d-none d-lg-block my-5 p-5 text-center"> + <a class="btn btn-outline-primary rounded-pill border-primary border shadow-none" + href="#FIXME: url page 'on embauche' section 'on se retrouve'"> + {{ __('Je suis candidat') }} + </a> + </div> + <div class="rounded-5 p-md-4" id="wrapper-listen-form"> + <div class="row m-md-0 p-md-4 my-5 py-5"> + <div class="col-12 col-lg-4 text-lg-start text-center"> + <h2 class="h2 fw-bold text-primary m-0">{{ $staticPageModel->title }}</h2> + </div> + <div class="d-lg-none col-12 text-center"> + <a class="btn btn-outline-primary rounded-pill border-primary text-lowercase my-3 border shadow-none" + href="#FIXME: url page 'on embauche' section 'on se retrouve'"> + {{ __('Je suis candidat') }} + </a> + </div> + <div class="col-12 col-lg-6 text-lg-start d-lg-flex align-items-end justify-content-center text-center"> + @if ($staticPageModel->content) + <div class="ck-content text-primary"> + {!! clean($staticPageModel->content) !!} + </div> + @endif + </div> + <div class="col-12 col-lg-2 d-none d-lg-flex justify-content-center align-items-center"> + <div class="badge-logo bg-primary rounded-pill"></div> + </div> + </div> + <form class="rounded-4 p-md-3 p-xl-5 p-0" id="listen-form" method="POST" action="{{ route('fo.listen.send') }}" + enctype="multipart/form-data"> + @method('POST') + @csrf + <div class="position-relative row w-100 gx-0 gx-md-4 mx-auto"> + <div class="col-12 col-md-6 col-xl-4"> + <div class="row"> + <fieldset class="col-12 form-floating mb-3" inert="true"> + <input class="form-control bg-transparent" id="contactSociety" name="society" type="text" + value="{{ old('society') }}" placeholder="{{ Str::of(__('validation.custom.society'))->ucFirst() }}"> + <label for="contactSociety">{{ Str::of(__('validation.custom.society'))->ucFirst() }}</label> + @foreach ($errors->get('society') as $message) + <div class="invalid-feedback d-block">{{ $message }}</div> + @endforeach + </fieldset> + <fieldset class="col-12 form-floating mb-3" inert="true"> + <input class="form-control bg-transparent" id="contactFirstname" name="first_name" type="text" + value="{{ old('first_name') }}" + placeholder="{{ Str::of(__('validation.attributes.first_name'))->ucFirst() }}"> + <label for="contactFirstname">{{ Str::of(__('validation.attributes.first_name'))->ucFirst() }}</label> + @foreach ($errors->get('first_name') as $message) + <div class="invalid-feedback d-block">{{ $message }}</div> + @endforeach + </fieldset> + <fieldset class="col-12 form-floating mb-3" inert="true"> + <input class="form-control bg-transparent" id="contactLastname" name="last_name" type="text" + value="{{ old('last_name') }}" + placeholder="{{ Str::of(__('validation.attributes.last_name'))->ucFirst() }}" required> + <label for="contactLastname">{{ Str::of(__('validation.attributes.last_name'))->ucFirst() }}*</label> + @foreach ($errors->get('last_name') as $message) + <div class="invalid-feedback d-block">{{ $message }}</div> + @endforeach + </fieldset> + <fieldset class="col-12 form-floating mb-3" inert="true"> + <input class="form-control bg-transparent" id="contactEmail" name="email" type="text" + value="{{ old('email') }}" required + placeholder="{{ Str::of(__('validation.attributes.email'))->ucFirst() }}"> + <label for="contactEmail">{{ Str::of(__('validation.attributes.email'))->ucFirst() }}*</label> + @foreach ($errors->get('email') as $message) + <div class="invalid-feedback d-block">{{ $message }}</div> + @endforeach + </fieldset> + <fieldset class="col-12 form-floating mb-3" inert="true"> + <input class="form-control bg-transparent" id="contactPhone" name="phone" type="number" + value="{{ old('phone') }}" placeholder="{{ Str::of(__('validation.attributes.phone'))->ucFirst() }}"> + <label for="contactPhone">{{ Str::of(__('validation.attributes.phone'))->ucFirst() }}</label> + @foreach ($errors->get('phone') as $message) + <div class="invalid-feedback d-block">{{ $message }}</div> + @endforeach + </fieldset> + </div> + </div> + <div class="col-12 col-md-6 col-xl-4"> + <div class="row"> + <fieldset class="col-12" inert="true"> + <div class="row"> + <div class="col-6 col-md-12 form-floating mb-3"> + <input class="form-control bg-transparent" id="contactPostalcode" name="postal_code" type="number" + value="{{ old('postal_code') }}" + placeholder="{{ Str::of(__('validation.attributes.postal_code'))->ucFirst() }}"> + <label + for="contactPostalcode">{{ Str::of(__('validation.attributes.postal_code'))->ucFirst() }}</label> + @foreach ($errors->get('postal_code') as $message) + <div class="invalid-feedback d-block">{{ $message }}</div> + @endforeach + </div> + <div class="col-6 col-md-12 form-floating mb-3"> + <input class="form-control bg-transparent" id="contactCity" name="city" type="text" + value="{{ old('city') }}" + placeholder="{{ Str::of(__('validation.attributes.city'))->ucFirst() }}"> + <label for="contactCity">{{ Str::of(__('validation.attributes.city'))->ucFirst()->value() }}</label> + @foreach ($errors->get('city') as $message) + <div class="invalid-feedback d-block">{{ $message }}</div> + @endforeach + </div> + </div> + </fieldset> + <fieldset class="col-12 mb-3" inert="true"> + <select class="form-control bg-transparent px-2" id="contactCountry" name="country"> + <option value="null" selected> + {{ __('Sélectionner un :entity', ['entity' => __('validation.attributes.country')]) }} + </option> + @foreach (\App\Enums\Country::validShippingCountries() as $key => $country) + <option class="my-2" value="{{ $country->value() }}" + @if (old('country') == $country->value()) selected @endif> + {{ \App\Enums\Country::make($country->value)->label() }} + </option> + @endforeach + </select> + @foreach ($errors->get('country') as $message) + <div class="invalid-feedback d-block">{{ $message }}</div> + @endforeach + </fieldset> + <fieldset class="col-12 form-floating mb-3" inert="true"> + <input class="form-control bg-transparent" id="contactAddress" name="address" type="text" + value="{{ old('address') }}" + placeholder="{{ Str::of(__('validation.attributes.address'))->ucFirst() }}"> + <label for="contactAddress">{{ Str::of(__('validation.attributes.address'))->ucFirst() }}</label> + @foreach ($errors->get('address') as $message) + <div class="invalid-feedback d-block">{{ $message }}</div> + @endforeach + </fieldset> + </div> + </div> + <fieldset class="col-12 col-xl-4 listen-message rounded-4 p-md-4 d-flex justify-content-center align-items-center p-0"> + <div class="row"> + <div class="col-12 form-floating mb-3" inert="true"> + <select class="form-control bg-transparent px-2" id="contactObject" name="object"> + <option value="null" selected> + {{ __('Sélectionner un :entity de mail*', ['entity' => __('validation.custom.object')]) }} + </option> + <option value="0">{{ __('Recutement') }}</option> + @foreach (\App\Enums\Listen\ObjectEnum::toArray() as $key => $object) + <option class="my-2" value="{{ $object->value }}" + @if (old('object') == $object->value) selected @endif> + {{ $object->label }} + </option> + @endforeach + </select> + @push('scripts') + <script nonce="{{ $nonce }}"> + document.addEventListener("DOMContentLoaded", () => { + const selectObject = document.getElementById('contactObject') + selectObject.addEventListener('change', (event) => { + if (selectObject.value == 0) { + window.open('https://www.odwebp.svc.ms/embed?smkt=fr-fr', '_blank'); + selectObject.value = null; + } + }) + }); + </script> + @endpush + @foreach ($errors->get('object') as $message) + <div class="invalid-feedback d-block">{{ $message }}</div> + @endforeach + </div> + <div class="col-12 form-floating mb-3" inert="true"> + <textarea class="form-control bg-transparent" id="contactMessage" name="message" rows="6" placeholder="Leave a comment here" + required>{{ old('message') }}</textarea> + <label class="ms-2" for="contactMessage"> + {{ Str::of(__('validation.custom.message'))->ucFirst()->value() }}* + </label> + @foreach ($errors->get('message') as $message) + <div class="invalid-feedback d-block">{{ $message }}</div> + @endforeach + </div> + <div class="col-12 mb-1"> + <label class="btn btn-light w-100 test d-flex justify-content-between text-start shadow-none" + for="contact-file"> + {{ Str::of(__('joindre un fichier'))->ucFirst()->value() }}* + <span id="contact-file-icon"></span> + </label> + <input class="d-none" id="contact-file" name="file" type="file" value="{{ old('file') }}" + role="button" accept=".jpg,.jpeg,.png,.pdf"> + @foreach ($errors->get('file') as $message) + <div class="invalid-feedback d-block">{{ $message }}</div> + @endforeach + </div> + <div class="col-12 pe-md-5 m-xl-0 mb-2"> + <span class="text-body-secondary"> + {{ Str::of(__('formats acceptés: jpg,jpeg,png,pdf'))->ucFirst()->value() }} + </span> + </div> + </div> + </fieldset> + {{-- Don't remove next empty div, use for placement --}} + <div class="d-none d-lg-block col-12 col-xl-4 visibility-hidden"></div> + <div class="col-12 col-xl-4 py-xl-0 py-4"> + <div class="row"> + <fieldset class="col-12 d-flex justify-content-start align-items-start align-items-md-center mb-1 flex-row" + inert="true"> + <input class="form-check-input mt-2 p-2" id="accept_rules" name="accept_rules" type="checkbox" + role="button" @if (old('accept_rules')) checked @endif required> + <label class="ms-2 mt-1" for="accept_rules" role="button"> + {!! nl2br( + __('J’autorise :appName à traiter mes données personnelles conformément à la :startAPolitique de confidentialité:endA.', [ + 'appName' => config('app.name'), + 'startA' => '<a href="' . route('fo.confidentiality') . '">', + 'startA' => '<a href="' . route('fo.confidentiality') . '">', + 'endA' => '</a>', + ]), + ) !!} + </label> + @foreach ($errors->get('accept_rules') as $message) + <div class="invalid-feedback d-block">{{ $message }}</div> + @endforeach + </fieldset> + <fieldset class="col-12 d-flex justify-content-start align-items-start align-items-md-center mb-1 flex-row" + inert="true"> + <input class="form-check-input mt-2 p-2" id="send_data" name="send_data" type="checkbox" role="button" + @if (old('send_data')) checked @endif required> + <label class="ms-2 mt-1" for="send_data" role="button"> + {!! nl2br( + __('J\'ai lu et j\'accepte la politique de confidentialité de ce site: :startA Voir nos mentions légales et CGU:endA.', [ + 'startA' => '<a href="' . route('fo.legals') . '">', + 'endA' => '</a>', + ]), + ) !!} + </label> + @foreach ($errors->get('send_data') as $message) + <div class="invalid-feedback d-block">{{ $message }}</div> + @endforeach + </fieldset> + </div> + </div> + <div class="col-12 col-xl-4"> + <a class="cn-cookie-link" id="recaptcha-warning" href="" rel="nofollow"> + <strong class="text-underline text-bold text-normal text-danger"> + {{ __('cookie-notice.custom.recaptcha.warning') }} + </strong> + </a> + <div class="d-flex flex-column justify-content-center align-items-center"> + <div id="r_captcha"></div> + @if ($errors->has('g-recaptcha-response')) + <div class="mb-6"> + <span class="text-danger">{{ $errors->first('g-recaptcha-response') }}</span> + </div> + @endif + <p>{{ __('*Champ obligatoire') }}</p> + </div> + <div class="text-center"> + <button class="g-recaptcha btn btn-primary rounded-pill text-capitalize" + data-sitekey="{{ config('services.google.recaptcha.public') }}" type="submit" + inert="true">{{ Str::ucfirst(__('Envoyer')) }}</button> + </div> + </div> + </div> + </form> + </div> + </section> +@endsection + +@push('scripts') + <script nonce="{{ $nonce }}"> + document.addEventListener('DOMContentLoaded', function() { + window.__CN_Recaptcha = function() { + (function(d, t) { + let g = d.createElement(t), + s = d.getElementsByTagName(t)[0]; + g.src = 'https://www.google.com/recaptcha/api.js?render=explicit&onload=__CN_Recaptcha_Loaded'; + s.parentNode.insertBefore(g, s) + }(document, 'script')); + }; + window.__CN_Recaptcha_Loaded = function() { + grecaptcha.render('r_captcha', { + 'sitekey': '{{ config('services.google.recaptcha.public') }}' + }); + document.getElementById('recaptcha-warning').remove(); + document.getElementById('listen-form').querySelectorAll('[inert="true"]').forEach(element => { + element.inert = false; + }); + }; + }); + </script> +@endpush diff --git a/resources/views/vendor/cn-cookies.blade.php b/resources/views/vendor/cn-cookies.blade.php index bbe9195..ae54a19 100644 --- a/resources/views/vendor/cn-cookies.blade.php +++ b/resources/views/vendor/cn-cookies.blade.php @@ -2,7 +2,7 @@ @php $site_name = Str::ucfirst(config('app.name')); -$logo_picture_url = Vite::asset('resources/assets/images/logo.png'); +$logo_picture_url = Vite::asset('resources/assets/images/header/volena-logo.svg'); $logo_title_text = __('Logo du site :name', ['name' => $site_name]); $logo_alt_text = __('Logo :name', ['name' => $site_name]); diff --git a/resources/views/vendor/cookie-notice-templates/standard.blade.php b/resources/views/vendor/cookie-notice-templates/standard.blade.php index 154a40c..20b3669 100644 --- a/resources/views/vendor/cookie-notice-templates/standard.blade.php +++ b/resources/views/vendor/cookie-notice-templates/standard.blade.php @@ -5,15 +5,15 @@ <title>{{ $strings->picture_cookie_title }} - - - - - - - - + fill="#0e2b45" /> + + + + + + + + {{-- BANNER --}} diff --git a/resources/views/vendor/mail/html/header.blade.php b/resources/views/vendor/mail/html/header.blade.php index 920bc2d..197ad8a 100644 --- a/resources/views/vendor/mail/html/header.blade.php +++ b/resources/views/vendor/mail/html/header.blade.php @@ -2,11 +2,10 @@ @if (trim($slot) === 'Laravel') - + @else - {{-- FIXME: Personaliser ca --}} - - {{ $slot }} + @endif diff --git a/routes/web-fo.php b/routes/web-fo.php index 8968282..295a0af 100644 --- a/routes/web-fo.php +++ b/routes/web-fo.php @@ -13,8 +13,14 @@ Route::middleware(['throttle:credentials'])->name('fo.')->group(function () { Route::get('/', [HomeController::class, 'index'])->name('homepage'); Route::get('/on-se-devoile', [StaticPageController::class, 'unveil'])->name('unveil'); + Route::get('/on-sengage', [StaticPageController::class, 'commit'])->name('commit'); + Route::get('/on-vous-ecoute', [StaticPageController::class, 'listen'])->name('listen'); + Route::get('/mentions-legales', [StaticPageController::class, 'listen'])->name('legals'); + Route::get('/charte-de-confidentialite', [StaticPageController::class, 'listen'])->name('confidentiality'); Route::get('/sites/{site:slug}', [SiteController::class, 'show'])->name('sites.show'); + Route::post('/on-vous-ecoute-formulaire', [StaticPageController::class, 'listenForm'])->name('listen.send'); + // * Iframe cookies Route::get('/frame/{frame}', function (string $frame) { return view('fo.modules.frame', ['frame' => $frame]); diff --git a/vite.config.ts b/vite.config.ts index e35b13a..85e06c4 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -24,7 +24,9 @@ const purgePlugin = purge({ /^cropper-/, /^offcanvas-/, /^tooltip/, /^bs-tooltip/, /^data-popper/, /.*\[data-popper-placement].*/, /^bs-popover/, /^popover/, // Vue - /-(leave|enter|appear)(|-(to|from|active))$/, /^(?!(|.*?:)cursor-move).+-move$/, /^router-link(|-exact)-active$/, /data-v-.*/ + /-(leave|enter|appear)(|-(to|from|active))$/, /^(?!(|.*?:)cursor-move).+-move$/, /^router-link(|-exact)-active$/, /data-v-.*/, + // Cookies + /^cn-.*/ ], });