Entretenir : Formulaire/modale

preview (image)
  • template
<?php $concessions = file_get_contents(__DIR__ . "/concessions.json"); ?>
<script>
const concessionsDatasForm = <?= $concessions ?>;
</script>
<div class="maintain-modal fixed inset-0 z-[100]"
x-data="initMaintainFormModal()"
@keydown.escape.window="close()"
:class="{
'block' : modalOpen,
'hidden' : !modalOpen
}"
x-cloak
>
<div class="maintain-modal__overlay absolute inset-0 bg-primary opacity-40 cursor-pointer transition duration-300 translate-x-full"
:class="{
'translate-x-0' : isOpen,
'translate-x-full' : !isOpen
}"
@click="close()"
></div>
<div class="maintain-modal__content absolute z-10 right-0 top-0 bottom-0 flex flex-col transition duration-[350ms] lg:w-[920px]"
:class="{
'translate-x-0' : isOpen,
'translate-x-full' : !isOpen
}"
>
<div class="h-screen ml-auto bg-ui-light md:max-w-[920px] w-full flex flex-col" x-data="initMaintainForm()">
<?php /* Modal header */ ?>
<div class="maintain-modal__header bg-white border-b border-ui flex justify-between items-center pl-7 md:pl-7.5 relative">
<div class="text-base md:text-smaller font-semibold">Prendre rendez-vous</div>
<div class="numbered-steps flex items-center mx-auto sm:w-fit absolute bottom-[-15px] left-0 right-0 px-7.5 md:px-0 md:static z-1">
<div class="numbered-steps__step"
:class="{
'numbered-steps__step--fill': mainStep > 1
}"
>
<span>1</span>
<?= icon('check', 'w-3.5'); ?>
</div>
<div class="numbered-steps__separator"></div>
<div class="numbered-steps__step numbered-steps__step--inactive"
:class="{
'numbered-steps__step--fill': mainStep > 2,
'numbered-steps__step--inactive': mainStep < 2
}"
>
<span>2</span>
<?= icon('check', 'w-3.5'); ?>
</div>
<div class="numbered-steps__separator numbered-steps__separator--inactive" :class="{'numbered-steps__separator--inactive': mainStep < 3}"></div>
<div class="numbered-steps__step numbered-steps__step--inactive"
:class="{
'numbered-steps__step--fill': mainStep > 3,
'numbered-steps__step--inactive': mainStep < 3
}"
>
<span>3</span>
<?= icon('check', 'w-3.5'); ?>
</div>
<div class="numbered-steps__separator numbered-steps__separator--inactive" :class="{'numbered-steps__separator--inactive': mainStep < 4}"></div>
<div class="numbered-steps__step numbered-steps__step--inactive"
:class="{
'numbered-steps__step--fill': mainStep > 4,
'numbered-steps__step--inactive': mainStep < 4
}"
>
<span>4</span>
<?= icon('check', 'w-3.5'); ?>
</div>
<div class="numbered-steps__separator numbered-steps__separator--inactive" :class="{'numbered-steps__separator--inactive': mainStep < 4}"></div>
<div class="numbered-steps__step numbered-steps__step--inactive"
:class="{
'numbered-steps__step--fill': mainStep > 5,
'numbered-steps__step--inactive': mainStep < 5
}"
>
<span>5</span>
<?= icon('check', 'w-3.5'); ?>
</div>
</div>
<div>
<button @click="$dispatch('closeBookingModal')" class="link text-primary-accent hover:text-secondary px-7.5 pt-8.75 pb-9.5"><?= icon('close', 'w-3.25'); ?></button>
</div>
</div>

<?php /* Modal content */ ?>
<div class="overflow-y-auto flex-1">
<div class="flex flex-col md:h-full">
<div x-show="mainStep === 1 || mainStep === 2 || mainStep === 5 || mainStep === 6"
class="flex-1 flex flex-col md:flex-row md:justify-between px-7 pb-7.5 pt-12 md:p-7.5 md:pt-8"
:class="{
'bg-maintain-success-step': mainStep === 6
}"
>
<div class="md:max-w-[326px]">
<div x-show="mainStep === 1">
<?php include renderTemplate('side-panels/maintain/maintain-steps/maintain-steps-summary', 'complete'); ?>
</div>
<div x-cloak x-show="mainStep === 2 && subStep === 1">
<?php include renderTemplate('side-panels/maintain/maintain-steps/maintain-steps-summary', 'select'); ?>
</div>
<div x-cloak x-show="mainStep === 2 && subStep === 2">
<div class="maintain-summary">
<div class="text-lg md:text-2xl tracking-tightened font-semibold leading-[1.2]"><span x-text="currentIntervention.type_label"></span>, parfait, précisez le type de service </div>
<ul class="hidden md:block pt-7.5 font-medium tracking-tightened">
<li class="flex gap-2.5"><?= icon('label-check-colored', 'w-5.5'); ?> Rendez-vous en ligne</li>
<li class="flex gap-2.5 mt-2.5"><?= icon('label-check-colored', 'w-5.5'); ?> 65 concessions près de vous, N marques</li>
<li class="flex gap-2.5 mt-2.5"><?= icon('label-check-colored', 'w-5.5'); ?> Lorem ipsum dolor</li>
</ul>
</div>
</div>
<div x-cloak x-show="(mainStep === 2 && subStep === 3) || (mainStep === 5 && subStep === 1)">
<div class="maa-summary">
<div class="md:max-w-[326px] text-lg md:text-2xl tracking-tightened font-semibold leading-[1.2] flex items-start gap-4"><?= icon('label-check-colored', 'w-7 mt-1.5'); ?> Vous avez ajouté une intervention</div>
<div class="md:max-w-[326px] mt-5.5 bg-white rounded-button border border-ui flex flex-col items-start p-5 md:p-7.5">
<div class="font-semibold tracking-tightened text-[17px]"><span x-text="vehicle.brand"></span> <span x-text="vehicle.model"></span></div>
<div class="text-text-light font-medium"><span x-text="vehicle.energy"></span></div>
<hr class="border-t-0 border-b border-ui-border mt-3.75 mb-5.5 w-full">
<div class="flex flex-col gap-2.5">
<template x-for="(intervention, index) in interventions">
<div class="bg-ui-light rounded-button pl-3 py-3.75 w-full flex">
<div class="flex-1">
<div class="font-medium text-text-light tracking-tightened flex flex-wrap gap-1.25"><span x-html="intervention.type_icon"></span> Service&nbsp;: <span class="font-bold text-text" x-text="intervention.type_label"></span></div>
<div class="tracking-tightened font-bold text-text mt-1.75" x-text="intervention.intervention_label"></div>
</div>
<div>
<button class="px-3 py-1" @click="removeIntervention(index)"><?= icon('label-suppress-colored', 'w-3.75'); ?></button>
</div>
</div>
</template>
</div>
</div>
</div>
</div>
<div x-cloak x-show="mainStep === 6 && subStep === 1">
<div class="text-white">
<div class="flex md:flex-col gap-5">
<div class="shrink-0 pt-0.5"><?= icon('label-check-success-colored', 'w-[60px]'); ?></div>
<div class="tracking-tightened text-lg leading-[1.2]">
<div class="md:text-2xl font-semibold">C’est enregistré !</div>
<div class="font-medium mt-2.5 md:mt-2.5">Votre rendez-vous a bien été pris en compte</div>
</div>
</div>

<p class="mt-7.5 md:mt-5">
Vous pouvez retrouver toutes les informations de votre véhicule et vos interventions dans votre garage en ligne
</p>

<a href="#" class="btn btn-primary mt-5 btn-full-mobile">Voir mon garage en ligne</a>
</div>
</div>
</div>

<?php /* Colonne droite */ ?>
<div class="pt-6 md:pt-0 flex-1">
<div class="md:max-w-[415px] md:ml-auto" x-show="(mainStep !== 5)">
<div class="bg-white border border-ui rounded-button p-7.5">
<?php /* Main Step 1 - Sub Step 1 */ ?>
<div x-show="mainStep === 1 && subStep === 1">
<p class="tracking-tightened font-medium text-base text-text-light">Indiquez votre plaque d’immatriculation ou retrouvez votre voiture par modèle 👇</p>
<div class="mt-6">
<div class="form-element form-box-radio-slider form-box-radio-slider--full-double"
x-data="boxCheckboxSlider()">
<div x-ref="controler" class="controler"></div>
<div class="label-wrapper" x-ref="wrapper">
<label for="immatriculation">
<input @click="changeInput(); $parent.tab = 'immatriculation'; hasErrors = {}" type="radio" value="immatriculation" name="choice_type" id="immatriculation" checked>
<span>Par immatriculation</span>
</label>
<label for="model">
<input @click="changeInput(); $parent.tab = 'model'; hasErrors = {}" type="radio" value="model" name="choice_type" id="model">
<span>Par modèle</span>
</label>
</div>
</div>

<div x-show="tab === 'immatriculation'" class="mt-5" x-ref="immatriculation">
<div class="form-element form-license-plate">
<label for="license-plate">
<span class="form-license-plate__decorative">
<?= icon('european-stars-colored', 'w-5.5'); ?>
<span>F</span>
</span>
<input class="w-full" type="text" id="license-plate" name="license-plate" placeholder="ex BB 466 ZZ...">
<span class="form-license-plate__decorative">
<?= icon('flower', 'w-5.5'); ?>
<span>00</span>
</span>
</label>
</div>

<div x-cloak x-show="hasErrors.licence_plate" class="font-medium tracking-tightened text-error pt-5">
Ce numéro d’immatriculation n'a pas été reconnu. Merci de vous munir de votre carte grise ou d’identifier votre véhicule en sélectionnant sa marque, son modèle, sa date de mise en circulation
</div>
</div>

<div x-cloak x-show="tab === 'model'" class="mt-5" x-ref="model">
<div class="form-element form-select w-full"
x-data="selectInput"
:class="{ 'active' : active }"
@click.away="active = false"
>
<input x-ref="input" name="brand" class="" id="brand" type="text" pattern="\S+" x-model="currentValue">
<div x-ref="display" @click="active = !active" class="form-input select" x-text="currentLabel"></div>
<label @click="active = !active" :class="{ 'moved' : full }" for="brand">Marque</label>
<ul x-ref="options" class="select-options" x-show="active">
<li><button type="button" @click="setValue('peugeot', 'Peugeot')">Peugeot</button></li>
<li><button type="button" @click="setValue('renault', 'Renault')">Renault</button></li>
<li><button type="button" @click="setValue('audi', 'Audi')">Audi</button></li>
<li><button type="button" @click="setValue('citroen', 'Citroën')">Citroën</button></li>
<li><button type="button" @click="setValue('kia', 'Kia')">Kia</button></li>
<li><button type="button" @click="setValue('alfa-romeo', 'Alfa Romeo')">Alfa</button></li>
</ul>
</div>
<div x-cloak x-show="hasErrors.brand" class="font-medium tracking-tightened text-error pt-1.25">Ce champs est requis</div>

<div class="flex gap-2.5 mt-2.5">
<div class="w-1/2">
<div class="form-element form-select min-w-0 w-full"
x-data="selectInput"
:class="{ 'active' : active }"
@click.away="active = false"
>
<input x-ref="input" name="model" class="" id="choice_model" type="text" pattern="\S+" x-model="currentValue">
<div x-ref="display" @click="active = !active" class="form-input select" x-text="currentLabel"></div>
<label @click="active = !active" :class="{ 'moved' : full }" for="choice_model">Modèle</label>
<ul x-ref="options" class="select-options" x-show="active">
<li><button type="button" @click="setValue('3008', '3008')">3008</button></li>
<li><button type="button" @click="setValue('208', '208')">208</button></li>
<li><button type="button" @click="setValue('308', '308')">308</button></li>
<li><button type="button" @click="setValue('408', '408')">408</button></li>
</div>
<div x-cloak x-show="hasErrors.choice_model" class="font-medium tracking-tightened text-error pt-1.25">Ce champs est requis</div>
</div>
<div class="w-1/2">
<div class="form-element form-select min-w-0 w-full"
x-data="selectInput"
:class="{ 'active' : active }"
@click.away="active = false"
>
<input x-ref="input" name="year" class="" id="year" type="text" pattern="\S+" x-model="currentValue">
<div x-ref="display" @click="active = !active" class="form-input select" x-text="currentLabel"></div>
<label @click="active = !active" :class="{ 'moved' : full }" for="year">Année</label>
<ul x-ref="options" class="select-options" x-show="active">
<li><button type="button" @click="setValue('2022', '2022')">2022</button></li>
<li><button type="button" @click="setValue('2021', '2021')">2021</button></li>
<li><button type="button" @click="setValue('2020', '2020')">2020</button></li>
<li><button type="button" @click="setValue('2019', '2019')">2019</button></li>
<li><button type="button" @click="setValue('2018', '2018')">2018</button></li>
<li><button type="button" @click="setValue('2017', '2017')">2017</button></li>
<li><button type="button" @click="setValue('2018', '2016')">2016</button></li>
<li><button type="button" @click="setValue('2017', '2015')">2015</button></li>
<li><button type="button" @click="setValue('2016', '2014')">2014</button></li>
<li><button type="button" @click="setValue('2015', '2013')">2013</button></li>
</ul>
</div>
<div x-cloak x-show="hasErrors.year" class="font-medium tracking-tightened text-error pt-1.25">Ce champs est requis</div>
</div>
</div>
</div>
</div>
</div>

<?php /* Main Step 1 - Sub Step 2 */ ?>
<div x-cloak x-show="mainStep === 1 && subStep === 2">
<p class="tracking-tightened font-medium text-base text-text-light">Validez votre véhicule</p>
<div class="mt-6 bg-ui-light px-5 py-6.25 flex gap-4.5">
<div class="shrink-0"><?= icon('label-check-colored', 'w-8.75'); ?></div>
<div class="text-smaller tracking-tight">
<div class="font-semibold"><span x-text="vehicle.brand"></span> <span x-text="vehicle.model"></span></div>
<div class="mt-3 font-medium">
<p x-text="vehicle.energy" x-show="vehicle.energy" x-cloak>Essence</p>
<p x-text="vehicle.power" x-show="vehicle.power" x-cloak>400 CV (294 KW)</p>
<p x-text="vehicle.year" x-show="vehicle.year" x-cloak>04/2017 à 10/2020</p>
<p x-text="vehicle.volume" x-show="vehicle.volume" x-cloak>2480 cm3</p>
</div>
</div>
</div>
<div class="mt-5 flex gap-4.5">
<button class="btn btn-secondary-grey p-2.75 flex-1" @click="setStep(1,1,false)">
<span class="hidden md:inline">Nouvelle recherche</span>
<span class="md:hidden">Revenir</span>
</button>
<button class="btn btn-primary p-2.75 flex-1" @click="setStep(2,1,false)">
<span class="hidden md:inline">Valider ce véhicule</span>
<span class="md:hidden">Valider</span>
</button>
</div>
</div>

<?php /* Main Step 2 - Sub Step 1 */ ?>
<div x-cloak x-show="mainStep === 2 && subStep === 1">
<p class="tracking-tightened font-medium text-base text-text-light">Choisissez un type d’intervention</p>
<div x-cloak x-show="hasErrors.missing_intervention_type" class="font-medium tracking-tightened text-error pt-1.25">Veuillez choisir un type d'intervention</div>
<div class="mt-6 flex flex-col gap-4.5">
<div class="form-element form-checkbox-button w-full">
<label for="type_entretien_courant">
<input type="radio" id="type_entretien_courant" value="entretien-courant" name="type_intervention">
<span class="controller">
<span><?= icon('oil', 'w-7.5 text-icon'); ?></span>
<span>Entretien courant</span>
</span>
</label>
</div>
<div class="form-element form-checkbox-button w-full">
<label for="type_diagnostic">
<input type="radio" id="type_diagnostic" value="diagnostic" name="type_intervention">
<span class="controller">
<?= icon('diagnostic', 'w-7.5 text-icon'); ?>
<span>Diagnostic</span>
</span>
</label>
</div>
<div class="form-element form-checkbox-button w-full">
<label for="type_climatisation">
<input type="radio" id="type_climatisation" value="climatisation" name="type_intervention">
<span class="controller">
<?= icon('ice-cone', 'w-7.5 text-icon'); ?>
<span>Climatisation</span>
</span>
</label>
</div>
<div class="form-element form-checkbox-button w-full">
<label for="type_pneumatique_suspension">
<input type="radio" id="type_pneumatique_suspension" value="pneumatique-suspensions" name="type_intervention">
<span class="controller">
<?= icon('suspensions-2', 'w-7.5 text-icon'); ?>
<span>Pneumatique / Suspension</span>
</span>
</label>
</div>
<div class="form-element form-checkbox-button w-full">
<label for="type_freins">
<input type="radio" id="type_freins" value="freins" name="type_intervention">
<span class="controller">
<?= icon('freins', 'w-7.5 text-icon'); ?>
<span>Freinage</span>
</span>
</label>
</div>
<div class="form-element form-checkbox-button w-full">
<label for="type_direction_transmission_boite_moteur">
<input type="radio" id="type_direction_transmission_boite_moteur" value="direction-transmission-boite-moteur" name="type_intervention">
<span class="controller">
<?= icon('strap', 'w-7.5 text-icon'); ?>
<span>Direction - Transmission - Boîte - Moteur</span>
</span>
</label>
</div>
<div class="form-element form-checkbox-button w-full">
<label for="type_visibilite">
<input type="radio" id="type_visibilite" value="visibilite" name="type_intervention">
<span class="controller">
<?= icon('beam', 'w-7.5 text-icon'); ?>
<span>Visibilité</span>
</span>
</label>
</div>
<div class="form-element form-checkbox-button w-full">
<label for="type_carrosserie">
<input type="radio" id="type_carrosserie" value="carrosserie" name="type_intervention">
<span class="controller">
<?= icon('bodywork', 'w-7.5 text-icon'); ?>
<span>Carrosserie</span>
</span>
</label>
</div>
<div class="form-element form-checkbox-button w-full">
<label for="type_moteur">
<input type="radio" id="type_moteur" value="moteur" name="type_intervention"">
<span class="controller">
<?= icon('engine', 'w-7.5 text-icon'); ?>
<span>Moteur</span>
</span>
</label>
</div>
<div class="form-element form-checkbox-button w-full">
<label for="type_divers">
<input type="radio" id="type_divers" value="divers" name="type_intervention">
<span class="controller">
<?= icon('diagnostic', 'w-7.5 text-icon'); ?>
<span>Divers</span>
</span>
</label>
</div>
</div>
</div>

<?php /* Main Step 2 - Sub Step 2 */ ?>
<div x-cloak x-show="mainStep === 2 && subStep === 2">
<p class="tracking-tightened font-medium text-base text-text-light">⚙️ Choisissez votre intervention</p>
<div x-cloak x-show="hasErrors.missing_intervention" class="font-medium tracking-tightened text-error pt-1.25">Veuillez choisir une intervention</div>
<div class="mt-6 flex flex-col gap-4.5">
<div class="form-element form-select w-full"
x-data="selectInput"
:class="{ 'active' : active }"
@click.away="active = false"
>
<input x-ref="input" class="" id="intervention_select" type="text" pattern="\S+" x-model="currentValue">
<div x-ref="display" @click="active = !active" class="form-input select" x-text="currentLabel"></div>
<label @click="active = !active" :class="{ 'moved' : full }" for="intervention_select">Choisir une intervention</label>
<ul x-ref="options" class="select-options" x-show="active">
<li><button type="button" @click="setValue('recharge-climatisation', 'Recharge climatisation'); $parent.showIntervention('climatisation-recharge-climatisation')">Recharge climatisation</button></li>
<li><button type="button" @click="setValue('nettoyage-climatisation', 'Nettoyage climatisation'); $parent.showIntervention('climatisation-nettoyage-climatisation')">Nettoyage climatisation</button></li>
<li><button type="button" @click="setValue('reparation-climatisation', 'Réparation climatisation'); $parent.showIntervention('climatisation-reparation-climatisation')">Réparation climatisation</button></li>
</ul>
</div>

