227 lines
8.7 KiB
PHP
227 lines
8.7 KiB
PHP
<?php
|
||
require_once __DIR__ . '/../includes/init_client.php';
|
||
|
||
$id = (int) ($_SESSION['reference_id'] ?? 0);
|
||
if (! $id) {http_response_code(403);exit($translations['client_introuvable'] ?? 'Client introuvable');}
|
||
|
||
// Récupérer les données du client
|
||
$stmt = $pdo->prepare("SELECT * FROM client WHERE id = ?");
|
||
$stmt->execute([$id]);
|
||
$client = $stmt->fetch();
|
||
if (! $client) {
|
||
exit($translations['client_introuvable'] ?? 'Client introuvable');
|
||
}
|
||
|
||
// ---- Traitement du formulaire AVANT tout output ----
|
||
if (($_SERVER['REQUEST_METHOD'] ?? '') === 'POST') {
|
||
require_post_csrf();
|
||
$nom = trim($_POST['nom'] ?? '');
|
||
$prenom = trim($_POST['prenom'] ?? '');
|
||
$telephone = trim($_POST['telephone'] ?? '');
|
||
$genre = trim($_POST['genre'] ?? '');
|
||
$date_naiss = $_POST['date_naissance'] ?? null;
|
||
$adresse = trim($_POST['adresse'] ?? '');
|
||
$ville = trim($_POST['ville'] ?? '');
|
||
$cp = trim($_POST['code_postal'] ?? '');
|
||
|
||
$stmt = $pdo->prepare("
|
||
UPDATE client SET nom=:nom, prenom=:prenom, telephone=:telephone,
|
||
genre=:genre, date_naissance=:date_naissance, adresse=:adresse,
|
||
ville=:ville, code_postal=:code_postal
|
||
WHERE id=:id
|
||
");
|
||
$stmt->execute([
|
||
'nom' => $nom,
|
||
'prenom' => $prenom,
|
||
'telephone' => $telephone,
|
||
'genre' => $genre,
|
||
'date_naissance' => $date_naiss ?: null,
|
||
'adresse' => $adresse,
|
||
'ville' => $ville,
|
||
'code_postal' => $cp,
|
||
'id' => $id,
|
||
]);
|
||
|
||
// redirection (évite le repost + actualise la page infos)
|
||
header('Location: /public/client/informations.php?updated=1');
|
||
exit;
|
||
}
|
||
require_once __DIR__ . '/../includes/header.php';
|
||
|
||
?>
|
||
|
||
<div class="main1">
|
||
<div class="container py-5">
|
||
|
||
|
||
<form method="POST" class="shadow p-4 rounded bg-light">
|
||
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars(ensure_csrf_token(), ENT_QUOTES, 'UTF-8') ?>">
|
||
<h2 class="mb-4 text-center"><?php echo $translations['modifier_infos_heading'] ?></h2>
|
||
<div class="mb-3">
|
||
<label class="form-label"><?php echo $translations['label_nom'] ?> *</label>
|
||
<input type="text" name="nom" value="<?php echo htmlspecialchars($client['nom'] ?? '') ?>" required class="form-control">
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<label class="form-label"><?php echo $translations['label_prenom'] ?> *</label>
|
||
<input type="text" name="prenom" value="<?php echo htmlspecialchars($client['prenom'] ?? '') ?>" required class="form-control">
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<label class="form-label"><?php echo $translations['label_telephone'] ?> *</label>
|
||
<input type="tel" name="telephone" id="telephone" value="<?php echo htmlspecialchars($client['telephone'] ?? '') ?>" class="form-control" placeholder="+33600000000"
|
||
required
|
||
pattern="^\+?[1-9]\d{6,14}$"
|
||
title="<?php echo htmlspecialchars($translations['telephone_format_message'] ?? '') ?>">
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<label class="form-label"><?php echo $translations['label_genre'] ?></label>
|
||
<select name="genre" class="form-select">
|
||
<option value=""><?php echo $translations['select_selectionnez'] ?></option>
|
||
<option value="<?php echo $translations['genre_homme'] ?>" <?php echo $client['genre'] === $translations['genre_homme'] ? 'selected' : '' ?>><?php echo $translations['genre_homme'] ?></option>
|
||
<option value="<?php echo $translations['genre_femme'] ?>" <?php echo $client['genre'] === $translations['genre_femme'] ? 'selected' : '' ?>><?php echo $translations['genre_femme'] ?></option>
|
||
<option value="<?php echo $translations['genre_autre'] ?>" <?php echo $client['genre'] === $translations['genre_autre'] ? 'selected' : '' ?>><?php echo $translations['genre_autre'] ?></option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<label class="form-label"><?php echo $translations['label_date_naissance'] ?></label>
|
||
<input type="date" name="date_naissance" value="<?php echo htmlspecialchars($client['date_naissance'] ?? '') ?>" class="form-control">
|
||
</div>
|
||
|
||
<div class="mb-3 input-wrapper">
|
||
<label class="form-label"><?php echo $translations['label_adresse'] ?></label>
|
||
<textarea name="adresse" id="adresse" class="form-control"><?php echo htmlspecialchars($client['adresse'] ?? '') ?></textarea>
|
||
<ul id="suggestions" class="list-group position-absolute"></ul>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<label class="form-label"><?php echo $translations['label_ville'] ?></label>
|
||
<input type="text" name="ville" id="ville" value="<?php echo htmlspecialchars($client['ville'] ?? '') ?>" class="form-control">
|
||
</div>
|
||
|
||
<div class="mb-4">
|
||
<label class="form-label"><?php echo $translations['label_code_postal'] ?></label>
|
||
<input type="text" name="code_postal" id="code_postal" value="<?php echo htmlspecialchars($client['code_postal'] ?? '') ?>" class="form-control">
|
||
</div>
|
||
|
||
<div class="text-center">
|
||
<button type="submit" class="btn btn-primary"><?php echo $translations['btn_mettre_a_jour'] ?></button>
|
||
</div>
|
||
<?php echo $translations['champs_obligatoire'] ?>
|
||
</form>
|
||
</div>
|
||
|
||
<script>
|
||
// === Téléphone: simple & efficace ===
|
||
const tel = document.getElementById('telephone');
|
||
|
||
// 1) Nettoyage en direct (espaces, tirets, points, parenthèses)
|
||
tel?.addEventListener('input', function () {
|
||
const pos = this.selectionStart;
|
||
this.value = this.value.replace(/[\s\-._()/]/g, '');
|
||
try { this.setSelectionRange(pos, pos); } catch(_) {}
|
||
});
|
||
|
||
// 2) Normalisation au blur
|
||
tel?.addEventListener('blur', function() {
|
||
let val = this.value.trim().replace(/[\s\-._()/]/g, '');
|
||
if (val.startsWith('00')) val = '+' + val.slice(2);
|
||
if (/^0\d{9}$/.test(val)) val = '+33' + val.substring(1);
|
||
if (val && !val.startsWith('+')) val = '+' + val;
|
||
this.value = val;
|
||
});
|
||
|
||
// 3) Au submit : applique la normalisation même si l’utilisateur n’a pas quitté le champ
|
||
tel?.form?.addEventListener('submit', function (e) {
|
||
tel.dispatchEvent(new Event('blur'));
|
||
if (!tel.checkValidity()) {
|
||
e.preventDefault();
|
||
tel.reportValidity();
|
||
tel.focus();
|
||
}
|
||
});
|
||
|
||
document.addEventListener("DOMContentLoaded", function () {
|
||
const adresseInput = document.getElementById("adresse");
|
||
const villeInput = document.getElementById("ville");
|
||
const cpInput = document.getElementById("code_postal");
|
||
const suggestions = document.getElementById("suggestions");
|
||
|
||
// petite fonction utilitaire : construit "numero + rue"
|
||
function buildStreet(props) {
|
||
const num = (props.housenumber || '').trim();
|
||
const street = (props.street || props.name || '').trim();
|
||
return [num, street].filter(Boolean).join(' ');
|
||
}
|
||
// fallback ville si city manquant (rare)
|
||
function getCity(props) {
|
||
if (props.city) return props.city;
|
||
// ex: "84160, Cucuron, Vaucluse, Provence-Alpes-Côte d'Azur"
|
||
if (props.context) {
|
||
const parts = props.context.split(',').map(s => s.trim());
|
||
// généralement la 2e valeur correspond à la commune
|
||
return parts[1] || parts[0] || '';
|
||
}
|
||
return '';
|
||
}
|
||
|
||
let abortCtrl = null;
|
||
|
||
adresseInput.addEventListener("input", function () {
|
||
const query = adresseInput.value.trim();
|
||
if (query.length < 3) {
|
||
suggestions.innerHTML = '';
|
||
return;
|
||
}
|
||
|
||
// annule la requête précédente si on retape vite
|
||
try { abortCtrl?.abort(); } catch(_) {}
|
||
abortCtrl = new AbortController();
|
||
|
||
fetch("https://api-adresse.data.gouv.fr/search/?limit=5&q=" + encodeURIComponent(query), {
|
||
signal: abortCtrl.signal
|
||
})
|
||
.then(res => res.json())
|
||
.then(data => {
|
||
suggestions.innerHTML = '';
|
||
(data.features || []).forEach(feature => {
|
||
const props = feature.properties || {};
|
||
const li = document.createElement("li");
|
||
li.className = 'list-group-item list-group-item-action';
|
||
li.textContent = props.label || buildStreet(props);
|
||
|
||
li.addEventListener("click", function () {
|
||
// ✅ Adresse = seulement numéro + rue
|
||
adresseInput.value = buildStreet(props);
|
||
// ✅ Ville + CP séparés
|
||
villeInput.value = getCity(props);
|
||
cpInput.value = props.postcode || '';
|
||
suggestions.innerHTML = '';
|
||
});
|
||
|
||
suggestions.appendChild(li);
|
||
});
|
||
})
|
||
.catch(() => {});
|
||
});
|
||
|
||
// clic hors zone -> ferme la liste
|
||
document.addEventListener("click", function (e) {
|
||
if (!suggestions.contains(e.target) && e.target !== adresseInput) {
|
||
suggestions.innerHTML = '';
|
||
}
|
||
});
|
||
});
|
||
</script>
|
||
|
||
</div>
|
||
<footer class="site-footer">
|
||
<div class="container">
|
||
<p><?php echo $translations['copyr'] ?></p>
|
||
</div>
|
||
</footer>
|
||
</body>
|
||
</html>
|