Envoi fonctionnel sur Contact et Reclamation

This commit is contained in:
Jérémy Munsch 2021-02-11 20:41:26 +01:00
parent e1b2b9a48d
commit 02ed176752
40 changed files with 1916 additions and 14 deletions

View file

@ -0,0 +1,47 @@
<?php
namespace App\Enums;
use BadMethodCallException;
/**
* @method static self m()
* @method static self mme()
* @method static self mlle()
*/
final class ContactFormCivility extends BaseEnum
{
protected static function values(): array
{
return [
'm' => 1,
'mme' => 2,
'mlle' => 3,
];
}
protected static function labels(): array
{
return [
'm' => __('M'),
'mme' => __('Mme'),
'mlle' => __('Mlle')
];
}
public function __toString(): string
{
return (string) $this->label;
}
public static function make($value): BaseEnum
{
foreach (static::toArray() as $toValue => $labels) {
if ($value == $toValue) {
return parent::make(strtolower($labels));
}
}
$classname = static::class;
throw new BadMethodCallException("There's no value {$value} defined for enum {$classname}, consider adding it in the docblock definition.");
}
}

View file

@ -0,0 +1,28 @@
<?php
namespace App\Enums;
/**
* @method static self none()
* @method static self recipe()
* @method static self abuse()
* @method static self complain()
* @method static self games()
*/
final class ContactFormType extends BaseEnum
{
protected static function labels(): array
{
return [
'recipe' => __('Les Recettes'),
'abuse' => __('Le Club des Gaulois et Les Départ’aimants'),
'complain' => __('Réclamation Produit'),
'games' => __('Les Jeux')
];
}
public function __toString(): string
{
return (string) $this->label;
}
}

View file

@ -0,0 +1,14 @@
<?php
namespace App\Exceptions;
use Exception;
/**
* This class Exception is used to skip a row import from
* database migration (2016 -> 2020)
* @author Jérémy Munsch <jeremy.munsch@ldc.fr>
*/
class AbortContactMailer extends Exception
{
}

View file

@ -0,0 +1,14 @@
<?php
namespace App\Facades;
use App\Enums\ContactFormCivility as EnumsContactFormCivility;
use Illuminate\Support\Facades\Facade;
class ContactFormCivility extends Facade
{
protected static function getFacadeAccessor()
{
return EnumsContactFormCivility::class;
}
}

View file

@ -0,0 +1,14 @@
<?php
namespace App\Facades;
use App\Enums\ContactFormType as EnumsContactFormType;
use Illuminate\Support\Facades\Facade;
class ContactFormType extends Facade
{
protected static function getFacadeAccessor()
{
return EnumsContactFormType::class;
}
}

View file

@ -0,0 +1,98 @@
<?php
namespace App\Http\Controllers;
use App\Enums\ContactFormType;
use App\Exceptions\AbortContactMailer;
use App\Http\Requests\ContactFormRequest;
use App\Mail\Contact as MailsContact;
use App\Mail\ContactComplain as MailsContactComplain;
use App\Models\Contact as ModelsContact;
use App\Models\MailContactData;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
class ContactController extends Controller
{
public function contact(Request $request, ContactFormType $type = null)
{
$status = $request->status;
$user = null;
$type = $type ?? ContactFormType::none();
return view('front.contact.contact', compact('type', 'user', 'status'));
}
public function contactSubmit(ContactFormRequest $request)
{
try {
$data = new MailContactData();
$data->fill($request->all());
Mail::to(config('mail.contactsList.contact'))
->send(
new MailsContact(
$data,
realpath($this->getContactFilePathArchadia()) .
DIRECTORY_SEPARATOR .
sprintf('contact_le_gaulois_%d_%d.csv', time(), rand(1000, 9999))
)
);
ModelsContact::incrementStat($data->type);
return response()->redirectToRoute('contact-us', ['status' => true]);
} catch (AbortContactMailer $e) {
Log::error('Fail to build mail from contact page ', ['exception' => $e]);
}
return back()->withInput()->with('status', false);
}
public function complain(Request $request)
{
return $this->contact($request, ContactFormType::complain());
}
public function complainSubmit(ContactFormRequest $request)
{
try {
$data = new MailContactData();
$data->fill($request->all());
Mail::to(config('mail.contactsList.passerelle'))
->send(new MailsContactComplain(
$data,
realpath($this->getContactFilePathPasserelle()) .
DIRECTORY_SEPARATOR .
sprintf('LEGAULOIS_PASS_MESSAGE-%s.xml', date("YmdHis"))
));
ModelsContact::incrementStat($data->type);
return response()->redirectToRoute('product-request', ['status' => true]);
} catch (AbortContactMailer $e) {
Log::error('Fail to build mail from complain page ', ['exception' => $e]);
}
return back()->withInput()->with('status', false);
}
private function getContactFilePathArchadia($passerelle = false): string
{
$path = !$passerelle ?
config('contactfiles.dossierFichiersArchadia') :
config('contactfiles.dossierFichiersPasserelle');
if (!File::isDirectory($path)) {
if (!File::makeDirectory($path, 0007, true, true)) {
throw new AbortContactMailer(sprintf('Could not create %s', $path));
}
}
return $path;
}
private function getContactFilePathPasserelle(): string
{
return $this->getContactFilePathArchadia(true);
}
}

View file

@ -0,0 +1,37 @@
<?php
namespace App\Http\Requests;
class ComplainFormRequest extends ContactFormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return array_merge(parent::rules(), [
'productName' => 'required|min:2|max:100',
'productCode' => 'required|digits_between:8,13|min:1|max:9999999999999',
'buyPlace' => 'required|min:2|max:100',
'lotNumberName' => 'required|min:2|max:50',
'limitDateDay' => 'required|numeric|min:1|max:31',
'limitDateMonth' => 'required|numeric|min:1|max:31',
'limitDateYear' => 'required|numeric|min:2010|max:2050',
'consumptionDateDay' => 'required|numeric|min:1|max:31',
'consumptionDateMonth' => 'required|numeric|min:1|max:31',
'consumptionDateYear' => 'required|numeric|min:2010|max:2050',
]);
}
}

View file

@ -0,0 +1,61 @@
<?php
namespace App\Http\Requests;
use App\Enums\ContactFormCivility;
use App\Enums\ContactFormType;
use Illuminate\Foundation\Http\FormRequest;
class ContactFormRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'civility' => [
'required',
function ($attribute, $value, $fail) {
if (!in_array($value, ContactFormCivility::toValues())) {
$fail(__('Veuillez choisir entre :values', [
'value' => implode(',', ContactFormCivility::toLabels())
]));
}
}
],
'type' => [
'required',
function ($attribute, $value, $fail) {
if (!in_array($value, ContactFormType::toValues())) {
$fail(__('Veuillez choisir entre :values', [
'value' => implode(',', ContactFormType::toLabels())
]));
}
}
],
'lastname' => 'required|min:2',
'firstname' => 'required|min:2',
'address' => 'required|min:4',
// TODO: The dns and spoof validators require the PHP intl extension. (présent sur prod ?)
'email' => 'required|email:rfc,dns,spoof',
'postal' => 'required|min:3|max:12',
'town' => 'required|min:3|max:90',
'phone' => 'required|min:8|max:14',
'message' => 'required|min:20|max:1900',
'joinFile' => 'nullable|mimes:jpg,jpeg,png,pdf|max:3145728'
];
}
}

