feat: ✨ add crm + newsletter subscription + unsubscribe page
This commit is contained in:
parent
a7a227a669
commit
c6a9e2135f
20 changed files with 589 additions and 20 deletions
|
|
@ -52,3 +52,8 @@ SAML2_SP_CERT_x509=
|
|||
SAML2_SP_CERT_PRIVATEKEY=
|
||||
SAML2_CONTACT_TECHNICAL_EMAIL=
|
||||
SAML2_CONTACT_SUPPORT_EMAIL=
|
||||
|
||||
# CRM
|
||||
CRM_ENDPOINT=
|
||||
CRM_PASSWORD=
|
||||
CRM_TOKEN=
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ use App\Mail\ContactFormMail;
|
|||
use App\Models\StaticPage;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use LDC\LDCCRM\Enums\ApiError;
|
||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
||||
use LDC\LDCCRM\Exceptions\CrmException;
|
||||
use LDC\LDCCRM\Models\SingleOptin;
|
||||
|
||||
class ContactController extends Controller
|
||||
{
|
||||
|
|
@ -34,6 +38,28 @@ class ContactController extends Controller
|
|||
{
|
||||
Mail::to(config('mail.contactsList.contactform'))->send(new ContactFormMail($request));
|
||||
|
||||
if ($request->opt_in) {
|
||||
try {
|
||||
SingleOptin::setStatus($request->email, true);
|
||||
} catch (ApiErrorException $e) {
|
||||
if ($e->getApiError()->equals(ApiError::singleOptinCustomerExists)) {
|
||||
return back()
|
||||
->withErrors(['opt_in' => trans('Vous êtes déjà inscrit avec cette adresse email')])
|
||||
->withInput();
|
||||
}
|
||||
|
||||
\report($e);
|
||||
return back()
|
||||
->withErrors(['opt_in' => trans('Une erreur est survenue, merci de réessayer ultérieurement')])
|
||||
->withInput();
|
||||
} catch (CrmException $e) {
|
||||
\report($e);
|
||||
return back()
|
||||
->withErrors(['opt_in' => trans('Une erreur est survenue, merci de réessayer ultérieurement')])
|
||||
->withInput();
|
||||
}
|
||||
} //end if
|
||||
|
||||
Session::forget('saveProductInBasket');
|
||||
|
||||
Session::flash('matomo_generate_lead');
|
||||
|
|
|
|||
|
|
@ -3,10 +3,19 @@
|
|||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Fo\Newsletter\SingleOptinRequest;
|
||||
use App\Http\Requests\Fo\Newsletter\UnsubscribeNewsletterRequest;
|
||||
use App\Models\News;
|
||||
use App\Models\Product;
|
||||
use App\Models\Range;
|
||||
use App\Models\Slide;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use LDC\LDCCRM\Enums\ApiError;
|
||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
||||
use LDC\LDCCRM\Exceptions\CrmException;
|
||||
use LDC\LDCCRM\Exceptions\ValidationException;
|
||||
use LDC\LDCCRM\Models\Customer;
|
||||
use LDC\LDCCRM\Models\SingleOptin;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
|
|
@ -55,4 +64,79 @@ class HomeController extends Controller
|
|||
'news'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the CRM to add a single optin
|
||||
*
|
||||
* @param \App\Http\Requests\Fo\Newsletter\SingleOptinRequest $request
|
||||
* @return string|array|null|\Illuminate\Contracts\Translation\Translator
|
||||
* @throws \LDC\LDCCRM\Exceptions\ValidationException ValidationException.
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException BindingResolutionException.
|
||||
*/
|
||||
public function addOptIn(SingleOptinRequest $request)
|
||||
{
|
||||
try {
|
||||
SingleOptin::setStatus($request->email, true);
|
||||
return \response(trans("Votre inscription à la newsletter a été prise en compte"), 200);
|
||||
} catch (ApiErrorException $e) {
|
||||
if ($e->getApiError()->equals(ApiError::singleOptinCustomerExists)) {
|
||||
return trans('Vous êtes déjà inscrit avec cette adresse email');
|
||||
}
|
||||
\report($e);
|
||||
return \response(trans('Une erreur est survenue, merci de réessayer ultérieurement'), 404);
|
||||
} catch (CrmException $e) {
|
||||
\report($e);
|
||||
return \response(trans('Une erreur est survenue, merci de réessayer ultérieurement'), 404);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* unsubscribeNewsletter method
|
||||
*
|
||||
* @param \App\Http\Requests\Fo\Newsletter\UnsubscribeNewsletterRequest $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function unsubscribeNewsletter(UnsubscribeNewsletterRequest $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$error = null;
|
||||
$hashcode = $request->hashcode;
|
||||
|
||||
try {
|
||||
SingleOptin::unsetStatusWithHashcode($hashcode);
|
||||
} catch (ApiErrorException $e) {
|
||||
Log::debug($e->getMessage());
|
||||
if ($e->getApiError()->equals(ApiError::modelNotFound)) {
|
||||
if ($customer = Customer::find($hashcode)) {
|
||||
$customer->opt_in = false;
|
||||
// ! Les données peuvent être parsés en retour de la crm et inconsitantes (Héritage vielle crm).
|
||||
try {
|
||||
$customer->save();
|
||||
} catch (ValidationException $e) {
|
||||
$error = null;
|
||||
}
|
||||
} else {
|
||||
abort(404);
|
||||
}
|
||||
} else {
|
||||
if (app()->bound('sentry')) {
|
||||
app('sentry')->captureException($e);
|
||||
}
|
||||
$error = true;
|
||||
}
|
||||
} catch (CrmException $e) {
|
||||
Log::debug($e->getMessage());
|
||||
$error = true;
|
||||
if (app()->bound('sentry')) {
|
||||
app('sentry')->captureException($e);
|
||||
}
|
||||
} //end try
|
||||
|
||||
if (!is_null($error)) {
|
||||
return view('fo.pages.newsletter-unsubscribe')->with(
|
||||
'error',
|
||||
trans('Une erreur est survenue, merci de réessayer ultérieurement')
|
||||
);
|
||||
}
|
||||
return view('fo.pages.newsletter-unsubscribe');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,18 @@ class ContactRequest extends FormRequest
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the data for validation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'opt_in' => $this->boolean('opt_in'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
|
|
@ -40,7 +52,8 @@ class ContactRequest extends FormRequest
|
|||
'city' => 'nullable|string|max:255',
|
||||
'message' => 'required|string|min:20|max:255',
|
||||
'callTime' => ['required', new Enum(ContactTimeEnum::class)],
|
||||
'brigade' => 'nullable|boolean',
|
||||
'brigade' => 'nullable|boolean',
|
||||
'opt_in' => 'required|boolean',
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -81,7 +94,8 @@ class ContactRequest extends FormRequest
|
|||
'city' => trans('ville'),
|
||||
'message' => trans('message'),
|
||||
'callTime' => trans('préférence de rappel'),
|
||||
'brigade' => trans('La Brigade')
|
||||
'brigade' => trans('La Brigade'),
|
||||
'opt_in' => trans('newsletter'),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
30
app/Http/Requests/Fo/Newsletter/SingleOptinRequest.php
Normal file
30
app/Http/Requests/Fo/Newsletter/SingleOptinRequest.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Fo\Newsletter;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class SingleOptinRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'email' => 'required|email:rfc,dns,spoof',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Fo\Newsletter;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UnsubscribeNewsletterRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'hashcode' => 'required|uuid'
|
||||
];
|
||||
}
|
||||
}
|
||||
26
app/Providers/CrmApiServiceProvider.php
Normal file
26
app/Providers/CrmApiServiceProvider.php
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use LDC\LDCCRM\CrmApiV4;
|
||||
|
||||
class CrmApiServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap the application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
App::singleton('crmAPI', function () {
|
||||
return new CrmApiV4(
|
||||
config('crm.endpoint'),
|
||||
config('crm.token'),
|
||||
config('crm.password')
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
"laravel/framework": "^11.0",
|
||||
"laravel/tinker": "^2.8",
|
||||
"laravel/ui": "^4.2",
|
||||
"ldc/ldccrmv4client": "^4.0",
|
||||
"mews/purifier": "^3.4",
|
||||
"propaganistas/laravel-phone": "^5.0.3",
|
||||
"sentry/sentry-laravel": "^4.9",
|
||||
|
|
|
|||
187
composer.lock
generated
187
composer.lock
generated
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "2877466a2db551f8fec6c811bd7d59c4",
|
||||
"content-hash": "82e60c1c2f09c728135cd60aa5bc9ab5",
|
||||
"packages": [
|
||||
{
|
||||
"name": "24slides/laravel-saml2",
|
||||
|
|
@ -2405,6 +2405,63 @@
|
|||
},
|
||||
"time": "2025-01-28T15:15:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ldc/ldccrmv4client",
|
||||
"version": "4.0.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "git@lab.s-web.fr:ldc-web/projets/crm-client.git",
|
||||
"reference": "b54f61add50e93c68d26cadbe55d29216fcfc666"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://lab.s-web.fr/api/v4/projects/26/packages/composer/archives/ldc/ldccrmv4client.zip?sha=b54f61add50e93c68d26cadbe55d29216fcfc666",
|
||||
"reference": "b54f61add50e93c68d26cadbe55d29216fcfc666",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/inflector": "^2.0",
|
||||
"ext-curl": "*",
|
||||
"guzzlehttp/guzzle": "^7.4",
|
||||
"php": "^8.2",
|
||||
"respect/validation": "^2.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"orchestra/testbench": "^8.10",
|
||||
"phpunit/phpunit": "9.6",
|
||||
"slevomat/coding-standard": "^8.10",
|
||||
"squizlabs/php_codesniffer": "^3.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"LDC\\LDCCRM\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"LDC\\LDCCRM\\Tests\\": "tests"
|
||||
}
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jérémy Munsch",
|
||||
"email": "jeremy.munsch@ldc.fr",
|
||||
"homepage": "https://jeremydev.ovh"
|
||||
}
|
||||
],
|
||||
"description": "LDC CRM Client V4",
|
||||
"homepage": "https://github.com/kwaadpepper",
|
||||
"keywords": [
|
||||
"CRM",
|
||||
"Client",
|
||||
"LDC",
|
||||
"Laravel"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "league/commonmark",
|
||||
"version": "2.6.1",
|
||||
|
|
@ -5041,6 +5098,128 @@
|
|||
],
|
||||
"time": "2024-04-27T21:32:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "respect/stringifier",
|
||||
"version": "0.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Respect/Stringifier.git",
|
||||
"reference": "e55af3c8aeaeaa2abb5fa47a58a8e9688cc23b59"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Respect/Stringifier/zipball/e55af3c8aeaeaa2abb5fa47a58a8e9688cc23b59",
|
||||
"reference": "e55af3c8aeaeaa2abb5fa47a58a8e9688cc23b59",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.8",
|
||||
"malukenho/docheader": "^0.1.7",
|
||||
"phpunit/phpunit": "^6.4"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/stringify.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Respect\\Stringifier\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Respect/Stringifier Contributors",
|
||||
"homepage": "https://github.com/Respect/Stringifier/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Converts any value to a string",
|
||||
"homepage": "http://respect.github.io/Stringifier/",
|
||||
"keywords": [
|
||||
"respect",
|
||||
"stringifier",
|
||||
"stringify"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Respect/Stringifier/issues",
|
||||
"source": "https://github.com/Respect/Stringifier/tree/0.2.0"
|
||||
},
|
||||
"time": "2017-12-29T19:39:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "respect/validation",
|
||||
"version": "2.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Respect/Validation.git",
|
||||
"reference": "d1575eb4dde7b06f8dbc5e8d84dffb87931a40bd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Respect/Validation/zipball/d1575eb4dde7b06f8dbc5e8d84dffb87931a40bd",
|
||||
"reference": "d1575eb4dde7b06f8dbc5e8d84dffb87931a40bd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"respect/stringifier": "^0.2.0",
|
||||
"symfony/polyfill-mbstring": "^1.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"egulias/email-validator": "^3.0",
|
||||
"giggsey/libphonenumber-for-php-lite": "^8.13",
|
||||
"malukenho/docheader": "^1.0",
|
||||
"mikey179/vfsstream": "^1.6",
|
||||
"phpstan/phpstan": "^1.9",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.1",
|
||||
"phpstan/phpstan-phpunit": "^1.3",
|
||||
"phpunit/phpunit": "^9.6",
|
||||
"psr/http-message": "^1.0",
|
||||
"respect/coding-standard": "^4.0",
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
"suggest": {
|
||||
"egulias/email-validator": "Improves the Email rule if available",
|
||||
"ext-bcmath": "Arbitrary Precision Mathematics",
|
||||
"ext-fileinfo": "File Information",
|
||||
"ext-mbstring": "Multibyte String Functions",
|
||||
"giggsey/libphonenumber-for-php-lite": "Enables the phone rule if available"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Respect\\Validation\\": "library/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Respect/Validation Contributors",
|
||||
"homepage": "https://github.com/Respect/Validation/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "The most awesome validation engine ever created for PHP",
|
||||
"homepage": "http://respect.github.io/Validation/",
|
||||
"keywords": [
|
||||
"respect",
|
||||
"validation",
|
||||
"validator"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Respect/Validation/issues",
|
||||
"source": "https://github.com/Respect/Validation/tree/2.4.1"
|
||||
},
|
||||
"time": "2025-01-11T00:06:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "robrichards/xmlseclibs",
|
||||
"version": "3.1.3",
|
||||
|
|
@ -12275,12 +12454,12 @@
|
|||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"stability-flags": {},
|
||||
"prefer-stable": true,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": "^8.3"
|
||||
},
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.3.0"
|
||||
"platform-dev": {},
|
||||
"plugin-api-version": "2.6.0"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -179,6 +179,7 @@ return [
|
|||
App\Providers\EventServiceProvider::class,
|
||||
App\Providers\RouteServiceProvider::class,
|
||||
App\Providers\ViewServiceProvider::class,
|
||||
App\Providers\CrmApiServiceProvider::class,
|
||||
],
|
||||
|
||||
/*
|
||||
|
|
|
|||
7
config/crm.php
Normal file
7
config/crm.php
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'endpoint' => env('CRM_ENDPOINT'),
|
||||
'token' => env('CRM_TOKEN'),
|
||||
'password' => env('CRM_PASSWORD')
|
||||
];
|
||||
|
|
@ -33,7 +33,9 @@ data:
|
|||
SAML2_CONTACT_TECHNICAL_EMAIL: "${APP_SAML2_CONTACT_TECHNICAL_EMAIL}"
|
||||
SAML2_CONTACT_SUPPORT_EMAIL: "${APP_SAML2_CONTACT_SUPPORT_EMAIL}"
|
||||
SAML2_DEFAULT_TENANT_UUID: "${APP_SAML2_DEFAULT_TENANT_UUID}"
|
||||
|
||||
CRM_ENDPOINT: "${APP_CRM_ENDPOINT}"
|
||||
CRM_PASSWORD: "${APP_CRM_PASSWORD}"
|
||||
CRM_TOKEN: "${APP_CRM_TOKEN}"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
|
|
|
|||
|
|
@ -3,11 +3,21 @@ footer {
|
|||
|
||||
background-color: $color-bg-footer;
|
||||
|
||||
a { outline: none; }
|
||||
a:hover { color: $secondary; }
|
||||
a {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
ul { list-style-type: none; }
|
||||
.img-slogan-wrapper { max-width: 250px; }
|
||||
a:hover {
|
||||
color: $secondary;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.img-slogan-wrapper {
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
.deactivatable {
|
||||
position: relative;
|
||||
|
|
@ -25,8 +35,14 @@ footer {
|
|||
rotate: 0deg;
|
||||
transition: rotate 0.3s ease-in-out;
|
||||
}
|
||||
.deactivatable:hover::after { background: no-repeat center/cover url("@/images/fleche-hover.png"); }
|
||||
.deactivatable.active::after { rotate: 180deg; }
|
||||
|
||||
.deactivatable:hover::after {
|
||||
background: no-repeat center/cover url("@/images/fleche-hover.png");
|
||||
}
|
||||
|
||||
.deactivatable.active::after {
|
||||
rotate: 180deg;
|
||||
}
|
||||
}
|
||||
|
||||
// LLLLLLLLLLL GGGGGGGGGGGGG
|
||||
|
|
@ -45,26 +61,36 @@ footer {
|
|||
// L::::::::::::::::::::::L GG:::::::::::::::G
|
||||
// L::::::::::::::::::::::L GGG::::::GGG:::G
|
||||
// LLLLLLLLLLLLLLLLLLLLLLLL GGGGGG GGGG
|
||||
@include media-breakpoint-up(lg) { // >= 992px
|
||||
@include media-breakpoint-up(lg) {
|
||||
|
||||
// >= 992px
|
||||
footer {
|
||||
.banner-wrapper {
|
||||
> .row {
|
||||
>.row {
|
||||
width: 100%;
|
||||
flex-direction: row-reverse !important;
|
||||
}
|
||||
|
||||
.team-wrapper { flex: 3; }
|
||||
.team-wrapper {
|
||||
flex: 3;
|
||||
}
|
||||
|
||||
.social-wrapper {
|
||||
flex: 2;
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
.newsletter-wrapper {
|
||||
flex: 2;
|
||||
}
|
||||
}
|
||||
|
||||
.deactivatable {
|
||||
position: static;
|
||||
|
||||
&::after { display: none; }
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
import route from "../../modules/route";
|
||||
|
||||
const laravelRoute = route.methods.route;
|
||||
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
// BOUTON HAMBURGER
|
||||
|
|
@ -102,6 +105,51 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||
}));
|
||||
}
|
||||
|
||||
// Subscribe to newsletter
|
||||
const newsletterForms = document.querySelectorAll(".newsletter-wrapper");
|
||||
|
||||
newsletterForms.forEach(form => {
|
||||
const emailInput = form.querySelector(".newsletter-email") as HTMLInputElement;
|
||||
const submitBtn = form.querySelector(".newsletter-submit");
|
||||
const messageDiv = form.querySelector(".newsletter-message");
|
||||
|
||||
if (emailInput && submitBtn && messageDiv) {
|
||||
submitBtn.addEventListener("click", function (e) {
|
||||
e.preventDefault();
|
||||
messageDiv.classList.remove("alert", "alert-success", "alert-danger");
|
||||
messageDiv.textContent = "";
|
||||
|
||||
const addSingleOptinRoute = laravelRoute("fo.add-single-optin");
|
||||
if (!addSingleOptinRoute) return;
|
||||
|
||||
window.axios.post(addSingleOptinRoute, {
|
||||
email: emailInput.value,
|
||||
})
|
||||
.then(response => {
|
||||
messageDiv.classList.remove("d-none");
|
||||
messageDiv.classList.add("alert-success", "alert");
|
||||
messageDiv.textContent = String(response.data);
|
||||
emailInput.value = "";
|
||||
})
|
||||
.catch(error => {
|
||||
messageDiv.classList.remove("d-none");
|
||||
messageDiv.classList.add("alert-danger", "alert");
|
||||
if (error.response.status == 422) {
|
||||
const errors = error.response.data.errors;
|
||||
for (const errorKey in errors) {
|
||||
const errorP = document.createElement("p");
|
||||
errorP.classList.add("m-0");
|
||||
errorP.textContent = errors[errorKey];
|
||||
messageDiv.appendChild(errorP);
|
||||
}
|
||||
} else {
|
||||
messageDiv.textContent = error.response.data;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// PAGE NOS ACTUALITES
|
||||
// ON AFFICHE OU ON CACHE LES SOUS-MENUS DU HEADER
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
<div class="col newsletter-wrapper my-lg-5 mt-5">
|
||||
<div class="d-block d-md-flex align-items-center justify-content-center gap-2">
|
||||
<div>
|
||||
<p class="text-start">
|
||||
{{ __('Abonnez-vous à notre') }} <br />
|
||||
<span class="fw-bold fs-2 text-uppercase">{{ __('Newsletter') }}</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="newsletter-form">
|
||||
<div class="input-group rounded-4 mb-3 overflow-hidden">
|
||||
<input class="newsletter-email form-control rounded-start text-primary border-0 bg-white py-3" type="text"
|
||||
aria-label="Votre email" aria-describedby="basic-addon2" placeholder="{{ __('Votre email') }}">
|
||||
<button
|
||||
class="newsletter-submit btn bg-noir input-group-text text-uppercase fs-4 fw-bold rounded-0 px-3">{{ __('OK') }}</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-none newsletter-message my-3"></div>
|
||||
<p class="text-center">Pour toute information complémentaire concernant vos données personnelles et vos droits, merci de consulter
|
||||
notre <a>Charte de
|
||||
confidentialité.</a></p>
|
||||
</div>
|
||||
|
|
@ -17,4 +17,5 @@
|
|||
'{{ route('fo.product.add-product-to-basket', ['publishedProduct' => 'PRODUCT']) }}';
|
||||
window.__SYSTEM._routes['product.remove-product-from-basket'] =
|
||||
'{{ route('fo.product.remove-product-from-basket', ['slug' => 'SLUG']) }}';
|
||||
window.__SYSTEM._routes['fo.add-single-optin'] = '{{ route('fo.add-single-optin') }}';
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -133,8 +133,23 @@
|
|||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="row wrapper-sm p-3">
|
||||
<div class="col col-md-8 lh-sm px-0 py-2">
|
||||
<div class="form-check text-start">
|
||||
<input class="form-check-input @if ($errors->has('opt_in')) is-invalid @endif me-1" id="check-optin"
|
||||
name="opt_in" type="checkbox" @checked(old('opt_in'))>
|
||||
<label class="form-check-label w-fit" for="check-optin" role="button">
|
||||
{{ __('Je souhaite m’inscrire à la newsletter') }} {{ Config::get('theme.site_name') }}
|
||||
</label>
|
||||
</div>
|
||||
@foreach ($errors->get('opt_in') as $message)
|
||||
<div class="invalid-feedback d-block">{{ $message }}</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
<div class="row wrapper-sm mb-3">
|
||||
<div class="rgpg-wrapper d-flex align-items-center ff-poppins-regular fs-xxsm mt-1 p-3">
|
||||
<div class="rgpg-wrapper d-flex align-items-center ff-poppins-regular fs-xxsm px-3 py-1">
|
||||
<p>
|
||||
{{ __('Les informations recueillies à partir de ce formulaire sont traitées par le Responsable de Traitement pour donner suite à votre demande de contact. Pour connaître vos droits, vous pouvez consulter la') }}
|
||||
<a class="fw-bold text-decoration-underline" href="{{ route('fo.policies') }}"
|
||||
|
|
|
|||
42
resources/views/fo/pages/newsletter-unsubscribe.blade.php
Normal file
42
resources/views/fo/pages/newsletter-unsubscribe.blade.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
@php
|
||||
$staticPageModel = new stdClass();
|
||||
$staticPageModel->title = __('Désincription à la newsletter');
|
||||
$staticPageModel->subtitle = __('Vous partez déjà ?');
|
||||
$staticPageModel->picture = null;
|
||||
$staticPageModel->picture_title = '';
|
||||
$staticPageModel->picture_alt = '';
|
||||
@endphp
|
||||
|
||||
@extends('fo.layout', ['page' => 'unsubscribe'])
|
||||
|
||||
@section('title', __('Désincription à la newsletter'))
|
||||
@section('description', __('Page de désincription à la newsletter du site le Gaulois'))
|
||||
|
||||
@section('bannerHeader')
|
||||
@include('fo.partials.banner-header', [
|
||||
'title' => $staticPageModel->title,
|
||||
'description' => '',
|
||||
])
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
{{-- HEADER --}}
|
||||
|
||||
<div class="container mb-3 mt-5 pt-5">
|
||||
<div class="row mb-5">
|
||||
<div @class([
|
||||
'col-6 mx-auto alert fw-medium',
|
||||
'alert-danger' => isset($error),
|
||||
'alert-success' => !isset($error),
|
||||
])>
|
||||
<p>
|
||||
@isset($error)
|
||||
{{ $error }}
|
||||
@else
|
||||
{{ __("Votre désinscription a été effectuée avec succès. Si vous changez d'avis, n'hésitez pas à vous réinscrire !") }}
|
||||
@endisset
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<x-fo.newsletter.newsletter-subscribe />
|
||||
<div class="col social-wrapper my-lg-5 mt-5 text-center">
|
||||
<p class="ff-poppins-bold fs-banner-medium">
|
||||
{{ __('Restez connecté') }}<br>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,12 @@ Route::name('fo.')
|
|||
->group(function () {
|
||||
Route::get('/', [HomeController::class, 'index'])->name('homepage');
|
||||
|
||||
// * NEWSLETTER
|
||||
Route::post('/optin', [HomeController::class, 'addOptIn'])->name('add-single-optin');
|
||||
Route::get('/{unsubscribe}', [HomeController::class, 'unsubscribeNewsletter'])
|
||||
->where('unsubscribe', 'unsubscribe|unsubscribe.php|unsubscribe.html|newsletter')
|
||||
->name('unsubscribeNewsletter');
|
||||
|
||||
Route::prefix('/notre-adn')
|
||||
->name('adn.')
|
||||
->group(function () {
|
||||
|
|
@ -112,10 +118,12 @@ Route::name('fo.')
|
|||
Route::get('/{publishedProduct:slug}', [ProductsController::class, 'show'])
|
||||
->name('show');
|
||||
Route::post('/{publishedProduct:slug}/ajout-au-panier', [
|
||||
ProductsController::class, 'addProductToBasket'
|
||||
ProductsController::class,
|
||||
'addProductToBasket'
|
||||
])->name('add-product-to-basket');
|
||||
Route::get('/{publishedProduct:slug}/print-commercial-sheet', [
|
||||
ProductsController::class, 'printCommericalSheet'
|
||||
ProductsController::class,
|
||||
'printCommericalSheet'
|
||||
])->name('print-commercial-sheet');
|
||||
Route::post('/{slug}/retrait-du-panier', [ProductsController::class, 'removeProductFromBasket'])
|
||||
->name('remove-product-from-basket');
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue