templates/user/profile/profile_step1.html.twig line 1

Open in your IDE?
  1. {% extends 'user/profile/profile_layout.html.twig' %}
  2. {% use "user/profile/section_sidebar.html.twig" with javascript as javascript_sidebar, content as section_sidebar %}
  3. {% from "form/inputs.twig.html" import text_field, date_picker, dropdownlist, radio_group, check_box, textarea, uploader %}
  4. {% if app.user is not empty and 
  5.   constant('App\\Entity\\Role::USER') in app.user.getSubRoleNames() 
  6. %}
  7.   {% set mode = 'EDIT' %}
  8. {% else %}
  9.   {% set mode = 'NEW' %}
  10. {% endif %}
  11. {% block step %}
  12. <form autocomplete="off"
  13.   name="form-apply" id="form-profile-step1" 
  14.   action="{{ path('profile.step1_save') }}"
  15.   method="POST"
  16.   enctype="multipart/form-data"
  17.   class="form-outline {{ validated is defined ? 'was-validated' : ''  }} row"
  18. >
  19. {% if mode == 'EDIT' %}
  20.   <input type='hidden' name='_method' value='PUT'>
  21. {% endif %}
  22. <div class="col-lg-3">
  23.   {{ block('section_sidebar') }}
  24. </div>
  25. <div class="col-lg-9 pl-lg-5">
  26.   <div class="d-flex flex-md-row flex-column mb-4">
  27.     <div class="section-title text-left d-flex align-items-center pt-5 pt-lg-0 mb-0">
  28.       <span class="mr-2">/</span> {% trans %}Vos informations personnelles{% endtrans %}
  29.     </div>
  30.     <div class="ml-auto">
  31.       <span class="required-note text-orange ml-4 mb-0 d-lg-inline d-block text-right">
  32.         <small>{% trans %}Champs obligatoires{% endtrans %} *</small>
  33.       </span>
  34.     </div>
  35.   </div>
  36.   <div class="text-center p-2 p-lg-4 mb-5 bg-light" style="border-radius: 0.9rem;">
  37.     <div class="text-orange text-uppercase font-weight-bold text-center h5 my-3">Accélérez votre inscription grâce à l’autoremplissage intelligent</div>
  38.     Importez votre carte d’identité ou votre passeport (PDF, JPG, PNG).<br>
  39.     Notre système analyse automatiquement le document et préremplit vos informations personnelles.<br>
  40.     <span style="color: #FF0033;font-weight: 500;">Moins de saisie, moins d’erreurs, plus de rapidité.</span>
  41.     <p class="text-purple mt-2">Vos données sont traitées de manière sécurisée et confidentielle.</p>
  42.     <input type="file" id="uploadDocument" name="uploadDocument" class="d-none" accept=".pdf, .jpg, .jpeg, .png">
  43.     <input type="file" name="fileIdentity" class="d-none" disabled>
  44.     <input type="hidden" name="expireIdentity" class="d-none" disabled>
  45.     <label for="uploadDocument"
  46.         class="link-gradient mb-3"
  47.         style="
  48.             display: flex;
  49.             width: 290px;
  50.             margin: 0 auto;
  51.             font-size: 18px;
  52.             font-weight: 500;
  53.             cursor: pointer;
  54.         "
  55.     >
  56.       <i 
  57.           class="fas fa-cloud-arrow-up mr-3 ml-2" 
  58.           style="
  59.               font-size: 16px !important;
  60.               display: flex;
  61.               align-items: center;
  62.           "
  63.       ></i> Importer mon document
  64.     </label>
  65.   </div>
  66.   {{ radio_group(
  67.       'user[gender]', 
  68.       "Vous êtes" | trans, 
  69.       [
  70.         { value: 0, text: "Homme" | trans }, 
  71.         { value: 1, text: "Femme" | trans }, 
  72.       ], 
  73.       formData, 
  74.       { required: true, inline: true }
  75.     ) 
  76.   }}
  77.   <div class="form-row">
  78.     <div class="col-lg-4">
  79.       {{ text_field('user[lastName]', "Nom de famille" | trans, formData, { required: true }) }}
  80.     </div>
  81.     <div class="col-lg-4">
  82.       {{ text_field('user[firstName]', "Prénom" | trans, formData, { required: true }) }}
  83.     </div>
  84.     <div class="col-lg-4">
  85.       {{ date_picker(
  86.           'user[birthDay]', 
  87.           "Date de naissance" | trans, 
  88.           formData, 
  89.           { 
  90.             attributes: { 
  91.               "maxDate": "-14Y", 
  92.               "minDate": "-100Y"
  93.             },
  94.             required: true
  95.           }
  96.         ) 
  97.       }}
  98.     </div>
  99.   </div>
  100.   <div class="form-row">
  101.     <div class="col-lg-4">
  102.       {{ 
  103.         dropdownlist(
  104.           'user[country]', 
  105.           "Pays de naissance" | trans, 
  106.           countries, 
  107.           formData, 
  108.           { valueProperty: 'id', textProperty: 'name' }
  109.         ) 
  110.       }}
  111.     </div>
  112.     <div class="col-lg-4">
  113.       {{ 
  114.         dropdownlist(
  115.           'user[department]', 
  116.           "Département de naissance" | trans, 
  117.           departments, 
  118.           formData,
  119.           { 
  120.             attributes: { 
  121.               disabled: formData.inputValues and 
  122.                 formData.inputValues.user.country and 
  123.                 (
  124.                   formData.inputValues.user.country is object ? 
  125.                     formData.inputValues.user.country.id != 1 : 
  126.                     formData.inputValues.user.country != '1'
  127.                 ) 
  128.               } 
  129.           }
  130.         ) 
  131.       }}
  132.     </div>
  133.     <div class="col-lg-4">
  134.       {{ text_field('user[birthPlace]', "Ville de naissance" | trans, formData) }}
  135.     </div>
  136.   </div>
  137.   <div class="form-row">
  138.     <div class="col-lg-4">
  139.       {{ 
  140.         dropdownlist(
  141.           'user[nationality]', 
  142.           "Nationalité" | trans, 
  143.           countries, 
  144.           formData, 
  145.           { valueProperty: 'id', textProperty: 'nationality' }
  146.         ) 
  147.       }}
  148.     </div>
  149.     <div class="col-lg-4">
  150.       {{ text_field('user[email]', "Email" | trans, formData, { required: true, attributes: { disabled: mode == 'EDIT' } }) }}
  151.     </div>
  152.     <div class="col-lg-4">
  153.       {{ text_field('user[phone]', "Téléphone" | trans, formData, { required: true }) }}
  154.     </div>
  155.   </div>
  156.   <div class="form-row">
  157.     <div class="col-lg-4">
  158.       {{ text_field('information[address]', "Adresse" | trans, formData) }}
  159.     </div>
  160.     <div class="col-lg-4">
  161.       {{ text_field('information[postalCode]', "Code postal" | trans, formData) }}
  162.     </div>
  163.     <div class="col-lg-4">
  164.       {{ text_field('information[city]', "Ville" | trans, formData) }}
  165.     </div>
  166.   </div>
  167.   <div class="form-row">
  168.     <div class="col-lg-4">
  169.       {{ 
  170.         dropdownlist(
  171.           'information[country]', 
  172.           "Pays de résidence" | trans, 
  173.           countries, 
  174.           formData, 
  175.           { valueProperty: 'id', textProperty: 'name' }
  176.         ) 
  177.       }}
  178.     </div>
  179.     <div class="col-lg-4">
  180.       {{ text_field('information[socialSecutiryNumber]', "N° sécurité sociale" | trans, formData) }}
  181.     </div>
  182.   </div>
  183.   <div class="form-row">
  184.     <div class="col">
  185.       {{ check_box(
  186.           'isHandicap', 
  187.           "Êtes-vous en situation de handicap ?" | trans, 
  188.           1, 
  189.           formData, 
  190.           { 
  191.             labelClass: '', 
  192.             wrapperClass: 'mt-1', 
  193.             showIfChecked: textarea('handicapInfo', "Préciser les aménagements nécessaires au bon suivi de votre scolarité" | trans  ~ ' *', formData),
  194.             isBooleanCheck: true,
  195.             mapShowIfChecked: uploader('fileHandicap', "Votre justificatif de handicap éventuel" | trans, formData, { checkSize: true }),
  196.           }
  197.         ) 
  198.       }}
  199.     </div>
  200.   </div>
  201.   <div class="form-row">
  202.     <div class="col">
  203.       <div class="form-group agreefield mb-2 mt-2">
  204.         <div class="custom-control custom-checkbox">
  205.           <input 
  206.             type="checkbox" class="custom-control-input" id="internalRegulations" required 
  207.             {{ validated is defined or mode == 'EDIT' ? 'checked' : ''  }} 
  208.           />
  209.           <label class="custom-control-label text-dark-purple" for="internalRegulations">
  210.               {% trans with {'%link%': '<a class="text-purple" href="' ~ path('reglement_interieur') ~ '">' ~ 'règlement intérieur' | trans ~ '</a>' } %}J'atteste avoir pris connaissance du %link%{% endtrans %}
  211.           </label>
  212.         </div>
  213.       </div>
  214.     </div>
  215.   </div>
  216.   <div class="form-row">
  217.     <div class="col">
  218.       <div class="form-group agreefield">
  219.         <div class="custom-control custom-checkbox">
  220.           <input 
  221.             type="checkbox" class="custom-control-input" id="accept" required 
  222.             {{ validated is defined or mode == 'EDIT' ? 'checked' : ''  }} 
  223.           />
  224.           <label class="custom-control-label text-dark-purple" for="accept">
  225.             <small>
  226.               <b>{% trans %}J'accepte qu' ÉSTIAM utilise mes données personnelles dans le cadre du traitement de ma candidature.{% endtrans %}</b>
  227.               <br/>
  228.               <i>{% trans %}ÉSTIAM s'engage à ne pas communiquer vos données personnelles.
  229.               Conformément à la loi RGPD du 25 Mai 2018 :
  230.               Vous bénéficiez d'un droit d'accès, de rectification, de portabilité, d'effacement de celles-ci ou une limitation du traitement.
  231.               Vous pouvez vous opposer au traitement des données vous concernant et disposez du droit de retirer votre consentement à tout moment.
  232.               Vous avez la possibilité d'introduire une réclamation auprès d'une autorité de contrôle.{% endtrans %}</i>
  233.             </small>
  234.           </label>
  235.         </div>
  236.       </div>
  237.     </div>
  238.   </div>
  239.   <div class="mt-3" data-aos='fade-up'>
  240.     <div class="font-20 text-purple font-weight-bold mb-3"><span class="text-orange mr-1" style="text-shadow: 2px 0px #f50;">/</span> Quel matériel pour étudier ?</div>
  241.     <p>Quelle que soit la classe que vous rejoindrez l’année prochaine, vous aurez besoin d’un ordinateur portable et d’un smartphone avec les caractéristiques minimales suivantes :</p>
  242.     <div class="d-flex align-items-start font-weight-bold mb-2"><span class="pt-1 line-height-small"><i class="fa-solid fa-angles-right text-purple mr-2"></i></span>Caractéristiques minimales de l’ordinateur portable :</div>
  243.     <ul class="list-unstyled mb-3 ml-4">
  244.       <li class="d-flex align-items-start mb-1"><span class="pt-1 line-height-small"><i class="fa-solid fa-check text-success mr-3"></i></span>Processeur Core i7 ou i9 (12ème génération),</li>
  245.       <li class="d-flex align-items-start mb-1"><span class="pt-1 line-height-small"><i class="fa-solid fa-check text-success mr-3"></i></span>RAM 16 Go minimum,</li>
  246.       <li class="d-flex align-items-start mb-1"><span class="pt-1 line-height-small"><i class="fa-solid fa-check text-success mr-3"></i></span>Carte graphique avec 6 Go de mémoire,</li>
  247.       <li class="d-flex align-items-start mb-1"><span class="pt-1 line-height-small"><i class="fa-solid fa-check text-success mr-3"></i></span>Webcam et micro,</li>
  248.       <li class="d-flex align-items-start mb-1"><span class="pt-1 line-height-small"><i class="fa-solid fa-check text-success mr-3"></i></span>Disque dur 1 To minimum,</li>
  249.       <li class="d-flex align-items-start mb-1"><span class="pt-1 line-height-small"><i class="fa-solid fa-check text-success mr-3"></i></span>Pour les ordinateurs Apple, utilisation d’un émulateur Windows 11.</li>
  250.     </ul>
  251.     <div class="d-flex align-items-start font-weight-bold mb-2"><span class="pt-1 line-height-small"><i class="fa-solid fa-angles-right text-purple mr-2"></i></span class="pt-1 line-height-small">Caractéristiques minimales du smartphone personnel de l’étudiant :</div>
  252.     <ul class="list-unstyled mb-3 ml-4">
  253.       <li class="d-flex align-items-start mb-1"><span class="pt-1 line-height-small"><i class="fa-solid fa-check text-success mr-3"></i></span>Téléphone Android 13 minimum (avec appareil photo) ou Apple iPhone avec iOS 15 minimum. Avec possibilité de se connecter à internet.</li>
  254.     </ul>
  255.     <div class="d-flex align-items-start font-weight-bold mb-2"><span class="pt-1 line-height-small"><i class="fa-solid fa-angles-right text-purple mr-2"></i></span>Caractéristiques minimales de la connexion Internet personnelle de l’étudiant (ADSL, Fibre optique ou 4G) :</div>
  256.     <ul class="list-unstyled ml-4">
  257.       <li class="d-flex align-items-start mb-1"><span class="pt-1 line-height-small"><i class="fa-solid fa-check text-success mr-3"></i></span>1 Mbps de débit ascendant</li>
  258.       <li class="d-flex align-items-start mb-1"><span class="pt-1 line-height-small"><i class="fa-solid fa-check text-success mr-3"></i></span>7 Mbps de débit descendant minimum</li>
  259.     </ul>
  260.   </div>
  261.   {% if mode == 'NEW' and captcha_enabled %}
  262.     <div class="captcha-row mb-4 d-flex justify-content-center">
  263.         <div class="g-recaptcha animate__animated" data-sitekey="{{ captcha_key }}"></div>
  264.     </div>
  265.   {% endif %}
  266.   {% if valid_programs is defined %}
  267.     <div class="captcha-row mb-4 d-flex justify-content-center">
  268.       <p class="error text-red font-italic">{{ valid_programs }}</p>
  269.     </div>
  270.   {% endif %}
  271.   <div class="text-center form-submit mt-4">
  272.     <button type="submit" id="btn-submit" class="link-gradient d-block d-lg-inline-block">
  273.       <span>SUIVANT</span><i class="far fa-arrow-right"></i>
  274.     </button>
  275.   </div>
  276.   
  277. </div>
  278. </form>
  279. {% endblock %}
  280. {% block custom_javascripts %}
  281. <script>
  282. function loadButtonAnalyze(element) {
  283.   element.find('i').removeClass('fas fa-cloud-arrow-up');
  284.   element.find('i').addClass('fas fa-spinner fa-pulse ml-1');
  285.   element.prop('disabled', true);
  286. }
  287. function removeLoadButtonAnalyze(element) {
  288.   element.find('i').removeClass('fas fa-spinner fa-pulse ml-1');
  289.   element.find('i').addClass('fas fa-cloud-arrow-up');
  290.   element.prop('disabled', false);
  291. }
  292. $(document).ready(function(){
  293.   {% if mode == 'EDIT' %}
  294.   $([document.documentElement, document.body]).animate({
  295.       scrollTop: $(".section-apply-tabs").offset().top - 60
  296.   }, 400);
  297.   {% else %}
  298.     $('#form-profile-step1').on('submit', function (e) {
  299.         {% if captcha_enabled %}
  300.           if (grecaptcha.getResponse().length == 0) {
  301.               e.preventDefault();
  302.               $('.g-recaptcha').css({"box-shadow": "0px 0px 4px #ff0000b3"});
  303.               $('.preloader').fadeOut();              
  304.               return false;
  305.           }
  306.         {% endif %}
  307.     });
  308.   {% endif %}
  309.   $('[name="isHandicap"]').change(function() {
  310.     if ($(this).prop('checked')) {
  311.       $('[name="handicapInfo"]').prop('required', true)
  312.     } else {
  313.       $('[name="handicapInfo"]').prop('required', false)
  314.     }
  315.   })
  316.   $('[name="user[country]"]').change(function() {
  317.     console.log($(this).val())
  318.     if ($(this).val() === '1') {
  319.       console.log('france checked')
  320.       $('[name="user[department]"]').prop('disabled', false)
  321.     } else {
  322.       console.log('not france')
  323.       $('[name="user[department]"]').prop('disabled', true)
  324.       $('[name="user[department]"]').val('')
  325.       $('[name="user[department]"]').removeClass('active')
  326.     }
  327.   })
  328.   $('#uploadDocument').change(function(e) {
  329.     if (this.files && this.files[0]) {
  330.         const files = this.files;
  331.         var formData = new FormData();
  332.         formData.append('file', files[0], 'image.jpg') ;
  333.         let $button = $(document).find('[for="uploadDocument"]');
  334.         loadButtonAnalyze($button);
  335.         $.ajax({
  336.             url: "{{ path('profile.analyze_file') }}",
  337.             type: "POST",
  338.             dataType: 'json',
  339.             data : formData,
  340.             contentType: false,
  341.             processData: false,
  342.             success: function(result) {
  343.                 const data = result.data[0];
  344.                 if(data.country_id) {
  345.                   //$('[name="user\\[country\\]"]').val(data.country_id).trigger('change');
  346.                   $('[name="user\\[nationality\\]"]').val(data.country_id).trigger('change');
  347.                 }
  348.                 if(data.name) {
  349.                   $('[name="user\\[firstName\\]"]').val(data.name);
  350.                 }
  351.                 if(data.surname) {
  352.                   $('[name="user\\[lastName\\]"]').val(data.surname);
  353.                 }
  354.                 if(data.date_of_birth) {
  355.                   $('[name="user\\[birthDay\\]"]').val(data.date_of_birth);
  356.                 }
  357.                 if(data.place_of_birth) {
  358.                   $('[name="user\\[birthPlace\\]"]').val(data.place_of_birth);
  359.                 }
  360.                 if(data.personal_number) {
  361.                   //$('[name="information\\[socialSecutiryNumber\\]"]').val(data.personal_number);
  362.                 }
  363.                 if(data.gender) {
  364.                   if(data.gender === 'female') {
  365.                     $('[name="user\\[gender\\]"][value="1"]').prop('checked', true);
  366.                   } else {
  367.                     $('[name="user\\[gender\\]"][value="0"]').prop('checked', true);
  368.                   }
  369.                 }
  370.                 if(data.document_expiry) {
  371.                   $('[name="expireIdentity"]').val(data.document_expiry);
  372.                   $('[name="expireIdentity"]').removeAttr('disabled');
  373.                 }
  374.                 $('[name="fileIdentity"]').removeAttr('disabled');
  375.                 $('[name="fileIdentity"]')[0].files = files;
  376.             }
  377.         }).always(function () {
  378.            $('#uploadDocument').val('');
  379.            removeLoadButtonAnalyze($button);
  380.         });
  381.     }
  382.   })
  383. })
  384. </script>
  385.   {{ block('javascript_sidebar') }}
  386. {% endblock %}