112
app/Mail/Contact.php Normal file
View file

@ -0,0 +1,112 @@
<?php
namespace App\Mail;
use App\Exceptions\AbortContactMailer;
use App\Models\MailContactData;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\File;
use League\Csv\Writer;
use SplTempFileObject;
class Contact extends Mailable
{
use Queueable;
use SerializesModels;
/**
* The order instance.
*
* @var MailContactData
*/
protected $data;
/**
* Where to store CSV FilePath
*
* @var string
*/
protected $csvFilePath;
/**
* The joined file name
*
* @var string
*/
protected $joinedFileName;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct(MailContactData $data, string $csvFilePath)
{
$this->data = $data;
$this->csvFilePath = $csvFilePath;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
$this->joinFileIfProvided();
$this->makeCsvFile();
return $this
->subject(sprintf('Nouveau message consommateur Le Gaulois (%s)', $this->data->type->label))
->view('emails.contact')
->text('emails.contact-plain')
->with('data', $this->data)
->attach($this->csvFilePath, [
'as' => sprintf('contact_le_gaulois_%d.csv', time()),
'mime' => 'text/csv',
]);
}
/**
* Attach a joined file if given in data
*
* @return void
*/
protected function joinFileIfProvided()
{
if ($this->data->joinFile) {
$this->joinedFileName = sprintf(
'LEGAULOIS_PASS_MESSAGE-PJ-%s.%s',
date("YmdHis"),
$this->data->joinFile->extension()
);
$this->attach($this->data->joinFile, [
'as' => $this->joinedFileName,
'mime' => $this->data->joinFile->getMimeType()
]);
$this->data->joinFile = $this->joinedFileName;
}
}
protected function makeCsvFile()
{
//we create the CSV into memory
// FILENAME
$csv = Writer::createFromFileObject(new SplTempFileObject());
$csv->setDelimiter(';');
//we insert the CSV header
$csv->insertOne([
'EMETTEUR_DATE', 'EMETTEUR_HEURE', 'EMETTEUR_CIVILITE', 'EMETTEUR_NOM', 'EMETTEUR_PRENOM',
'EMETTEUR_ADRESSE', 'EMETTEUR_CP', 'EMETTEUR_VILLE', 'EMETTEUR_EMAIL', 'EMETTEUR_OBJETDEMANDE',
'EMETTEUR_MESSAGE', 'EMETTEUR_CATEGORIE', 'EMETTEUR_ACTIVITE', 'REPONSE_ETAT', 'TYPE_REPONSE'
]);
$csv->insertOne($this->data->exportToArcadiaDataArray());
if (!File::put($this->csvFilePath, $csv->getContent())) {
throw new AbortContactMailer(sprintf('Could save create %s', $this->csvFilePath));
}
}
}

View file

@ -0,0 +1,70 @@
<?php
namespace App\Mail;
use App\Exceptions\AbortContactMailer;
use App\Models\MailContactData;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\File;
use League\Csv\Reader;
use League\Csv\Statement;
use League\Csv\XMLConverter;
class ContactComplain extends Contact
{
use Queueable;
use SerializesModels;
/**
* The order instance.
*
* @var MailContactData
*/
protected $data;
/**
* Where to store XML FilePath
*
* @var string
*/
protected $xmlFilePath;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct(MailContactData $data, string $xmlFilePath)
{
$this->data = $data;
$this->xmlFilePath = $xmlFilePath;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
$this->joinFileIfProvided();
$this->makeXmlFile();
return $this->view('emails.contact')
->subject(sprintf('Nouveau message consommateur Le Gaulois (%s)', $this->data->type->label))
->text('emails.contact-plain')
->with('data', $this->data)
->attach($this->xmlFilePath, [
'as' => sprintf('LEGAULOIS_PASS_MESSAGE_%d.xml', date("YmdHis")),
'mime' => 'application/xml',
]);
}
private function makeXmlFile()
{
$d = $this->data->exportToPasserelleDataArray();
if (!File::put($this->xmlFilePath, view('emails.passerelle-xml', ['data' => $d])->render())) {
throw new AbortContactMailer(sprintf('Could save create %s', $this->xmlFilePath));
}
}
}

View file

@ -0,0 +1,140 @@
<?php
namespace App\Models;
use App\Enums\ContactFormCivility;
use App\Enums\ContactFormType;
use App\Traits\CastsEnums;
use Illuminate\Database\Eloquent\Model;
/**
* This class is used to store data in memory only, not in databases
*/
class MailContactData extends Model
{
use CastsEnums;
protected $enumCasts = [
'type' => ContactFormType::class,
'civility' => ContactFormCivility::class
];
/**
* The database connection that should be used by the model.
*
* @var string
*/
protected $connection = null;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'civility',
'lastname',
'firstname',
'address',
'email',
'postal',
'town',
'phone',
'type',
'message',
'joinFile',
'productName',
'productCode',
'buyPlace',
'lotNumberName',
'limitDateDay',
'limitDateMonth',
'limitDateYear',
'consumptionDateDay',
'consumptionDateMonth',
'consumptionDateYear'
];
protected $attributes = [
'productName' => '',
'productCode' => '',
'buyPlace' => '',
'lotNumberName' => 0,
'limitDateDay' => '00',
'limitDateMonth' => '00',
'limitDateYear' => '0000',
'consumptionDateDay' => '00',
'consumptionDateMonth' => '00',
'consumptionDateYear' => '0000',
];
/**
* Export the model data to a Formatted Arcadia Data array
*
* @return array
*/
public function exportToArcadiaDataArray(): array
{
return [
date("Ymd"),
date("Gis"),
$this->civility->label,
$this->lastname,
$this->firstname,
$this->address,
$this->postal,
$this->town,
$this->email,
$this->type->label,
$this->message,
'0', '0', '0', '0'
];
}
/**
* Export the model data to a Formatted Arcadia Data array
*
* @return array
*/
public function exportToPasserelleDataArray(): array
{
// CF PAsserrelle fields .csv
return [
'EMETTEUR_MARQUE' => 1, // Marque le Gaulois (Obligatoire)
'EMETTEUR_DATE' => date("Ymd"), // (Obligatoire)
'EMETTEUR_HEURE' => date("Gis"), // (Obligatoire)
'EMETTEUR_CIVILITE' => $this->civility,
'EMETTEUR_NOM' => $this->lastname, // (Obligatoire)
'EMETTEUR_PRENOM' => $this->firstname, // (Obligatoire)
'EMETTEUR_ADRESSE1' => $this->address,
'EMETTEUR_ADRESSE2' => '',
'EMETTEUR_CP' => $this->postal,
'EMETTEUR_VILLE' => $this->town, // (Obligatoire)
'EMETTEUR_EMAIL' => $this->email,
'EMETTEUR_TELEPHONE' => $this->phone,
'EMETTEUR_PAYS' => 'France',
'EMETTEUR_NOM_PRODUIT' => $this->productName,
'EMETTEUR_EAN13' => $this->productCode, // (Obligatoire)
'EMETTEUR_DATE_LIMITE_CONSO' => sprintf(
'%s/%s/%s',
$this->limitDateDay ?? '00',
$this->limitDateMonth ?? '00',
$this->limitDateYear ?? '0000'
),
'EMETTEUR_NUM_LOT' => $this->lotNumberName,
'EMETTEUR_MESSAGE' => $this->message,
'EMETTEUR_PJ' => $this->joinFile,
// 'EMETTEUR_OBJETDEMANDE' => "objet de la reclamation string",
// 'EMETTEUR_OPT_IN' => '',
// 'REPONSE_ETAT' => 0,
// 'TYPE_REPONSE' => 'mail',
'DATE_CONSO' => sprintf(
'%s/%s/%s',
$this->consumptionDateDay ?? '00',
$this->consumptionDateMonth ?? '00',
$this->consumptionDateYear ?? '0000'
),
'LIEU_ACHAT' => $this->buyPlace
];
}
}

