Init Git Prod Mars 2026

This commit is contained in:
Oleg Barykin committed 2026-03-05 10:25:39 +01:00
commit d81efe93b1
362 files changed
+86627

No files matched your search

+411
View File
@@ -0,0 +1,411 @@
<?php
require_once __DIR__ . '/../includes/bootstrap_global.php';
?>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title><?= $translations['insc_praticien_title'] ?></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="<?= asset('/includes/site_style.css') ?>">
<link rel="stylesheet" href="<?= asset('/includes/custom_style.css') ?>">
<link rel="stylesheet" href="<?= asset('/includes/mobil_style.css') ?>">
<style>
.toggle-password {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
font-size: 18px;
}
.strength-bar {
height: 8px;
display: flex;
margin-bottom: 10px;
border-radius: 5px;
overflow: hidden;
}
.strength-fill {
flex: 1;
background: #ccc;
transition: background-color 0.3s ease;
}
.message-erreur {
color: red;
font-size: 0.9em;
display: none;
margin-bottom: 10px;
}
/* Checkbox custom */
.chk-wrap{
display:flex; align-items:flex-start; gap:10px; cursor:pointer; user-select:none;
}
.chk-wrap input{
position:absolute; opacity:0; pointer-events:none;
}
.chk-box{
width:22px; height:22px; flex:0 0 22px;
border:2px solid #38378B; border-radius:6px; background:#fff;
box-shadow:0 2px 6px rgba(0,0,0,.06);
display:inline-block; position:relative; transition:.18s ease;
}
.chk-wrap input:checked + .chk-box{
background:#38378B; border-color:#38378B;
}
.chk-wrap input:checked + .chk-box::after{
content:""; position:absolute; left:6px; top:2px; width:6px; height:12px;
border:solid #fff; border-width:0 2px 2px 0; transform:rotate(45deg);
}
.chk-label{
color:#111; line-height:1.4; font-size: 12px;
}
.chk-label a{ color:#38378B; text-decoration:none; }
.chk-label a:hover{ text-decoration:none; }
</style>
<?php include_once __DIR__ . '/includes/tracking.php'; ?>
</head>
<body>
<header class="site-header">
<div class="container">
<div class="header-left">
<div class="brand">
<a href="/index.php"><img src="/public/uploads/img/logo_u.png"
alt="uslugi.fr"
class="logo-mobile"></a>
<a href="/index.php"><img src="/public/uploads/img/logo.png"
alt="uslugi.fr"
class="logo-desktop"></a>
</div>
<div class="lang-switch">
<?php require __DIR__ . '/includes/menu_langue.php'; ?>
</div>
</div>
<nav class="header-actions">
<div class="dropdown">
<button class="btn btn-logo rounded-circle d-inline-flex align-items-center justify-content-center question-btn"
type="button" data-bs-toggle="dropdown" data-bs-auto-close="true"
aria-expanded="false" aria-label="Помощь">?</button>
<ul class="dropdown-menu dropdown-menu-end shadow help-menu menu-panel">
<li><a href="/how-it-work.php"><?= $translations['kak_rabotaet'] ?></a></a></li>
<li><a href="/about.php"><?= $translations['pro_nas'] ?></a></li>
<li><a href="/faq.php"><?= $translations['faq'] ?></a></li>
<li><a href="/contact.php"><?= $translations['nam_pisat'] ?></a></li>
</ul>
</div>
</nav>
</div>
</header>
<div class="main">
<div class="auth-center">
<?php require __DIR__ . '/choisir_abb.php'; ?>
<div class="card shadow-sm p-4" style="min-width: 380px; max-width: 480px; width: 100%; margin:40px auto;">
<h3 class="mb-4 text-center"><?= $translations['insc_praticien_title'] ?></h3>
<form id="form-inscription" method="POST" action="traitement_inscription_praticien.php">
<!-- Champ SIREN/SIRET -->
<input type="hidden" name="abonnement_id" id="abonnement_id" value="">
<div class="mb-3">
<input type="text"
name="siret"
id="siret"
class="form-control"
placeholder="<?= $translations['placeholder_siret'] ?>"
required
maxlength="17"
inputmode="numeric"
pattern="[0-9 ]+">
<div id="siret-feedback" class="message-erreur" style="display:none;"></div>
</div>
<div class="mb-3">
<input type="text" name="prenom" class="form-control" placeholder="<?= $translations['placeholder_prenom'] ?>" required>
</div>
<div class="mb-3">
<input type="text" name="nom" class="form-control" placeholder="<?= $translations['placeholder_nom'] ?>" required>
</div>
<div class="mb-1">
<input type="email" name="email" id="email" class="form-control" placeholder="<?= $translations['email_placeholder'] ?>" required>
</div>
<div class="message-erreur" id="email-erreur"><?= addslashes($translations['email_deja_utilise']) ?></div>
<div class="mb-3 position-relative">
<input type="password" name="mot_de_passe" id="mot_de_passe" class="form-control" placeholder="<?= $translations['motdepasse_placeholder'] ?>" required>
<span class="toggle-password" onclick="togglePassword('mot_de_passe')">👁️</span>
</div>
<div id="niveau-securite" class="mb-2 text-muted"><?= $translations['mdp_regle_min'] ?></div>
<div class="strength-bar mb-3">
<div class="strength-fill"></div>
<div class="strength-fill"></div>
<div class="strength-fill"></div>
</div>
<!-- Confirmation mot de passe -->
<div class="mb-3 position-relative">
<input type="password"
name="confirm_mot_de_passe"
id="confirm_mot_de_passe"
class="form-control"
placeholder="<?= $translations['confirm_mdp_placeholder'] ?? 'Confirmer le mot de passe' ?>"
required
autocomplete="new-password">
<span class="toggle-password" onclick="togglePassword('confirm_mot_de_passe')">👁️</span>
</div>
<div id="confirm-feedback" class="message-erreur" aria-live="polite" style="display:none;"></div>
<!-- CGU / Confidentialité (obligatoire) -->
<div class="mb-3">
<label class="chk-wrap">
<input type="checkbox" id="accept_cgu" name="accept_cgu" required>
<span class="chk-box" aria-hidden="true"></span>
<span class="chk-label"><?= $translations['cgu_label_html'] ?></span>
</label>
<div class="message-erreur" id="cgu-error" aria-live="polite" style="display:none;">
<?= htmlspecialchars($translations['cgu_obligatoire'], ENT_QUOTES, 'UTF-8') ?>
</div>
</div>
<button type="submit" class="btn btn-primary w-100"><?= $translations['btn_sinscrire'] ?></button>
</form>
</div>
<script>
(function(){
const form = document.getElementById('form-inscription');
const pwd = document.getElementById('mot_de_passe');
const cpwd = document.getElementById('confirm_mot_de_passe');
const feedback = document.getElementById('confirm-feedback');
const MSGS = {
mismatch: '<?= addslashes($translations["mdp_non_identiques"] ?? "Les mots de passe ne correspondent pas.") ?>',
ok: '<?= addslashes($translations["mdp_identiques_ok"] ?? "Les mots de passe correspondent.") ?>'
};
function showOk(){
feedback.textContent = MSGS.ok;
feedback.style.color = 'green';
feedback.style.display = 'block';
}
function showErr(){
feedback.textContent = MSGS.mismatch;
feedback.style.color = 'red';
feedback.style.display = 'block';
}
function checkMatch(){
// Si l’utilisateur n’a pas encore saisi la confirmation, on cache le message
if (!cpwd.value) { feedback.style.display = 'none'; form.dataset.confirmOk = '0'; return; }
if (pwd.value === cpwd.value) { showOk(); form.dataset.confirmOk = '1'; }
else { showErr(); form.dataset.confirmOk = '0'; }
}
pwd.addEventListener('input', checkMatch);
cpwd.addEventListener('input', checkMatch);
form.addEventListener('submit', function(e){
// Double sécurité côté front : empêche l’envoi si non identiques
if (form.dataset.confirmOk !== '1') {
checkMatch();
e.preventDefault();
cpwd.focus();
}
});
})();
</script>
<script>
function togglePassword(id) {
const input = document.getElementById(id);
if (input) {
input.type = input.type === "password" ? "text" : "password";
}
}
// Traductions envoyées depuis PHP
const EMAIL_TAKEN = '<?= addslashes($translations['email_deja_utilise']) ?>';
const T = {
rule: '<?= addslashes($translations['mdp_regle_min']) ?>',
weak: '<?= addslashes($translations['securite_faible']) ?>',
medium: '<?= addslashes($translations['securite_moyen']) ?>',
strong: '<?= addslashes($translations['securite_fort']) ?>'
};
</script>
<!--***********************************************************
Verification ajax pour SIRET
**************************************************************-->
<script>
// Vérifie Luhn (pour SIRET)
function luhnCheck(num) {
const arr = (num + '').split('').reverse().map(x => parseInt(x, 10));
const sum = arr.reduce((acc, val, i) => {
if (i % 2) {
val *= 2;
if (val > 9) val -= 9;
}
return acc + val;
}, 0);
return sum % 10 === 0;
}
(function(){
const form = document.getElementById('form-inscription'); // <-- manquait ici
const siretInput = document.getElementById('siret');
const feedback = document.getElementById('siret-feedback');
// init
form.dataset.siretExists = '0';
let debounceId = null;
let lastQueried = '';
const MSG = {
invalide: '<?= addslashes($translations["siret_format_invalide"]) ?>',
valide: '<?= addslashes($translations["siret_valide_format"]) ?>',
existe: '<?= addslashes($translations["siret_trouve"]) ?>',
nexiste: '<?= addslashes($translations["siret_non_trouve"]) ?>',
attente: '<?= addslashes($translations["siret_verification_en_cours"] ?? "Vérification en cours…") ?>'
};
function formatSiret(value) {
value = value.replace(/\D/g, '');
if (value.length > 3) value = value.slice(0,3) + ' ' + value.slice(3);
if (value.length > 7) value = value.slice(0,7) + ' ' + value.slice(7);
if (value.length > 11) value = value.slice(0,11) + ' ' + value.slice(11);
return value;
}
function setFeedback(text, color) {
feedback.textContent = text;
feedback.style.color = color;
feedback.style.display = 'block';
}
function checkSiretImmediate() {
// formatage visuel
const formatted = formatSiret(siretInput.value);
if (siretInput.value !== formatted) siretInput.value = formatted;
const raw = siretInput.value.replace(/\s+/g, '');
// On ne valide QUE le SIRET (14). Si 9 => on ne dit rien (évite faux positifs SIREN)
if (raw.length === 0) { feedback.style.display = 'none'; form.dataset.siretExists = '0'; return; }
if (raw.length !== 14) {
setFeedback(MSG.invalide, 'red');
form.dataset.siretExists = '0';
return;
}
if (!luhnCheck(raw)) {
setFeedback(MSG.invalide, 'red');
form.dataset.siretExists = '0';
return;
}
// Format OK + Luhn OK → on consulte l’API
setFeedback(MSG.attente, '#666');
form.dataset.siretExists = '0';
// Evite d’appeler si même valeur que la dernière fois
if (raw === lastQueried) return;
lastQueried = raw;
// Débounce réseau (600ms après dernière frappe)
clearTimeout(debounceId);
debounceId = setTimeout(() => {
fetch('/js/ajax_verif_siret.php?siret=' + encodeURIComponent(raw)) // <-- ajuste le chemin si besoin
.then(r => r.json())
.then(data => {
if (data && data.exists) {
setFeedback(MSG.existe, 'green');
form.dataset.siretExists = '1';
} else {
setFeedback(MSG.nexiste, 'red');
form.dataset.siretExists = '0';
}
})
.catch(() => {
// En cas d’erreur réseau, on reste prudent
setFeedback(MSG.nexiste, 'red');
form.dataset.siretExists = '0';
});
}, 600);
}
siretInput.addEventListener('input', checkSiretImmediate);
// (Optionnel) Bloquer la soumission si tu EXIGES la présence INSEE
form.addEventListener('submit', function(e){
const raw = siretInput.value.replace(/\s+/g, '');
if (raw.length !== 14 || !luhnCheck(raw)) {
e.preventDefault();
setFeedback(MSG.invalide, 'red');
siretInput.focus();
return;
}
// Exiger existence INSEE :
// if (form.dataset.siretExists !== '1') {
// e.preventDefault();
// setFeedback(MSG.nexiste, 'red');
// siretInput.focus();
// }
});
})();
</script>
<script src="js/verif_email.js"></script>
<script>
(function(){
const form = document.getElementById('form-inscription');
const cgu = document.getElementById('accept_cgu');
const err = document.getElementById('cgu-error');
form.addEventListener('submit', function(e){
if (!cgu.checked) {
e.preventDefault();
err.style.display = 'block';
// focus accessible
cgu.focus();
} else {
err.style.display = 'none';
}
});
})();
</script>
<script>
(function(){
const form = document.getElementById('form-inscription');
const hidden = document.getElementById('abonnement_id');
const err = document.getElementById('abo-error');
if (!form) return;
form.addEventListener('submit', function(e){
if (!hidden || !hidden.value) {
e.preventDefault();
if (err) err.style.display = 'block';
document.getElementById('abo-block')?.scrollIntoView({behavior:'smooth', block:'start'});
}
});
})();
</script>
</div>
</div>
<footer class="site-footer">
<div class="container">
<p><?= $translations['copyr'] ?></p>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>