<div data-intervention="climatisation-recharge-climatisation" class="hidden pt-2.5">
<div class="bg-ui-light px-5 py-6.25 flex gap-4.5">
<div class="shrink-0"><?= icon('ice-cone', 'w-7.5 text-icon'); ?></div>
<div class="text-smaller tracking-tight">
<div class="font-semibold">Recharge climatisation</div>
<div class="mt-1.25 font-medium text-text-light">
<p>Durée d’intervention : <span class="text-secondary">3h</span></p>
<p>Budget prévisionnel : <span class="text-secondary">250 €</span></p>
</div>
</div>
</div>

<div class="mt-6.25">
<div x-data="dropdown()" class="border border-ui rounded-button">
<div @click="toggle()"
class="flex justify-between font-semibold tracking-tight leading-[1.2] py-6 px-5 md:px-6.25 cursor-pointer gap-7.5 md:gap-13">
<div>Pourquoi changer votre pare-brise&nbsp;?</div>
<div>
<span x-show="!open"><?= icon('plus', 'w-5 text-text') ?></span>
<span x-show="open" x-cloak><?= icon('minus', 'w-5 text-text') ?></span>
</div>
</div>
<div class="overflow-hidden">
<div x-ref="content" class="hidden dropdown-content">
<div class="px-5 md:px-6.25 pb-5">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras vitae eros sit amet leo lobortis cursus...
</div>
</div>
</div>
</div>
<div x-data="dropdown()" class="border border-ui rounded-button mt-2.75">
<div @click="toggle()"
class="flex justify-between font-semibold tracking-tight leading-[1.2] py-6 px-5 md:px-6.25 cursor-pointer gap-7.5 md:gap-13">
<div>Comment se déroule l’intervention</div>
<div>
<span x-show="!open"><?= icon('plus', 'w-5 text-text') ?></span>
<span x-show="open" x-cloak><?= icon('minus', 'w-5 text-text') ?></span>
</div>
</div>
<div class="overflow-hidden">
<div x-ref="content" class="hidden dropdown-content">
<div class="px-5 md:px-6.25 pb-5">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras vitae eros sit amet leo lobortis cursus...
</div>
</div>
</div>
</div>

<div class="mt-6.25">
<div class="rounded-button bg-background relative h-[225px]">
<div class="absolute inset-center"><?= icon('youtube-play', 'w-13'); ?></div>
</div>
<div class="px-5 pt-2.5 tracking-tightened font-medium leading-[1.2]">
<p class="text-text-light">Comment réalise-t-on un changement de pare-brise ?</p>
<p class="text-icon text-sm">2 min - 2500 vues</p>
</div>
</div>
</div>
</div>
<div data-intervention="climatisation-filtre-a-air" class="hidden pt-2.5">Filtre à air</div>
</div>
</div>

<?php /* Main Step 2 - Sub Step 3 */ ?>
<div x-cloak x-show="mainStep === 2 && subStep === 3">
<div class="md:max-w-[415px]" >
<div class="bg-white border border-ui rounded-button p-7.5">
<p class="tracking-tightened font-medium text-base text-text-light">Que souhaitez-vous faire ?</p>
<div class="mt-5 flex flex-col gap-4.5">
<button class="btn btn-secondary-grey p-2.75 flex-1" @click="setStep(2,1,false)">Ajouter une autre intervention</button>
<button class="btn btn-primary p-2.75 flex-1" @click="nextStep()">Continuer</button>
</div>
<p class="mt-8.5 tracking-tightened font-medium text-text-light">Vous pouvez ajouter n autres interventions sur le même créneau de rendez-vous</p>
</div>
</div>
</div>

