templates/sign_up/index.html.twig line 1

Open in your IDE?
  1. {% extends 'base.html.twig' %}
  2. {% block title %}Zatoka Kodu - Rejestracja{% endblock %}
  3. {% block body %}
  4.     <main>
  5.         <section class="min-vh-100 d-flex align-items-center justify-content-center bg-white py-5 px-3">
  6.             <div class="container">
  7.                 <div class="row justify-content-center">
  8.                     <div class="col-md-10 col-lg-8 col-xl-6">
  9.                         <div class="text-center mb-4">
  10.                             <span class="display-4">馃憢</span>
  11.                             <h1 class="h3 fw-bold mt-2">Witamy w Zatoce Kodu</h1>
  12.                             <p class="text-muted">Wype艂nij formularz, aby zapisa膰 swoje dziecko na zaj臋cia</p>
  13.                         </div>
  14.                         <form action="/zapisz_na_kurs" method="post" class="bg-light p-4 p-md-5 rounded-4 shadow-sm" id="client_form">
  15.                             {% set fields = [
  16.                                 {'label': 'Imi臋 dziecka', 'name': 'child_name', 'icon': 'bi-person-circle'},
  17.                                 {'label': 'Nazwisko dziecka', 'name': 'child_surname', 'icon': 'bi-person-circle'},
  18.                                 {'label': 'Imi臋 rodzica', 'name': 'parent_name', 'icon': 'bi-person-circle'},
  19.                                 {'label': 'Nazwisko rodzica', 'name': 'parent_surname', 'icon': 'bi-person-circle'},
  20.                                 {'label': 'Adres email', 'name': 'email', 'type': 'email', 'icon': 'bi-envelope-fill'},
  21.                                 {'label': 'Telefon', 'name': 'phone', 'type': 'tel', 'icon': 'bi-phone-fill'},
  22.                                 {'label': 'Miasto', 'name': 'city', 'icon': 'bi-geo-alt-fill'},
  23.                                 {'label': 'Szko艂a', 'name': 'school', 'icon': 'bi-building'},
  24.                                 {'label': 'Klasa', 'name': 'class', 'icon': 'bi-people-fill'}
  25.                             ] %}
  26.                             {% for field in fields %}
  27.                                 <div class="mb-3">
  28.                                     <label class="form-label">{{ field.label }} *</label>
  29.                                     <div class="input-group">
  30.                                         <span class="input-group-text bg-white border-end-0"><i class="bi {{ field.icon }}"></i></span>
  31.                                         <input type="{{ field.type|default('text') }}" name="{{ field.name }}" class="form-control border-start-0" placeholder="{{ field.label }}" required>
  32.                                     </div>
  33.                                     {% if field.name == 'email' %}
  34.                                         <div id="emailHelp" class="form-text text-danger" style="display:none;">Niepoprawny format adresu e-mail.</div>
  35.                                     {% endif %}
  36.                                     {% if field.name == 'phone' %}
  37.                                         <div id="phoneHelp" class="form-text text-danger" style="display:none;">Niepoprawny format numeru telefonu. Mo偶esz wpisa膰 cyfry i opcjonalnie + na pocz膮tku.</div>
  38.                                     {% endif %}
  39.                                 </div>
  40.                             {% endfor %}
  41.                             <div class="mb-3">
  42.                                 <label class="form-label">Model P艂atno艣ci *</label>
  43.                                 <div class="input-group">
  44.                                     <span class="input-group-text bg-white border-end-0"><i class="bi bi-credit-card-2-front-fill"></i></span>
  45.                                     <select class="form-select border-start-0" name="payment" required>
  46.                                         <option value="" disabled selected>Wybierz model p艂atno艣ci</option>
  47.                                         <option value="miesieczna">Miesi臋czny (8 x 189 z艂) Cena za zaj臋cia: 50 z艂</option>
  48.                                         <option value="kwartalna">Kwartalny (3 x 420 z艂) Cena za zja臋cia: 42 z艂</option>
  49.                                     </select>
  50.                                 </div>
  51.                             </div>
  52.                             <div class="mb-3">
  53.                                 <label class="form-label">Has艂o *</label>
  54.                                 <div class="input-group">
  55.                                     <span class="input-group-text bg-white border-end-0"><i class="bi bi-lock-fill"></i></span>
  56.                                     <input type="password" name="password" id="password" class="form-control border-start-0" placeholder="Has艂o" minlength="6" required>
  57.                                 </div>
  58.                                 <div id="passwordHelpBlock" class="form-text text-danger" style="display:none;">Has艂o musi mie膰 co najmniej 6 znak贸w.</div>
  59.                             </div>
  60.                             <div class="mb-3">
  61.                                 <label class="form-label">Powt贸rz has艂o *</label>
  62.                                 <div class="input-group">
  63.                                     <span class="input-group-text bg-white border-end-0"><i class="bi bi-lock-fill"></i></span>
  64.                                     <input type="password" name="password-repeat" id="password-repeat" class="form-control border-start-0" placeholder="Powt贸rz has艂o" required>
  65.                                 </div>
  66.                                 <div id="passwordHelpBlock2" class="form-text text-danger" style="display:none;">Has艂a nie s膮 takie same.</div>
  67.                             </div>
  68.                             <div class="form-check my-3">
  69.                                 <input class="form-check-input" type="checkbox" name="permission" id="permission" required>
  70.                                 <label class="form-check-label small" for="permission">
  71.                                     Wyra偶am zgod臋 na przetwarzanie moich danych osobowych oraz danych osobowych mojego dziecka: imi臋 i nazwisko dziecka, imi臋 i nazwisko rodzica/opiekuna prawnego, dane kontaktowe (numer telefonu, adres e-mail), przez Programmers sp z o.o. w celu rejestracji dziecka na zaj臋cia oraz przygotowania umowy i realizacji 艣wiadcze艅 wynikaj膮cych z uczestnictwa w zaj臋ciach. Administratorem danych osobowych jest Programmers sp z o.o. Dane te b臋d膮 przetwarzane zgodnie z Rozporz膮dzeniem Parlamentu Europejskiego i Rady (UE) 2016/679 z dnia 27 kwietnia 2016 r. (RODO).
  72.                                 </label>
  73.                             </div>
  74.                             <div class="align-items-center mb-5">
  75.                                 <div class="d-grid">
  76.                                     <div class="g-recaptcha" data-sitekey="6Lc4NSQrAAAAAPo_MUEoj18JriAWuWj933iAian0"></div>
  77.                                 </div>
  78.                             </div>
  79.                             <input type="hidden" value="{% if course_id is defined %}{{ course_id }}{% endif %}" name="course">
  80.                             <input type="hidden" value="{% if course_id is defined %}{% if group_id matches '/^\\d+$/' %}{{ group_id }}{% endif %}{% endif %}" name="group">
  81.                             <input type="hidden" value="{% if type is defined %}{{ type }}{% endif %}" name="type">
  82.                             <input type="hidden" value="{% if district is defined %}{{ district }}{% else %}rejestracja{% endif %}" name="district">
  83.                             <div class="d-grid">
  84.                                 <button id="register_button" type="submit" class="btn btn-primary btn-lg rounded-pill">Zapisz dziecko</button>
  85.                             </div>
  86.                         </form>
  87.                     </div>
  88.                 </div>
  89.             </div>
  90.         </section>
  91.     </main>
  92. {% endblock %}
  93. {% block js %}
  94.     {{ parent() }}
  95. <script src="{{ asset('./assets/js/jquery-3.6.4.min.js') }}"></script>
  96. <script>
  97.     const passwordInput = document.getElementById('password');
  98.     const repeatPasswordInput = document.getElementById('password-repeat');
  99.     const emailInput = document.querySelector('[name="email"]');
  100.     const phoneInput = document.querySelector('[name="phone"]');
  101.     const form = document.getElementById('client_form');
  102.     function validateForm(event) {
  103.         let valid = true;
  104.         const requiredFields = form.querySelectorAll('[required]');
  105.         requiredFields.forEach(field => {
  106.             if (!field.value.trim()) {
  107.                 field.classList.add('is-invalid');
  108.                 valid = false;
  109.             } else {
  110.                 field.classList.remove('is-invalid');
  111.             }
  112.         });
  113.         const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;
  114.         if (!emailRegex.test(emailInput.value.trim())) {
  115.             emailInput.classList.add('is-invalid');
  116.             document.getElementById('emailHelp').style.display = 'block';
  117.             valid = false;
  118.         } else {
  119.             emailInput.classList.remove('is-invalid');
  120.             document.getElementById('emailHelp').style.display = 'none';
  121.         }
  122.         const phoneRegex = /^\+?[0-9]{9,15}$/;
  123.         if (!phoneRegex.test(phoneInput.value.trim())) {
  124.             phoneInput.classList.add('is-invalid');
  125.             document.getElementById('phoneHelp').style.display = 'block';
  126.             valid = false;
  127.         } else {
  128.             phoneInput.classList.remove('is-invalid');
  129.             document.getElementById('phoneHelp').style.display = 'none';
  130.         }
  131.         // Has艂o - min 6 znak贸w
  132.         if (passwordInput.value.length < 6) {
  133.             passwordInput.classList.add('is-invalid');
  134.             document.getElementById('passwordHelpBlock').style.display = 'block';
  135.             valid = false;
  136.         } else {
  137.             passwordInput.classList.remove('is-invalid');
  138.             document.getElementById('passwordHelpBlock').style.display = 'none';
  139.         }
  140.         // Por贸wnanie hase艂
  141.         if (passwordInput.value.length >= 6 && passwordInput.value !== repeatPasswordInput.value) {
  142.             repeatPasswordInput.classList.add('is-invalid');
  143.             document.getElementById('passwordHelpBlock2').style.display = 'block';
  144.             valid = false;
  145.         } else {
  146.             repeatPasswordInput.classList.remove('is-invalid');
  147.             document.getElementById('passwordHelpBlock2').style.display = 'none';
  148.         }
  149.         return valid;
  150.     }
  151.     function sendRequest(formData) {
  152.         const xhr = new XMLHttpRequest();
  153.         xhr.open('POST', '/zapisz_na_kurs', true);
  154.         xhr.setRequestHeader('Content-Type', 'application/json');
  155.         xhr.onreadystatechange = function () {
  156.             if (xhr.readyState === 4) {
  157.                 if (xhr.status === 200) {
  158.                     const jsonObj = JSON.parse(xhr.responseText);
  159.                     if (jsonObj.status == "success") {
  160.                        // document.getElementById('form_div').classList.add('text-center');
  161.                         {% if group_id is defined %}
  162.                             {% if group_id matches '/^\\d+$/' %}
  163.                                 window.location.href = "{{ path('register_success')}}";
  164.                             {% else %}
  165.                                 window.location.href = "{{ path('register_waiting_list')}}";
  166.                             {% endif %}
  167.                         {% else %}
  168.                             window.location.href = "{{ path('register_success')}}";
  169.                         {% endif %}
  170.                     } else if (jsonObj.status == "error3") {
  171.                         window.location.href = "{{ path('account_exsist')}}";
  172.                     }
  173.                 } else {
  174.                     alert('B艂膮d po艂膮czenia z serwerem.');
  175.                 }
  176.             }
  177.         };
  178.         xhr.send(formData);
  179.     }
  180.     form.addEventListener('submit', function (event) {
  181.         event.preventDefault();
  182.         if (!validateForm(event)) {
  183.             return;
  184.         }
  185.         const data = {};
  186.         new FormData(form).forEach((value, key) => {
  187.             data[key] = value;
  188.         });
  189.         sendRequest(JSON.stringify(data));
  190.     });
  191. </script>
  192.     <script src="https://www.google.com/recaptcha/api.js" async defer></script>
  193. {% endblock %}