View file

@ -235,7 +235,8 @@ return [
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
'ContactFormCivility' => App\Enums\ContactFormCivility::class,
'ContactFormType' => App\Enums\ContactFormType::class
],
];

6
config/contactfiles.php Normal file
View file

@ -0,0 +1,6 @@
<?php
return [
'dossierFichiersArchadia' => storage_path('msg_conso/arch_message_arcadia'),
'dossierFichiersPasserelle' => storage_path('msg_conso/arch_message_passerelle')
];

View file

@ -84,8 +84,15 @@ return [
*/
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
'name' => env('MAIL_FROM_NAME', 'Example'),
'address' => env('MAIL_FROM_ADDRESS', 'contact@legaulois.fr'),
'name' => env('MAIL_FROM_NAME', 'Contact Le Gaulois (legaulois.fr)')
],
// Contacts List
'contactsList' => [
'contact' => 'contact@legaulois.fr',
'passerelle' => 'passerelle.ldc@ldc.fr'
],
/*

View file

@ -0,0 +1 @@
<svg id="Calque_1" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 64.52"><defs><style>.cls-1{fill:#f2ebe3;}.cls-2{fill:#07386a;}</style></defs><title>entete-contact</title><path class="cls-1" d="M0,0V63.82H800V0C800,35.49,0,35.49,0,0Z" transform="translate(0 0.7)"/><path class="cls-2" d="M800-.7V63.82H297.25v-38C297,26.37,796.67,30.5,800-.7Z" transform="translate(0 0.7)"/></svg>

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

View file

@ -0,0 +1 @@
<svg id="Calque_1" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 64.52"><defs><style>.cls-1{fill:#f2ebe3;}.cls-2{fill:#07386a;}</style></defs><title>entete-contact</title><path class="cls-1" d="M0,0V63.82H800V0C800,35.49,0,35.49,0,0Z" transform="translate(0 0.7)"/><path class="cls-2" d="M800-.7V63.82H297.25v-38C297,26.37,796.67,30.5,800-.7Z" transform="translate(0 0.7)"/></svg>

After

Width:  |  Height:  |  Size: 407 B

View file

@ -0,0 +1 @@
<svg id="Calque_1" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 64.52"><defs><style>.cls-1{fill:#f2ebe3;}.cls-2{fill:#07386a;}</style></defs><title>entete-contact</title><path class="cls-1" d="M0,0V63.82H800V0C800,35.49,0,35.49,0,0Z" transform="translate(0 0.7)"/><path class="cls-2" d="M800-.7V63.82H297.25v-38C297,26.37,796.67,30.5,800-.7Z" transform="translate(0 0.7)"/></svg>

After

Width:  |  Height:  |  Size: 407 B

View file

@ -1,5 +1,26 @@
// Body
$body-bg: #f8fafc;
$body-bg: #f3ebe4;
// Breaking Points
$large_screen : 1366px;
$big_screen : 1200px;
$desktop : 1024px;
$tablet : 768px;
$mobile : 500px;
$xmobile : 320px;
$minLscreen : only screen and (min-width: $large_screen);
$minBscreen : only screen and (min-width: $big_screen);
$minDesktop : only screen and (min-width: $desktop);
$minTablet : only screen and (min-width: $tablet);
$minMobile : only screen and (min-width: $mobile);
$minxMobile : only screen and (min-width: $xmobile);
$max499 : only screen and (max-width: 499px);
$max767 : only screen and (max-width: 767px);
$max1023 : only screen and (max-width: 1023px);
$max1199 : only screen and (max-width: 1199px);
$max1365 : only screen and (max-width: 1365px);
// Typography
$font-family-sans-serif: 'Nunito', sans-serif;
@ -23,3 +44,16 @@ $theme-colors: (
"primary": #3176C4,
"secondary": #E7374B
);
$color10: #999595;
$color11: #ab9d8e;
$color9: #c6bcb3;
$color1: #f3ebe4;
$color2: #07386a;
$color3: #0f437e;
$color4: #1e5ba1;
$color5: #4e3238;
$color6: #f79e15;
$color8: #ffb504;
$color7: #e02125;
$orange: #ffb400;

View file

@ -3,13 +3,36 @@
}
body {
background-color: #f3ebe4;
background-color: $body-bg;
& p {
color: #4e3238;
color: $color5;
font-size: 1.5em;
font-family: 'Catamaran-Regular';
line-height: 125%;
}
& h1, h2, h3, h4, h5, h6 {
color: $color5;
font-family: 'Veneer';
}
& h1 {
font-size: 7.5em;
}
& h2 {
font-size: 6em;
}
& h3 {
font-size: 4.2em;
}
& h4 {
font-size: 4em;
}
& h5 {
font-size: 3.2em;
}
& h6 {
font-size: 1.5em;
}
}

View file

@ -378,6 +378,34 @@
}
}
.sub_header_contact {
background-image: url(../images/faq/faq_background.jpg);
background-repeat: no-repeat;
background-position: center 94%;
background-size: 102% auto;
height: 50em;
width: 100%;
margin-top: 1.15em;
.title {
background-image: url(../images/commun/entete-contact.svg);
background-repeat: no-repeat;
background-position: center 100%;
background-size: 102% auto;
height: 42em;
z-index: 11;
position: relative;
h1 {
margin-top: 81px;
color: white;
text-align: center;
font-size: 7em;
font-family: 'Veneer';
}
}
}
.sub_header_ocb {
width: 100%;
height: 370px;

View file

@ -0,0 +1,92 @@
/******** BUTTONS *********/
.btn {
border: none;
color: #fff;
cursor: pointer;
display: inline-block;
font-family: 'Catamaran-Black';
font-size: 15px;
height: 40px;
line-height: 1.25;
margin-bottom: 0;
padding: 10px 25px;
text-align: center;
touch-action: manipulation;
vertical-align: middle;
white-space: nowrap;
}
.btn-red {
background-color: #e43b4e;
&:hover {
background-color: #d8293a;
}
}
.btn-white {
background-color: #fff;
border: 2px solid #2965a1;
color: #1e5ba1;
&:hover {
background-color: #2965a1;
color: #fff;
}
}
.btn-yellow {
background-color: #ffb400;
}
.btn-orange {
background-color: #e77b32;
}
.btn-blue {
background-color: #1e5ba1;
}
.btn-d0c2b3 {
background-color: #d0c2b3;
}
.btn-violet {
background-color: #974c99;
}
.btn-gris {
background-color: #91b0d4;
}
.btn-d5cbc1 {
background-color: #d5cbc1;
}
.btn-arronded-20 {
border-radius: 20px;
}
.btn-arronded-14 {
border-radius: 14px;
}
.btn-arronded-2 {
border-radius: 2px;
}
.btn-arronded-3 {
border-radius: 3px;
}
.btn-creamy-txt {
font-family: 'CreamyScriptRegular';
font-size: 2.2em;
text-transform: none;
}
.btn-veneer-txt {
font-family: 'Veneer';
font-size: 2.2em;
text-transform: none;
}