<?php /* Main Step 5 - Sub Step 2 */ ?>
<div x-cloak x-show="mainStep === 5 && subStep === 2">
<div class="flex flex-col space-y-2.5">
<div class="flex flex-col md:flex-row gap-2.5">
<div class="form-element form-select md:w-1/2 md:min-w-0"
x-data="selectInput('m', 'M.')"
:class="{ 'active' : active }"
@click.away="active = false"
>
<input x-ref="input"
name="civility"
class=""
id="civility"
type="text"
pattern="\S+"
x-model="currentValue"
>
<div x-ref="display" @click="active = !active" class="form-input select" x-text="currentLabel"></div>
<label @click="active = !active" class="moved" :class="{ 'moved' : full }" for="civility">Civilité</label>
<ul x-ref="options" class="select-options" x-show="active">
<li><button type="button" value="m">M.</button></li>
<li><button type="button" value="mme" ">Mme</button></li>
</ul>
</div>
<span class="w-1/2"></span>
</div>
<div class="flex flex-col md:flex-row gap-2.5">
<div class="form-element text md:w-1/2" :class="hasErrors.firstname_required && 'error'">
<input name="firstname"
class="form-input w-full"
id="firstname"
type="text"
title="Prénom"
placeholder=" " pattern="\S+" required
x-model="user.firstname"
>
<label class="label" for="firstname">
<span>Prénom</span>
</label>
<div class="error-message" :class="hasErrors.firstname_required && 'flex'"><?= icon('label-error-colored'); ?><span>Ce champ est obligatoire.</span></div>
</div>
<div class="form-element text md:w-1/2" :class="hasErrors.lastname_required && 'error'">
<input name="lastname"
class="form-input w-full"
id="lastname"
type="text"
title="Nom"
placeholder=" " pattern="\S+" required
x-model="user.lastname"
>
<label class="label" for="lastname">
<span>Nom</span>
</label>
<div class="error-message" :class="hasErrors.lastname_required && 'flex'"><?= icon('label-error-colored'); ?><span>Ce champ est obligatoire.</span></div>
</div>
</div>
<div class="form-element text w-full" :class="hasErrors.phone_required && 'error'">
<input name="phone"
class="form-input w-full"
id="phone"
type="text"
title="Téléphone"
placeholder=" " pattern="\S+" required
x-model="user.phone"
>
<label class="label" for="phone">
<span>Votre téléphone mobile</span>
</label>
<div class="error-message" :class="hasErrors.phone_required && 'flex'"><?= icon('label-error-colored'); ?><span>Ce champ est obligatoire.</span></div>
</div>
<div class="form-element text w-full" :class="hasErrors.street_required && 'error'">
<input name="address"
class="form-input w-full"
id="street" type="text"
title="Adresse"
placeholder=" " pattern="\S+" required
x-model="user.street"
>
<label class="label" for="street">
<span>Votre adresse</span>
</label>
<div class="error-message" :class="hasErrors.street_required && 'flex'"><?= icon('label-error-colored'); ?><span>Ce champ est obligatoire.</span></div>
</div>
<div class="flex flex-col md:flex-row gap-2.5">
<div class="form-element text md:w-1/3" :class="hasErrors.postal_code_required && 'error'">
<input name="postal_code"
class="form-input w-full"
id="postal_code"
type="text"
title="Code postal"
placeholder=" " pattern="\S+" required
x-model="user.postal_code"
>
<label class="label" for="postal_code">
<span>Code postal</span>
</label>
<div class="error-message" :class="hasErrors.postal_code_required && 'flex'"><?= icon('label-error-colored'); ?><span>Ce champ est obligatoire.</span></div>
</div>
<div class="form-element text md:w-2/3" :class="hasErrors.city_required && 'error'">
<input name="city"
class="form-input w-full"
id="city" type="text"
title="Ville"
placeholder=" " pattern="\S+" required
x-model="user.city"
>
<label class="label" for="city">
<span>Ville</span>
</label>
<div class="error-message" :class="hasErrors.city_required && 'flex'"><?= icon('label-error-colored'); ?><span>Ce champ est obligatoire.</span></div>
</div>
</div>
<div class="form-element form-select w-full min-w-0"
x-data="selectInput('no', 'Pas de préférences')"
:class="{ 'active' : active }"
@click.away="active = false"
>
<input x-ref="input"
name="concession"
class="" id="concession"
type="text" pattern="\S+"
x-model="currentValue"
>
<div x-ref="display" @click="active = !active" class="form-input select" x-text="currentLabel"></div>
<label @click="active = !active" class="moved" :class="{ 'moved' : full }" for="concession">Concession</label>
<ul x-ref="options" class="select-options" x-show="active">
<li><button type="button" value="toulouse">Toulouse</button></li>
<li><button type="button" value="narbonne">Narbonne</button></li>
<li><button type="button" value="bordeaux">Bordeaux</button></li>
<li><button type="button" value="no">Pas de préférences</button></li>
</ul>
</div>
<div class="form-element form-select w-full min-w-0"
x-data="selectInput('particulier', 'Particulier')"
:class="{ 'active' : active }"
@click.away="active = false"
>
<input x-ref="input"
name="status"
class="" id="status"
type="text" pattern="\S+"
x-model="currentValue"
>
<div x-ref="display" @click="active = !active" class="form-input select" x-text="currentLabel"></div>
<label @click="active = !active" class="moved" :class="{ 'moved' : full }" for="status">Vous êtes</label>
<ul x-ref="options" class="select-options" x-show="active">
<li><button type="button" value="administrateur-de-compte">Administrateur de compte</button></li>
<li><button type="button" value="particulier">Particulier</button></li>
</ul>
</div>
</div>

<div x-cloak x-show="Object.keys(hasErrors).length > 0" class="rounded-button border-2 flex gap-2.5 py-2.5 px-4.25 border-error bg-error-light mb-2.5">
<?= icon('label-suppress-colored'); ?>
<span>Il y a <span x-text="Object.keys(hasErrors).length"></span> erreur<span x-show="Object.keys(hasErrors).length > 1">s</span> dans le formulaire</span>
</div>
</div>

<?php /* Main Step 6 - Sub Step 1 */ ?>
<div x-cloak x-show="mainStep === 6 && subStep === 1">
<div class="flex flex-col gap-2.5">
<div class="flex gap-4 bg-ui-light py-5 px-4 rounded-tl-button rounded-tr-button">
<div class="shrink-0 bg-white w-11.5 h-11.5 flex justify-center items-center rounded-full">
<?= icon('calendar', 'w-6.25 text-icon'); ?>
</div>
<div class="leading-[1.2]">
<div class="text-sm text-icon">Votre prochain rendez-vous</div>
<div class="text-xl font-bold">
<span class="capitalize" x-text="timeslot.daystr"></span> <span x-text="timeslot.day"></span> <span x-text="timeslot.monthstr"></span> <span x-text="timeslot.year"></span>
</div>
<div class="text-xl font-medium">à <span x-text="timeslot.hour"></span></div>
</div>
</div>

