This commit is contained in:
karim hassan
2025-08-18 19:30:47 +00:00
parent dd17d9f4bf
commit e3620c7f42
16 changed files with 562 additions and 0 deletions

27
public/admin.html Normal file
View File

@@ -0,0 +1,27 @@
<nav class="nav"><div class="inner">
<img src="/assets/img/logo.svg" width="22" height="22" alt="logo"/>
<div class="brand"><span class="badge">P24P</span><span class="title">Padel24Play</span></div>
<a href="/">Accueil</a><a href="/events.html">Événements</a><a href="/admin.html">Admin</a>
<div class="spacer"></div><a href="/reglement.html">Règlement</a></div></nav>
<main class="container">
<h1>🛠️ Admin — Inscriptions</h1>
<div class="card">
<div class="row"><input id="ev" placeholder="eventId (ex: ss-futur-1)" value="ss-futur-1"/><button class="btn" id="loadRegs">Charger</button></div>
<table id="regs"><thead><tr><th>Joueur</th><th>Email</th><th>Paiement</th><th>Statut</th></tr></thead><tbody></tbody></table>
<p class="notice">Version prod de base — paiements temps réel & effets à venir.</p>
</div>
</main>
<script src="/assets/js/app.js"></script>
<script>
document.getElementById('loadRegs').onclick = async ()=>{
const evId = document.getElementById('ev').value.trim();
const list = await api('/api/registrations?eventId='+encodeURIComponent(evId));
const tbody = document.querySelector('#regs tbody'); tbody.innerHTML='';
list.forEach(r=>{
const tr = document.createElement('tr');
tr.innerHTML = `<td>${r.player?.name||'-'}</td><td>${r.player?.email||'-'}</td><td>${r.payment} (${r.paymentStatus||'-'})</td><td>${r.status}</td>`;
tbody.appendChild(tr);
});
};
</script>

27
public/assets/css/app.css Normal file
View File