View file

@ -0,0 +1,380 @@
/******** Customize Checkbox *********/
@keyframes default-effect {
0% {
opacity : 0;
}
to {
opacity : 1;
}
}
.checkbox-wrap {
display: table;
&:hover {
.magic-checkbox {
+ label {
&:after {
//display: block;
}
}
}
}
.check {
display: table-cell;
position: relative;
vertical-align: text-top;
height: 20px; width: 20px;
&:hover {
.magic-checkbox {
+ label {
&:after {
display: block;
}
}
}
}
}
label {
color: #4e3238;
cursor: pointer;
font-family: 'Catamaran-Regular';
font-size: 12px;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}
> label {
display: table-cell;
vertical-align: middle;
}
&.blue-checkbox {
.magic-checkbox {
&:checked {
+ label {
&:before {
border: #1e5ba1;
background: #1e5ba1;
}
}
}
}
}
&.dark-checkbox {
.magic-checkbox {
&:checked {
+ label {
&:before {
border: #4e3238;
background: #4e3238;
}
}
}
}
}
&.big-checkbox {
.check {
height: 46px;
width: 46px;
&:hover {
+ label {
&:before {
border-color: #fff;
}
}
}
}
.magic-checkbox {
+ label:hover:before { border-color: #fff; }
}
.magic-checkbox, .magic-radio {
+ label {
padding-left: 60px;
&:before {
border-color: #fff;
height: 46px;
width: 46px;
}
&:after {
font-size: 21px;
left: 9px;
top: 12px;
// @media #{$minMobile} {
// left: 17px;
// top: 23px;
// }
}
&:hover {
&:before {
border-color: #fff;
}
}
}
}
}
&.checkbox-right {
.check {
padding-left: 15px;
}
.magic-checkbox {
+ label {
padding-left: 0;
}
}
}
&.check-2 {
line-height: 24px;
> label {
line-height: 125%;
text-align: left;
}
.magic-checkbox {
+ label {
line-height: 125%;
&:before {
border-color: #fff;
}
&:after {
color: #ffb400;
content: "\e903";
font-size: 24px;
left: 3px;
top: -3px;
}
}
&:checked {
+label {
&:before {
background: #fff;
border-color: #fff;
}
&:after {
}
}
}
}
}
&.check-3 {
line-height: 24px;
> label {
line-height: 125%;
}
.magic-checkbox {
+ label {
&:before {
border-color: #e5dace;
}
&:after {
color: #ffb400;
content: "\e903";
font-size: 24px;
left: 3px;
top: -6px;
}
}
&:checked {
+ label {
&:before {
background: #fff;
border-color: #e5dace;
}
}
}
}
}
&.check-4 {
> label {
line-height: 125%;
}
.magic-checkbox {
+ label {
&:before {
background-color: transparent;
border-color: #fff;
}
&:after {
color: #ffb400;
content: "\e903";
font-size: 24px;
left: 3px;
top: -3px;
}
}
&:checked {
+label {
&:before {
border-color: #fff;
border-width: 5px;
}
}
}
}
}
}
.dark-bgcolor {
.checkbox-wrap {
label {
color: #fff;
}
}
.magic-checkbox, .magic-radio {
+ label {
&:before {
border-color: #fff;
}
}
}
}
.magic-checkbox, .magic-radio {
position: absolute;
display: none;
+ label {
cursor: pointer;
display: block;
font-family: 'Catamaran-Regular';
padding-left: 30px;
position: relative;
vertical-align: middle;
&:before {
content: '';
display: inline-block;
position: absolute;
left: 0;
top: 0;
height: 20px;
width: 20px;
}
&:after {
content: '';
display: none;
position: absolute;
}
&:hover {
&:after {
animation-duration: .5s;
animation-fill-mode: both;
animation-name: default-effect;
}
}
}
&[disabled] {
cursor: not-allowed;
+ label {
color: #e4e4e4;
cursor: not-allowed;
&:after, &:before, &:hover { cursor: not-allowed; }
&:hover {
&:before {
animation-name: none;
border-color: #e4e4e4;
border-style: solid;
border-width: 1px;
}
}
&:before { border-color: #e4e4e4; }
}
}
&:checked {
+ label {
&:before { animation-name: none; }
}
}
}
.magic-checkbox {
+ label {
font-size: 12px;
&:before {
background-color: #fff;
border-color: #e5dace;
border-radius: 3px;
border-style: solid;
border-width: 2px;
}
&:after {
border-left: 0;
border-top: 0;
box-sizing: border-box;
color: #e5dace;
content: "\e902";
font-family: 'icomoon';
font-size: 9px;
left: 4px;
top: 4px;
}
&:hover {
&:after {
display: block;
}
}
}
&:checked {
&[disabled] {
+ label {
&:before {
background: #c9e2f9;
border-color: #c9e2f9;
}
}
}
+ label {
&:before {
border: #ffb400;
background: #ffb400;
}
&:after {
color: #fff;
display: block;
}
}
}
}
.magic-radio {
+ label {
color: #999595;
font-size: 14px;
line-height: 20px;
&:before {
background-color: #fff;
border-radius: 50%;
}
&:after {
background: #ffb400;
border-radius: 50%;
left: 6px;
top: 6px;
height: 8px;
width: 8px;
}
}
&:checked {
&[disabled] {
+ label {
&:before { border-color: #c9e2f9; }
&:after { background: #c9e2f9; }
}
}
+ label {
&:before {
}
&:after { display: block; }
}
}
&.bordered {
+ label {
color: #999595;
&:before {
border: 1px solid #999595;
}
&:after {}
}
}
&.bordered-2 {
+ label {
color: #e8ded5;
&:before {
border: 1px solid #e8ded5;
}
&:after {}
}
}
}

346
resources/sass/front/pages/_contact.scss vendored Normal file
View file

@ -0,0 +1,346 @@
.content.contact {
aside {
float: left;
padding-top: 75px;
padding-bottom: 50px;
width: 36.9%;
div {
margin-right: 35px;
max-width: 350px;
float: right;
margin-left: 10px;
p:nth-of-type(1) {
display: block;
font-family: "Veneer";
font-size: 4.3em;
margin-bottom: 15px;
}
p:nth-of-type(2) {
font-family: "CreamyScriptRegular";
font-size: 3.2em;
line-height: 28px;
margin-bottom: 30px;
}
p:nth-of-type(3) {
color: #ab9d8e;
margin-bottom: 15px;
}
p:nth-of-type(4) {
font-family: "Catamaran-Bold";
color: #ab9d8e;
}
}
}
section {
float: left;
padding-top: 75px;
width: 63.1%;
background-color: #07386a;
padding-left: 100px;
padding-bottom: 85px;
.text-white {
color: $color1;
}
h4 {
color: $orange;
font-family: 'CreamyScriptRegular';
font-size: 4em;
}
hr {
border: none;
background-color: #1e5ba1;
height: 1px;
margin-bottom: 30px;
}
label {
color: #fff;
font-family: "Catamaran-Bold";
font-size: 1.07em;
}
span {
color: #fff;
}
.statusMsg {
height: 745px;
p {
color: #fff;
font-family: "Catamaran-Bold";
font-size: 2em;
margin-bottom: 25px;
}
}
.form-contact {
width: 85%;
max-width: 593px;
.text-danger {
color: $color7;
padding: 1em;
font-size: 1em;
display: block;
}
.cvc {
input,
label,
span {
display: inline;
color: #fff;
font-family: "Catamaran-Bold";
margin-right: 10px;
}
margin-bottom: 20px;
}
.countries {
display: inline-block;
select {
font-size: 1em !important;
}
}
#contactFormError {
display: none;
color: white;
padding: 20px 25px;
background-color: #d8293a;
margin-bottom: 30px;
i {
margin-right: 10px;
}
}
.infoLot {
color: white;
font-style: italic;
margin-bottom: 10px;
}
.error {
background-color: #fcc9c9;
}
input[type="text"],
input[type="number"],
input[type="tel"],
input[type="email"] {
border: medium none;
border-radius: 2px;
color: #999595;
font-family: "Catamaran-Regular";
font-size: 1.1em;
margin: 0 13px 20px 0;
padding: 11px 10px;
width: 46.5%;
&::placeholder {
color: #999595;
}
}
input[type="number"] {
-moz-appearance: textfield;
}
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
.styled-select {
overflow: hidden;
width: 100%;
margin-bottom: 20px;
position: relative;
border-radius: 2px;
&:before {
color: #ffb504;
font-size: 2em;
display: inline-block;
position: absolute;
right: 15px;
top: 15px;
content: "\f078";
font-family: "FontAwesome";
pointer-events: none;
cursor: pointer;
}
&.countries {
width: 46.5%;
}
select {
border: medium none;
border-radius: 2px;
color: #999595;
font-family: "Catamaran-Regular";
font-size: 1.7em;
padding: 11px 10px;
width: 110%;
&::placeholder {
color: #999595;
}
}
}
textarea {
border: medium none;
border-radius: 2px;
color: #999595;
font-family: "Catamaran-Regular";
font-size: 1.1em;
margin: 0px 0 20px 0;
padding: 11px 10px;
width: 100%;
height: 160px;
resize: none;
&::placeholder {
color: #999595;
}
}
.formDateQualite {
display: inline-block;
width: 49.5%;
label {
display: block;
margin-bottom: 10px;
width: 100%;
}
input {
width: 26%;
}
}
.champPj {
font-size: 1.5em;
display: flex;
flex-wrap: wrap;
margin-bottom: 35px;
label {
width: 100px;
display: inline-block;
}
span.returnFile {
font-family: "CreamyScriptRegular";
font-size: 1.7em;
margin-left: 15px;
&.valid::after {
color: #ffb400;
content: "\e902";
font-family: "icomoon";
font-size: 0.8em;
margin-left: 5px;
}
&.unValid::after {
color: #e02125;
content: "\e90a";
font-family: "icomoon";
font-size: 0.8em;
margin-left: 5px;
}
}
.fileUpload {
cursor: pointer;
position: relative;
width: 225px;
height: 79px;
input[type="file"] {
border: medium none;
box-shadow: none;
cursor: pointer;
height: 100%;
left: 0;
opacity: 0;
padding: 0;
position: absolute;
top: 0;
width: 100%;
z-index: 2;
}
#btnup {
border: none;
color: #fff;
cursor: pointer;
display: inline-block;
font-family: "Catamaran-Black";
height: 30px;
margin-bottom: 0;
padding: 3px 10px;
background-color: #ffb400;
border-radius: 2px;
text-transform: uppercase;
width: 100%;
text-align: center;
i {
font-size: 1.3em;
margin-right: 8px;
vertical-align: sub;
}
}
span:nth-of-type(2) {
display: block;
font-size: 0.9em;
margin-top: 7px;
}
}
}
.envoyer {
align-items: center;
display: flex;
justify-content: flex-end;
span {
margin-right: 2em;
sup {
color: $orange;
line-height: 2em;
font-family: "Catamaran-Bold";
font-size: 1.1em;
}
}
.btn {
width: 200px;
text-transform: uppercase;
}
}
}
}
}

View file

@ -1,11 +1,14 @@
@import "~normalize.css/normalize.css";
@import "~@fortawesome/fontawesome-free/css/all.min.css";
@import "variables";
@import "front/reset";
@import "front/fonts";
@import "front/body";
@import "front/header";
@import "front/sub_header";
@import "front/footer";
@import "front/modules/magic-check";
@import "front/modules/buttons";
.pattern {
background-repeat: repeat;
@ -61,8 +64,15 @@
background-color: #64ab4b !important;
}
.display {
display: block !important;
}
.display-none {
display: none !important;
}
@import "front/pages/home";
@import "front/pages/contact";
@import "front/pages/products";
@import "front/pages/product";
@import "front/pages/legals";

View file

@ -0,0 +1,21 @@
Cette personne à utilisé le formulaire de contact du site legaulois.fr
Personne :
{{ $data->type->label }} {{ $data->lastname }} {{ $data->firstname }}
Adresse :
{{ $data->address }}
{{ $data->town }} {{ $data->postal }}
Contact :
{{ $data->phone }}
{{ $data->email }}
Sujet :
{{ $data->type->label }}
Message :
{{ $data->message }}
Fichier en pièce jointe.

View file

@ -0,0 +1,24 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Nouveau Contact Le Gaulois</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<h2>Cette personne à utilisé le formulaire de contact du site <a href="https://legaulois.fr" title="Visiter legaulois.fr">legaulois.fr</a></h2>
<p><u>Personne</u>&nbsp;:&nbsp;</p>
<p>{{ $data->civility->label }} {{ $data->lastname }} {{ $data->firstname }}</p>
<p><u>Adresse</u>&nbsp;:&nbsp;</p>
<p>{{ $data->address }}</p>
<p>{{ $data->town }} {{ $data->postal }}</p>
<p><u>Contact</u>&nbsp;:&nbsp;</p>
<p><a href="tel:{{ $data->phone }}" title="{{ $data->phone }}">{{ $data->phone }}</a></p>
<p><a href="mailto:{{ $data->email }}" title="{{ $data->email }}">{{ $data->email }}</a></p>
<p><u>Sujet</u>&nbsp;:&nbsp;</p>
<p>{{ $data->type->label }}</p>
<p><u>Message</u>&nbsp;:&nbsp;</p>
<p>{{ $data->message }}</p>
<p>Fichier en pièce jointe.</p>
</body>
</html>

View file

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<PASS_MESSAGE>
<MESSAGE>
<EMETTEUR_MARQUE>{{ $data ['EMETTEUR_MARQUE'] }}</EMETTEUR_MARQUE>
<EMETTEUR_DATE>{{ $data ['EMETTEUR_DATE'] }}</EMETTEUR_DATE>
<EMETTEUR_HEURE>{{ $data ['EMETTEUR_HEURE'] }}</EMETTEUR_HEURE>
<EMETTEUR_CIVILITE>{{ $data ['EMETTEUR_CIVILITE'] }}</EMETTEUR_CIVILITE>
<EMETTEUR_NOM>
<![CDATA[{{ $data ['EMETTEUR_NOM'] }}]]>
</EMETTEUR_NOM>
<EMETTEUR_PRENOM>
<![CDATA[{{ $data ['EMETTEUR_PRENOM'] }}]]>
</EMETTEUR_PRENOM>
<EMETTEUR_ADRESSE1>
<![CDATA[{{ $data ['EMETTEUR_ADRESSE1'] }}]]>
</EMETTEUR_ADRESSE1>
<EMETTEUR_ADRESSE2>
<![CDATA[{{ $data ['EMETTEUR_ADRESSE1'] }}]]>
</EMETTEUR_ADRESSE2>
<EMETTEUR_CP>
<![CDATA[{{ $data ['EMETTEUR_CP'] }}]]>
</EMETTEUR_CP>
<EMETTEUR_VILLE>
<![CDATA[{{ $data ['EMETTEUR_VILLE'] }}]]>
</EMETTEUR_VILLE>
<EMETTEUR_PAYS>{{ $data ['EMETTEUR_PAYS'] }}</EMETTEUR_PAYS>
<EMETTEUR_EMAIL>{{ $data ['EMETTEUR_EMAIL'] }}</EMETTEUR_EMAIL>
<EMETTEUR_TELEPHONE>
<![CDATA[{{ $data ['EMETTEUR_TELEPHONE'] }}]]>
</EMETTEUR_TELEPHONE>{{-- <EMETTEUR_OBJETDEMANDE>{{ $data ['EMETTEUR_OBJETDEMANDE'] }}</EMETTEUR_OBJETDEMANDE> --}}
<EMETTEUR_NOM_PRODUIT>
<![CDATA[{{ $data ['EMETTEUR_NOM_PRODUIT'] }}]]>
</EMETTEUR_NOM_PRODUIT>
<EMETTEUR_EAN13>
<![CDATA[{{ $data ['EMETTEUR_EAN13'] }}]]>
</EMETTEUR_EAN13>
<EMETTEUR_DATE_LIMITE_CONSO>{{ $data ['EMETTEUR_DATE_LIMITE_CONSO'] }}</EMETTEUR_DATE_LIMITE_CONSO>
<EMETTEUR_NUM_LOT>
<![CDATA[{{ $data ['EMETTEUR_NUM_LOT'] }}]]>
</EMETTEUR_NUM_LOT>{{-- <EMETTEUR_OPT_IN>{{ $data ['EMETTEUR_OPT_IN'] }}</EMETTEUR_OPT_IN> --}}
<EMETTEUR_MESSAGE>
<![CDATA[{{ $data ['EMETTEUR_MESSAGE'] }}]]>
</EMETTEUR_MESSAGE>
<EMETTEUR_PJ>
<![CDATA[{{ $data ['EMETTEUR_PJ'] }}]]>
</EMETTEUR_PJ> {{-- <REPONSE_ETAT>{{ $data ['REPONSE_ETAT'] }}</REPONSE_ETAT>
<TYPE_REPONSE>{{ $data ['TYPE_REPONSE'] }}</TYPE_REPONSE> --}}
<DATE_CONSO>{{ $data ['DATE_CONSO'] }}</DATE_CONSO>
<LIEU_ACHAT>
<![CDATA[{{ $data ['LIEU_ACHAT'] }}]]>
</LIEU_ACHAT>
</MESSAGE>
</PASS_MESSAGE>

View file

@ -0,0 +1,143 @@
<form action="{{ $type->equals(ContactFormType::complain()) ? route('product-request.submit') : route('contact-us.submit') }}" class="form-contact" method="post" enctype="multipart/form-data">
@csrf
<p id="contactFormError" @if(count($errors))class="display" @endif>
@include('front.icons.exclamation-triangle')
{{ __('Merci de compléter correctement les champs du formulaire.') }}
</p>
<h4>{{ __('Mes coordonnées') }}</h4>
<p class="clearfix cvc">
<span>{{ __('Civilité') }}</span>
@foreach(ContactFormCivility::toArray() as $ctCivValue => $ctCivLabel)
<input class="magic-radio" value="{{ $ctCivValue }}" type="radio" name="civility" id="civ{{ $ctCivValue }}" @if(old('civility')==$ctCivValue)checked @endif required>
<label for="civ{{ $ctCivValue }}">{{ $ctCivLabel }}</label>
@endforeach
@if($errors->default->has('civility'))<small class="text-danger">{{ implode('<br>', $errors->default->get('civility')) }}</small>@endif
</p>
<p class="clearfix">
{{-- // TODO test user data from logged --}}
<input type="text" name="lastname" value="@if(!is_null($user)){{ $user->lastname }}@endif{{ old('lastname') }}" placeholder="{{ __('Nom') }}*" minlength="2" required>
@if($errors->default->has('lastname'))<small class="text-danger">{{ implode('<br>', $errors->default->get('lastname')) }}</small>@endif
<input type="text" name="firstname" value="@if(!is_null($user)){{ $user->firstname }}@endif{{ old('firstname') }}" placeholder="{{ __('Prénom') }}*" minlength="2" required>
@if($errors->default->has('firstname'))<small class="text-danger">{{ implode('<br>', $errors->default->get('firstname')) }}</small>@endif
<input type="text" name="address" value="@if(!is_null($user)){{ $user->address }}@endif{{ old('address') }}" placeholder="{{ __('Adresse') }}*" minlength="4" required>
@if($errors->default->has('address'))<small class="text-danger">{{ implode('<br>', $errors->default->get('address')) }}</small>@endif
<input type="email" name="email" value="@if(!is_null($user)){{ $user->email }}@endif{{ old('email') }}" placeholder="{{ __('E-mail') }}*" required>
@if($errors->default->has('email'))<small class="text-danger">{{ implode('<br>', $errors->default->get('email')) }}</small>@endif
<input type="text" name="postal" value="@if(!is_null($user)){{ $user->postal }}@endif{{ old('postal') }}" placeholder="{{ __('Code postal') }}*" minlength="4" maxlength="10" required>
@if($errors->default->has('postal'))<small class="text-danger">{{ implode('<br>', $errors->default->get('postal')) }}</small>@endif
<input type="text" name="town" value="@if(!is_null($user)){{ $user->town }}@endif{{ old('town') }}" placeholder="{{ __('Ville') }}*" minlength="3" maxlength="90" required>
@if($errors->default->has('town'))<small class="text-danger">{{ implode('<br>', $errors->default->get('town')) }}</small>@endif
<input type="tel" name="phone" value="@if(!is_null($user)){{ $user->phone }}@endif{{ old('phone') }}" placeholder="{{ __('Téléphone') }}" minlength="8" maxlength="14" />
@if($errors->default->has('phone'))<small class="text-danger">{{ implode('<br>', $errors->default->get('phone')) }}</small>@endif
</p>
<hr />
@if($type->equals(ContactFormType::recipe()))
<h4>{{ __('Proposez votre recette') }}&nbsp;:</h4>
@elseif($type->equals(ContactFormType::abuse()))
<h4>{{ __('Signaler un abus') }}&nbsp;:</h4>
@elseif($type->equals(ContactFormType::complain()))
<h4>{{ __('Réclamation Produit') }}&nbsp;:</h4>
@else
<h4>{{ __('Votre question concerne')}}&nbsp;:</h4>
@endif
@if($type->equals(ContactFormType::complain()))
<input type="text" class="display-none" name="type" value="{{ ContactFormType::complain()->value }}" readonly />
@else
<div class="styled-select">
<select name="type" placeholder="{{ __('Votre demande concerne*') }}" required>
<option disabled @if(!old('type'))selected @endif>{{ __('Sélectionnez une demande') }}</option>
@foreach(ContactFormType::toArray() as $ctValue => $ctLabel)
@if($ctValue != ContactFormType::complain()->value && $ctValue != ContactFormType::none()->value)
<option value="{{ $ctValue }}" @if($type->value == old('type') || $type->equals(ContactFormType::make($ctValue)))selected @endif>{{ $ctLabel }}</option>
@endif
@endforeach
</select>
@if($errors->default->has('type'))<small class="text-danger">{{ implode('<br>', $errors->default->get('type')) }}</small>@endif
</div>
@endif
@if($type->equals(ContactFormType::complain()))
<div>
<p class="clearfix">
<input type="text" name="productName" value="{{ old('productName') }}" minlength="2" maxlength="100" placeholder="{{ __('Nom du produit') }}*" required>
<input type="number" name="productCode" value="{{ old('productCode') }}" min="1" max="9999999999999" placeholder="{{ __('Code barre du produit concerné') }}*" required>
<input type="text" name="buyPlace" value="{{ old('buyPlace') }}" minlength="2" maxlength="100" placeholder="{{ __('Lieu d\'achat') }}*" required>
<input type="text" name="lotNumberName" value="{{ old('lotNumberName') }}" minlength="2" maxlength="50" placeholder="{{ __('N° de lot figurant à coté de la date') }}*" required>
</p>
<p class="infoLot">
@include('front.icons.info-circle')
{{ __('Vous pouvez également trouver le n° de lot sous la dénomination "n° de tracabilité" ou "n° trac".') }}
</p>
<p class="formDateQualite">
<label for="limitDateDay">{{ __('Date limite de consommation') }}*</label>
<input type="number" id="limitDateDay" name="limitDateDay" value="{{ old('limitDateDay') }}" min="1" max="31" placeholder="{{ __('jj') }}" required>
<input type="number" name="limitDateMonth" value="{{ old('limitDateMonth') }}" min="1" max="12" placeholder="{{ __('mm') }}" required>
<input type="number" name="limitDateYear" value="{{ old('limitDateYear') }}" min="2010" max="2050" placeholder="{{ __('aaaa') }}" required>
</p>
<p class="formDateQualite">
<label for="consumptionDateDay">{{ __('Date de consommation') }}*</label>
<input type="number" id="consumptionDateDay" name="consumptionDateDay" value="{{ old('consumptionDateDay') }}" min="1" max="31" placeholder="{{ __('jj') }}" required>
<input type="number" name="consumptionDateMonth" value="{{ old('consumptionDateMonth') }}" min="1" max="12" placeholder="{{ __('mm') }}" required>
<input type="number" name="consumptionDateYear" value="{{ old('consumptionDateYear') }}" min="2010" max="2050" placeholder="{{ __('aaaa') }}" required>
</p>
</div>
<div class="champPj">
<label for="joinFile">{{ __('Pièce jointe') }}</label>
<div class="fileUpload">
<input type="file" name="joinFile" id="joinFile" accept=".jpg,.jpeg,.png,.pdf, image/jpg,image/png,application/pdf" />
<span id="btnup">
@include('front.icons.icon-upload')
{{ __('Ajouter un fichier') }}
</span>
<span>{{ __('Formats acceptés') }}&nbsp;:&nbsp;jpg,&nbsp;png,&nbsp;pdf<br>{{ __('Taille max') }}&nbsp;:&nbsp;{{ __(':datasize Mo', ['datasize' => 3]) }}</span>
</div>
<span id="returnFile"></span>
@if($errors->default->has('joinFile'))<small class="text-danger">{{ implode('<br>', $errors->default->get('joinFile')) }}</small>@endif
</div>
@endif
<p class="clearfix">
<textarea name="message" id="contactMessage" cols="1" rows="1" minlength="20" maxlength="1900" placeholder="{{ __('Votre message') }}..." required>{{ old('message') }}</textarea>
@if($errors->default->has('message'))<small class="text-danger">{{ implode('<br>', $errors->default->get('message')) }}</small>@endif
</p>
<p class="envoyer">
<span><sup>*</sup>{{ __('Champs obligatoires') }}</span>
<button title="Envoyer" class="btn btn-red btn-arronded-20 text-uppercase">{{ __('Envoyer') }}</button>
</p>
</form>
@push('scripts')
<script>
document.getElementById('contactMessage').addEventListener('onkeypress', function(e) {
this.value = this.value.substr(0, 1900);
});
document.getElementById('joinFile').onchange = function(e) {
let joinfFile = document.getElementById('joinFile');
let returnFile = document.getElementById('returnFile');
let ext = e.target.files[0].name.split('.').pop();
returnFile.innerText = joinfFile.value;
if (['png', 'jpg', 'jpeg', 'pdf'].indexOf(ext) === -1) {
returnFile.classList.add('unValid');
returnFile.classList.remove('valid');
} else {
returnFile.classList.add('valid');
returnFile.classList.remove('unValid');
}
};
</script>
@endpush

View file

@ -0,0 +1,44 @@
@extends('layouts.app')
@section('title', __('Formulaire de contact'))
@section('description', __('Envie de partager une remarque, une idée avec nous, de poser une question : n\'hésitez pas à compléter le formulaire de contact.'))
@section('sub_header')
<div class="sub_header sub_header_contact">
<div class="title">
<h1>{{ __('Contactez-nous') }}</h1>
</div>
</div>
@endsection
@section('content')
<div class="content contact clearfix">
<aside>
<div>
<p>{{ __('Bonjour,') }}</p>
<p>{{ __('Si vous avez une question à nous poser ou des remarques à formuler sur notre site, n\'hésitez pas à les inscrire dans le formulaire ci-contre. Merci d\'indiquer vos coordonnées exactes pour que nous puissions vous répondre prochainement.') }}</p>
<p>{{ __('Les informations qui vous concernent sont destinées à un usage interne et ne seront en aucun cas transmises à des tiers. Vous disposez d\'un droit d\'accès, de modification, de rectification et de suppression des données qui vous concernent (art. 34 de la loi "Informatique et Libertés").') }}</p>
</div>
</aside>
<section>
{{-- IF MAIL IS SENT --}}
@if(!is_null($status))
<div class="statusMsg">
@if($status)
<p>{{ __('Votre message a été envoyé avec succès.') }}</p>
@else
<p>{{ __('Une erreur est survenue durant l\'envoi de votre message. Veuillez réessayer ultèrieurement.') }}</p>
@endif
<a href="{{ route('home') }}" class="btn btn-red btn-arronded-20 text-uppercase">{{ __('Retour à l\'accueil') }}</a>
</div>
@else
@if(!$type->equals(ContactFormType::complain()))
<p class="text-white">{{ __('Si vous désirez plutôt envoyer une réclamation utilisez ce lien') }}<br>
<a href="{{ route('product-request') }}" class="btn btn-red btn-arronded-20 text-uppercase">{{ __('Envoyer une réclamation') }}</a></p>
<br>
@endif
@include('front.contact.contact-form')
@endif
</section>
</div>
@endsection

View file

@ -0,0 +1,40 @@
@extends('layouts.app')
@section('title', __('Formulaire de contact'))
@section('description', __('Envie de partager une remarque, une idée avec nous, de poser une question : n\'hésitez pas à compléter le formulaire de contact.'))
@section('sub_header')
<div class="sub_header_contact">
<div class="title">
<h1>{{ __('Contactez-nous') }}</h1>
</div>
</div>
@endsection
@section('content')
<div class="content contact clearfix">
<aside>
<div>
<p>{{ __('Bonjour,') }}</p>
<p>{{ __('Si vous avez une question à nous poser ou des remarques à formuler sur notre site, n\'hésitez pas à les inscrire dans le formulaire ci-contre. Merci d\'indiquer vos coordonnées exactes pour que nous puissions vous répondre prochainement.') }}</p>
<p>{{ __('Les informations qui vous concernent sont destinées à un usage interne et ne seront en aucun cas transmises à des tiers. Vous disposez d\'un droit d\'accès, de modification, de rectification et de suppression des données qui vous concernent (art. 34 de la loi "Informatique et Libertés").') }}</p>
</div>
</aside>
<section>
{{-- IF MAIL IS SENT --}}
@if(!is_null($status))
<div class="statusMsg">
@if($status)
<p>{{ __('Votre message a été envoyé avec succès.') }}</p>
@else
<p>{{ __('Une erreur est survenue durant l\'envoi de votre message. Veuillez réessayer ultèrieurement.') }}</p>
@endif
<a href="{{ route('home') }}" class="btn btn-red btn-arronded-20 text-uppercase">{{ __('Retour à l\'accueil') }}</a>
</div>
@else
<a href="{{ route('product-request') }}" class="btn btn-red btn-arronded-20 text-uppercase">{{ __('Envoyer une réclamation') }}</a>
@include('front.contact.contact-form')
@endif
</section>
</div>
@endsection

View file

@ -0,0 +1,3 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="chevron-down" class="svg-inline--fa fa-chevron-down fa-w-14" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
<path fill="currentColor" d="M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z"></path>
</svg>

After

Width:  |  Height:  |  Size: 530 B

View file

@ -0,0 +1,3 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="exclamation-triangle" class="svg-inline--fa fa-exclamation-triangle fa-w-18" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
<path fill="currentColor" d="M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"></path>
</svg>

After

Width:  |  Height:  |  Size: 715 B

View file

@ -0,0 +1,3 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="upload" class="svg-inline--fa fa-upload fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path fill="currentColor" d="M296 384h-80c-13.3 0-24-10.7-24-24V192h-87.7c-17.8 0-26.7-21.5-14.1-34.1L242.3 5.7c7.5-7.5 19.8-7.5 27.3 0l152.2 152.2c12.6 12.6 3.7 34.1-14.1 34.1H320v168c0 13.3-10.7 24-24 24zm216-8v112c0 13.3-10.7 24-24 24H24c-13.3 0-24-10.7-24-24V376c0-13.3 10.7-24 24-24h136v8c0 30.9 25.1 56 56 56h80c30.9 0 56-25.1 56-56v-8h136c13.3 0 24 10.7 24 24zm-124 88c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20zm64 0c0-11-9-20-20-20s-20 9-20 20 9 20 20 20 20-9 20-20z"></path>
</svg>

After

Width:  |  Height:  |  Size: 692 B

View file

@ -0,0 +1,3 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="info-circle" class="svg-inline--fa fa-info-circle fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path fill="currentColor" d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"></path>
</svg>

After

Width:  |  Height:  |  Size: 648 B

View file

@ -43,7 +43,7 @@
@yield('content')
@include('layouts.app-footer')
</div>
@yield('scripts')
<script src="{{ asset('js/main.js') }}"></script>
@stack('scripts')
</body>
</html>

View file

@ -99,18 +99,15 @@ Route::get('/deconnexion', 'CustomerController@logout')->name('deconnexion')->mi
Route::get('/reinitialiser-mdp', 'CustomerController@passwordReset')->name('reinit-mdp');
Route::post('/change-mdp/{token}', 'CustomerController@changePassword')->name('change-mdp');
Route::get('/contactez-nous', function (){
die('Nous contacter');
})->name('contact-us');
Route::get('/contactez-nous', 'ContactController@contact')->name('contact-us');
Route::post('/contactez-nous', 'ContactController@contactSubmit')->name('contact-us.submit');
Route::get('/reclamation-produit', 'ContactController@complain')->name('product-request');
Route::post('/reclamation-produit', 'ContactController@complainSubmit')->name('product-request.submit');
Route::get('/faq', function (){
die('FAQ');
})->name('faq');
Route::get('/reclamation-produit', function (){
die('reclamation-produit');
})->name('product-request');
Route::get('/mentions-legales', function (){
return view('front.legals');
})->name('legal-notice');

View file

@ -0,0 +1 @@
*

View file

@ -0,0 +1 @@
*