<template x-for="intervention in interventions">
<div class="flex gap-4 bg-ui-light py-5 px-4 last:rounded-bl-button last:rounded-br-button">
<div class="shrink-0 bg-white w-11.5 h-11.5 flex justify-center items-center rounded-full">
<span x-html="intervention.type_icon"></span>
</div>
<div class="leading-[1.2] text-text-light tracking-tight">
<div class="text-lg font-bold"><span x-text="intervention.intervention_label"></span></div>
<div class="text-smaller font-medium">Durée d’intervention : <span class="text-secondary">3h</span></div>
</div>
</div>
</template>
</div>

<div class="mt-6.25 leading-[1.2]">
<div x-text="concessionSelected.name" class="tracking-tightened text-lg font-bold text-text-light mb-3.75"></div>
<div class="flex gap-3 items-start text-sm md:text-smaller text-text-light">
<?= icon('pinpoint', 'w-4 text-primary-accent mt-1 shrink-0'); ?>
<span x-text="concessionSelected.adresse"></span>
</div>
<div class="flex gap-3 items-start text-sm md:text-smaller text-text-light mt-2.5">
<?= icon('phone', 'w-4 text-primary-accent mt-1 shrink-0'); ?>
<div>
<a class="link block font-semibold" x-text="concessionSelected.telephone" :href="telHrefFormatting(concessionSelected.telephone)"></a>
<a class="link block" x-text="concessionSelected.email" :href="mailHrefFormatting(concessionSelected.email)"></a>
</div>
</div>
</div>

</div>
</div>
</div>


<?php /* Main Step 5 - Sub Step 1 */ ?>
<div x-cloak x-show="mainStep === 5 && subStep === 1">
<?php include renderTemplate('side-panels/global-steps/login-form'); ?>
</div>
</div>
</div>

<?php /* Step map */ ?>
<div x-show="mainStep === 3" x-cloak class="h-full">
<?php include renderTemplate('side-panels/global-steps/concession-selection-map'); ?>
</div>

<?php /* Step timeslot */ ?>
<div x-show="mainStep === 4" x-cloak class="h-full">
<?php include renderTemplate('side-panels/global-steps/timeslots'); ?>
</div>

<?php include renderTemplate('side-panels/maintain/maintain-footer'); ?>
</div>
</div>

<?php /* Modal buttons footer */ ?>
<div
class="maintain-modal__buttons border-t border-ui bg-white pt-5 px-7 pb-8.5 md:py-6.25 md:px-7.5 flex justify-between gap-3.75 shadow-filter-footer md:shadow-none"
x-show="!endMainStep"
>
<button class="btn btn-secondary-grey py-2.75 md:px-10 flex-1 md:flex-none" @click="prevStep()">
<span>Précédent</span>
</button>
<button class="btn btn-primary py-2.75 md:px-13 flex-1 md:flex-none"
@click="nextStep()"
:class="{
'pointer-events-none opacity-60': !canNext
}"
>
<span>Suivant</span>
</button>
</div>
</div>
</div>
</div>

<script>
function initMaintainFormModal() {
return {
modalOpen: false,
isOpen: false,
init() {
const current = this;
document.addEventListener('openMaintainModal', function (e) {
current.open();
});
document.addEventListener('closeMaintainModal', function (e) {
current.close();
});
},
open() {
document.body.classList.add('overflow-hidden');
this.modalOpen = true;
this.$nextTick(() => {
this.isOpen = true;
})
},
close() {
const current = this;
document.body.classList.remove('overflow-hidden');
this.isOpen = false;
setTimeout(function () {
current.modalOpen = false;
}, 350)
}
}
}

const immatFakeDatas = {
brand: 'Audi',
model: 'A3 limousine',
energy: 'Essence',
power: '400CV (294KW)',
year: '04/2017 à 10/2020',
volume: '2480 cm3'
};