@@ -0,0 +1,27 @@
:root{ color-scheme:dark; --bg:#0a0f1f; --card:rgba(255,255,255,.06); --line:rgba(255,255,255,.12); --txt:#eaf2ff; --acc:#27b0ff; --good:#22c55e; --bad:#ef4444 }
*{ box-sizing:border-box }
html,body{ margin:0; padding:0; background:radial-gradient(1000px 600px at 10% -10%, #122040 0%, transparent 60%), var(--bg); color:var(--txt); font-family: ui-sans-serif,system-ui,Segoe UI,Roboto,Helvetica,Arial }
a{ color:#9ad1ff; text-decoration:none }
.container{ max-width:1100px; margin:0 auto; padding:24px }
.nav{ position:sticky; top:0; z-index:10; backdrop-filter: blur(10px); background: rgba(6,12,24,.6); border-bottom:1px solid var(--line) }
.nav .inner{ display:flex; gap:16px; align-items:center; padding:12px 20px }
.brand{ display:flex; gap:10px; align-items:center; font-weight:900; letter-spacing:.3px }
.badge{ background:linear-gradient(135deg,#0ea5e9,#2563eb); padding:6px 10px; border-radius:10px; font-size:12px; font-weight:800; color:white }
.spacer{ flex:1 }
.btn{ background:linear-gradient(135deg,#0ea5e9,#2563eb); color:white; padding:10px 14px; border:0; border-radius:12px; cursor:pointer; font-weight:700; box-shadow:0 10px 24px rgba(37,99,235,.25) }
.row{ display:flex; gap:14px; flex-wrap:wrap }
.card{ background:var(--card); border:1px solid var(--line); border-radius:16px; padding:16px }
h1{ font-size:28px; margin:18px 0 }
table{ width:100%; border-collapse: collapse }
th,td{ border-top:1px solid var(--line); padding:10px 8px; text-align:left }
small{ opacity:.8 }
.hero{ display:grid; grid-template-columns: 1.2fr .8fr; gap:22px; align-items:center }
@media (max-width:900px){ .hero{ grid-template-columns:1fr } }
.pill{ border:1px solid var(--line); border-radius:999px; padding:6px 10px; display:inline-flex; gap:6px; align-items:center }
input,select{ background:#0f1b36; color:var(--txt); border:1px solid var(--line); border-radius:10px; padding:10px 12px; width:100% }
label{ font-size:13px; opacity:.9 }
.grid{ display:grid; gap:12px }
.grid-2{ grid-template-columns: 1fr 1fr }
.grid-3{ grid-template-columns: repeat(3, 1fr) }
footer{ margin-top:40px; opacity:.7; font-size:13px; border-top:1px solid var(--line); padding-top:14px }
.notice{ padding:10px 12px; border:1px dashed var(--line); border-radius:12px; background: rgba(255,255,255,.04) }

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
<defs><linearGradient id="g" x1="0" x2="1"><stop offset="0" stop-color="#0ea5e9"/><stop offset="1" stop-color="#2563eb"/></linearGradient></defs>
<circle cx="32" cy="32" r="30" fill="url(#g)"/>
<circle cx="32" cy="32" r="18" fill="none" stroke="white" stroke-width="4" stroke-dasharray="4 6"/>
<rect x="20" y="26" width="24" height="12" rx="6" fill="white" opacity="0.9"/>
</svg>

After

Width:  |  Height:  |  Size: 449 B

12
public/assets/js/app.js Normal file
View File

@@ -0,0 +1,12 @@
async function api(path, opts={}){
const res = await fetch(path, { headers:{ 'content-type':'application/json' }, ...opts });
if (!res.ok) throw new Error(await res.text());
const ct = res.headers.get('content-type')||'';
return ct.includes('application/json')? res.json() : res.text();
}
document.addEventListener('DOMContentLoaded', async ()=>{
try {
const cfg = await api('/api/config');
const el = document.querySelector('.title'); if (el) el.textContent = cfg.siteName || 'Padel24Play';
} catch {}
});

18
public/events.html Normal file
View File

@@ -0,0 +1,18 @@
<nav class="nav"><div class="inner">
<img src="/assets/img/logo.svg" width="22" height="22" alt="logo"/>
<div class="brand"><span class="badge">P24P</span><span class="title">Padel24Play</span></div>
<a href="/">Accueil</a><a href="/events.html">Événements</a><a href="/admin.html">Admin</a>
<div class="spacer"></div><a href="/reglement.html">Règlement</a></div></nav>
<main class="container">
<h1>📅 Événements</h1>
<div class="card">
<table id="eventsTable"><thead><tr><th>Nom</th><th>Type</th><th>Date</th><th>Lieu</th><th></th></tr></thead><tbody></tbody></table>
</div>
</main>
<script src="/assets/js/app.js"></script>
<script>
(async()=>{ const rows=document.querySelector('#eventsTable tbody'); const list = await api('/api/events');
list.forEach(ev=>{ const tr=document.createElement('tr'); tr.innerHTML = `<td>${ev.name}</td><td>${ev.kind||'-'}</td><td>${new Date(ev.date).toLocaleString()}</td><td>${ev.location}</td>
<td><a class="btn" href="/register.html?eventId=${encodeURIComponent(ev.id)}">S'inscrire</a></td>`; rows.appendChild(tr); });
})();</script>

28
public/index.html Normal file
View File

@@ -0,0 +1,28 @@
<nav class="nav"><div class="inner">
<img src="/assets/img/logo.svg" width="22" height="22" alt="logo"/>
<div class="brand"><span class="badge">P24P</span><span class="title">Padel24Play</span></div>
<a href="/">Accueil</a><a href="/events.html">Événements</a><a href="/admin.html">Admin</a>
<div class="spacer"></div><a href="/reglement.html">Règlement</a></div></nav>
<main class="container">
<section class="hero">
<div>
<h1>🎉 SuperSunday — V1 (prod)</h1>
<p>Base propre prête à tester (port 8080) — événements, inscriptions, iCal.</p>
<div class="row" style="margin-top:16px">
<a class="btn" href="/events.html">Voir les événements</a>
<a class="btn" href="/admin.html">Admin</a>
</div>
<p class="notice" style="margin-top:12px">Version sans effets “waouw” pour rester simple. On les ajoutera en brique.</p>
</div>
<div class="card">
<h3>Ce qui est dedans</h3>
<ul>
<li>8 éditions Winter (tous les 14 jours dès dim. 5 oct. 2025, 08:0011:00)</li>
<li>Un live démo (pour les inscriptions) et un futur ouvert</li>
<li>Formulaire dinscription + iCal</li>
</ul>
</div>
</section>
</main>
<script src="/assets/js/app.js"></script>

32
public/register.html Normal file
View File

@@ -0,0 +1,32 @@
<nav class="nav"><div class="inner">
<img src="/assets/img/logo.svg" width="22" height="22" alt="logo"/>
<div class="brand"><span class="badge">P24P</span><span class="title">Padel24Play</span></div>
<a href="/">Accueil</a><a href="/events.html">Événements</a><a href="/admin.html">Admin</a>
<div class="spacer"></div><a href="/reglement.html">Règlement</a></div></nav>
<main class="container">
<h1>📝 Inscription</h1>
<div class="card">
<form id="form" class="grid grid-2">
<div><label>Nom complet</label><input name="name" required/></div>
<div><label>Email</label><input name="email" type="email" required/></div>
<div><label>Téléphone</label><input name="phone" required/></div>
<div><label>Niveau</label><select name="level"><option>Débutant</option><option>Intermédiaire</option><option>Avancé</option></select></div>
<div><label>Paiement</label><select name="payment"><option value="card">Stripe</option><option value="paypal">PayPal</option><option value="onspot">Sur place</option></select></div>
<div><button class="btn">Valider</button></div>
</form>
<p id="msg" class="notice"></p>
</div>
</main>
<script src="/assets/js/app.js"></script>
<script>
const params = new URLSearchParams(location.search); const eventId = params.get('eventId')||'ss-futur-1';
document.getElementById('form').addEventListener('submit', async (e)=>{
e.preventDefault();
const f = new FormData(e.target);
const reg = { eventId, player:{ name:f.get('name'), email:f.get('email'), phone:f.get('phone'), level:f.get('level') }, payment:f.get('payment') };
const created = await fetch('/api/registrations', { method:'POST', headers:{'content-type':'application/json'}, body: JSON.stringify(reg) }).then(r=>r.json());
document.getElementById('msg').innerHTML = "Inscription créée ✔️ — "+
"<a class='btn' href='/api/ical/"+created.id+"'>Télécharger iCal</a>";
});
</script>

10
public/reglement.html Normal file
View File

@@ -0,0 +1,10 @@
<nav class="nav"><div class="inner">
<img src="/assets/img/logo.svg" width="22" height="22" alt="logo"/>
<div class="brand"><span class="badge">P24P</span><span class="title">Padel24Play</span></div>
<a href="/">Accueil</a><a href="/events.html">Événements</a><a href="/admin.html">Admin</a>
<div class="spacer"></div><a href="/reglement.html">Règlement</a></div></nav>
<main class="container">
<h1>📜 Règlement (extrait)</h1>
<div class="card"><p>Americano, fairplay, BYE équitables, remboursement jusquà J2 (48h), iCal après inscription.</p></div>
</main>