Init Git Prod Mars 2026
This commit is contained in:
commit
d81efe93b1
362 files changed
+86627
No files matched your search
+155
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
// /choisir_abb.php (BLOC EMBED - pas de <html>, pas de <body>, pas de form Stripe)
|
||||
require_once __DIR__ . '/../includes/bootstrap_global.php';
|
||||
|
||||
// Abonnement gratuit (id=1)
|
||||
$FREE_PLAN_ID = 1;
|
||||
|
||||
// (Optionnel) Déjà utilisé ? -> on retire le gratuit
|
||||
$hasUsedFree = false;
|
||||
$praticien_id = (int)($_SESSION['praticien_id'] ?? 0); // si tu as déjà un id en session, sinon 0
|
||||
|
||||
if ($praticien_id > 0) {
|
||||
$sql = "SELECT 1
|
||||
FROM paiement
|
||||
WHERE praticien_id = ?
|
||||
AND abonnement_id = ?
|
||||
AND (statut IS NULL OR statut <> 'échoué')
|
||||
LIMIT 1";
|
||||
$st = $pdo->prepare($sql);
|
||||
$st->execute([$praticien_id, $FREE_PLAN_ID]);
|
||||
$hasUsedFree = (bool)$st->fetchColumn();
|
||||
}
|
||||
|
||||
// Abonnements actifs
|
||||
$stmt = $pdo->query("SELECT * FROM abonnement WHERE actif = 1 ORDER BY prix ASC, duree_jours ASC");
|
||||
$abonnements = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($hasUsedFree) {
|
||||
$abonnements = array_values(array_filter($abonnements, fn($ab) => (int)$ab['id'] !== 1));
|
||||
}
|
||||
|
||||
function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); }
|
||||
?>
|
||||
|
||||
<style>
|
||||
.abo-wrap{
|
||||
max-width: 480px;
|
||||
margin: 24px auto 10px;
|
||||
background:#fff;
|
||||
border:1px solid #e5e7eb;
|
||||
border-radius:18px;
|
||||
box-shadow:0 8px 20px rgba(0,0,0,.06);
|
||||
padding:18px;
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: 768px){ .abo-grid{ grid-template-columns:1fr 1fr; } }
|
||||
|
||||
.abo-item{
|
||||
border:1px solid #e5e7eb;
|
||||
border-radius:16px;
|
||||
padding:12px 12px 12px;
|
||||
margin-bottom: 10px;
|
||||
display:flex; gap:10px;
|
||||
cursor:pointer;
|
||||
transition: .15s ease;
|
||||
align-items:flex-start;
|
||||
}
|
||||
.abo-item:hover{ border-color:#c7d2fe; box-shadow:0 6px 16px rgba(0,0,0,.05); }
|
||||
.abo-item.active{ border-color:#38378B; box-shadow:0 10px 22px rgba(56,55,139,.12); }
|
||||
|
||||
.abo-radio{ margin-top:2px; }
|
||||
.abo-name{ font-weight:700; color:#38378B; margin:0; font-size:16px;}
|
||||
.abo-desc{ margin:6px 0 0; color:#555; font-size:13px; line-height:1.35; }
|
||||
.abo-meta{ margin-top:8px; font-size:14px; font-weight:700; color:#38378B; display:flex; gap:10px; flex-wrap:wrap; }
|
||||
|
||||
.abo-error{ display:none; margin-top:10px; color:#E03C3F; font-size:13px; text-align:center; }
|
||||
</style>
|
||||
|
||||
<div class="abo-wrap" id="abo-block">
|
||||
<h3 class="mb-4 text-center"><?= h($translations['choisissez_votre_abonnement'] ?? 'Выберите ваш тариф') ?></h4>
|
||||
<p class="abo-sub"><?= h($translations['abo_obligatoire_inscription'] ?? "Выберите тариф: без этого регистрация невозможна.") ?></p>
|
||||
|
||||
<?php if (!$abonnements): ?>
|
||||
<div class="alert alert-warning text-center mb-0"><?= h($translations['aucun_abonnement_dispo'] ?? 'Нет доступных тарифов.') ?></div>
|
||||
<?php else: ?>
|
||||
<div class="abo-grid" role="radiogroup" aria-label="<?= h($translations['choisissez_votre_abonnement'] ?? 'Выберите ваш тариф') ?>">
|
||||
<?php foreach ($abonnements as $ab): ?>
|
||||
<?php
|
||||
$isFree = ((float)$ab['prix'] == 0.0);
|
||||
|
||||
$prixTxt = $isFree
|
||||
? ($translations['gratuit'] ?? 'Бесплатно')
|
||||
: number_format((float)$ab['prix'], 2, ',', ' ') . ' €';
|
||||
|
||||
$nomKey = trim((string)($ab['nom'] ?? ''));
|
||||
$descKey = trim((string)($ab['description'] ?? ''));
|
||||
|
||||
$nomTxt = $translations[$nomKey] ?? $nomKey;
|
||||
$descTxt = $translations[$descKey] ?? $descKey;
|
||||
|
||||
$id = (int)$ab['id'];
|
||||
?>
|
||||
|
||||
<label class="abo-item" data-abo-item="1">
|
||||
<input class="abo-radio"
|
||||
type="radio"
|
||||
name="abonnement_id_ui"
|
||||
value="<?= $id ?>"
|
||||
aria-label="<?= h($nomTxt) ?>">
|
||||
<div>
|
||||
<p class="abo-name"><?= h($nomTxt) ?></p>
|
||||
|
||||
<?php if ($descKey !== ''): ?>
|
||||
<p class="abo-desc"><?= nl2br(h($descTxt)) ?></p>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="abo-meta">
|
||||
|
||||
<?= h($translations['col_duree'] ?? 'Длительность:') ?>
|
||||
<?= (int)$ab['duree_jours'] ?> <?= h($translations['dnei'] ?? 'дней') ?><br>
|
||||
|
||||
<?= h($prixTxt) ?>
|
||||
</div>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<div class="abo-error" id="abo-error">
|
||||
<?= h($translations['abonnement_obligatoire'] ?? "Пожалуйста, выберите тариф.") ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function(){
|
||||
const block = document.getElementById('abo-block');
|
||||
if (!block) return;
|
||||
|
||||
function refreshActive(){
|
||||
const items = block.querySelectorAll('.abo-item');
|
||||
const err = document.getElementById('abo-error');
|
||||
const hidden = document.getElementById('abonnement_id'); // ✅ maintenant il existe
|
||||
|
||||
items.forEach(it => it.classList.remove('active'));
|
||||
|
||||
const checked = block.querySelector('input[name="abonnement_id_ui"]:checked');
|
||||
if (checked) {
|
||||
checked.closest('.abo-item')?.classList.add('active');
|
||||
if (hidden) hidden.value = checked.value; // ✅ rempli bien le hidden
|
||||
if (err) err.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ un seul listener robuste
|
||||
block.addEventListener('change', function(e){
|
||||
if (e.target && e.target.name === 'abonnement_id_ui') refreshActive();
|
||||
});
|
||||
|
||||
// init
|
||||
refreshActive();
|
||||
});
|
||||
</script>
|
||||
Reference in new issue
Block a user