function initMaintainForm(userConnected = false) {
return {
mainStep: 1,
subStep: 1,
endMainStep: false,
licencePlate: '',
vehicle: [],
interventions: [],
currentIntervention: [],
user: [],
tab: 'immatriculation',
hasErrors: {},
userConnected: userConnected,
canNext: true,
timeslot: [],
concessionSelected: [],
init() {

if(this.userConnected) {
this.mainStep = 2;
this.subStep = 1
}

new Cleave('#license-plate', {
delimiters: ['-'],
blocks: [2,3,2],
uppercase: true
});

let current = this;
/* Detect set concession */
document.addEventListener('set-concession-by-map', function (e) {
current.concessionSelected = e.detail;
current.concessionId = e.detail.id;
current.canNext = true;
});

/* Detect set timeslot */
document.addEventListener('set-time-slot', function (e) {
current.timeslot = e.detail;

current.canNext = true;
})
this.$nextTick(() => {
this.$dispatch('timeslot-resize');
})

/* Detect login */
document.addEventListener('set-datas-user-panel', function (e) {
current.nextStep();
})
},
nextStep() {
if(this.mainStep === 1) {
if(this.subStep === 1) {
this.checkChoice();
}
}
else if(this.mainStep === 2) {
if(this.subStep === 3) {
this.setStep(3,1,false);
this.canNext = false;
}

if(this.subStep === 2) {
this.selectIntervention();
}

if(this.subStep === 1) {
this.setInterventionType();
}
}
else if(this.mainStep === 3) {
if(this.concessionId !== undefined) {
delete this.hasErrors['missing_concession'];
this.setStep(4,1,false);
this.canNext = false;
this.$dispatch('timeslot-resize');
} else {
this.hasErrors.missing_concession = true;
return false;
}
}
else if(this.mainStep === 4) {
if(this.timeslot !== undefined) {
this.setStep(5,1,false);
this.canNext = false;
} else {
this.hasErrors.missing_timeslot = true;
return false;
}
}
else if(this.mainStep === 5) {
this.setStep(6,1,true)
}
},
prevStep() {
if(this.mainStep === 1) {
if(this.subStep === 2) {
this.setStep(1,1,false);
return false;
}
}
else if(this.mainStep === 2) {
if(this.subStep === 1) {
this.setStep(1,2,true);
return false;
}
if(this.subStep === 2) {
this.setStep(2,1,false);
return false;
}
}
else if(this.mainStep === 3) {
this.setStep(2,3, true)
}
else if(this.mainStep === 4) {
this.setStep(3,1, false);
this.canNext = true;
}
else if(this.mainStep === 5) {
this.setStep(4,1, false);
this.canNext = true;
}
},
setStep(main, sub, isEndMain) {
this.mainStep = main;
this.subStep = sub;
this.endMainStep = isEndMain;
},
checkChoice() {
this.hasErrors = {};
let isValid = true;
/* By immatriculation */
if(this.tab === 'immatriculation') {
const input = document.getElementById('license-plate');
if(input.value === '') {
this.hasErrors.licence_plate = true;
return false;
}
if(!input.value.match('^[A-Z]{2}-[0-9]{3}-[A-Z]{2}')) {
this.hasErrors.licence_plate = true;
return false;
}

/* Ajax récup info - fake datas */
this.vehicle = immatFakeDatas;
}
/* By model */
else {
isValid = this.checkError('brand', 'required');
isValid = this.checkError('choice_model', 'required');
isValid = this.checkError('year', 'required');

if(!isValid) {
return false;
} else {
this.setData('brand', 'brand', 'select');
this.setData('model', 'choice_model', 'select');
this.setData('year', 'year');
}
}

this.setStep(1,2,true);
return true;
},
setInterventionType() {
let input = document.querySelector('input[name="type_intervention"]:checked');
if(input) {
delete this.hasErrors['missing_intervention_type'];
let icon = input.nextElementSibling.querySelector('.icon').outerHTML;
icon = icon.replace('w-7.5', 'text-icon mr-1 w-auto h-5')
this.currentIntervention['type'] = input.value;
this.currentIntervention['type_icon'] = icon;
this.currentIntervention['type_label'] = input.nextElementSibling.querySelector('span').innerText;

/* ICI AJAX POUR REMPLIR 'intervention_select' en fonction des interventions rattachées. */

this.setStep(2,2,false);
} else {
this.hasErrors.missing_intervention_type = true;
return false;
}
},
showIntervention(id) {
const interventions = document.querySelectorAll('[data-intervention]');
Object.entries(interventions).forEach(([index, intervention]) => {
if(intervention.dataset.intervention === id) {
intervention.classList.remove('hidden');
} else {
intervention.classList.add('hidden');
}
})
},
addIntervention() {
let current = this.currentIntervention;
let currentDatas = [];
Object.keys(this.currentIntervention).map(function (key) {
currentDatas[key] = current[key]
});
this.interventions.push(current);
this.currentIntervention = [];
document.querySelector('input[name="type_intervention"]:checked').checked = false;
this.$dispatch('select-reset-value', {id:'intervention_select'});
return true;
},
removeIntervention(index) {
this.interventions.splice(index,1)
if(this.interventions.length === 0) {
this.setStep(2,1,false)
}
},
selectIntervention() {
if(document.getElementById('intervention_select').value === "") {
this.hasErrors.missing_intervention = true;
return false;
} else {
delete this.hasErrors['missing_intervention'];
this.currentIntervention['intervention'] = document.getElementById('intervention_select').value;
this.currentIntervention['intervention_label'] = document.getElementById('intervention_select').nextElementSibling.innerHTML;

this.addIntervention();
this.setStep(2,3,true);
}
},
checkError(id, error) {
if(error === 'required') {
if(document.getElementById(id).value === '') {
this.hasErrors[id] = true;
return false;
} else {
return true;
}
}
},
setData(data, id, type = 'input') {
if(type === 'select') {
this.vehicle[data] = document.getElementById(id).nextElementSibling.innerText;
} else if(type === 'radio') {
this.vehicle[data] = document.querySelector(id).value;
} else {
this.vehicle[data] = document.getElementById(id).value;
}
},
telHrefFormatting(tel) {
if(tel !== undefined) {
let formatted = tel.replace(/\s/g, '');
formatted = formatted.replace(/^0/, "+33");
return 'tel:' + formatted;
}
return false
},
mailHrefFormatting(mail) {
return 'mailto:' + mail;
}
}
}
</script>