Files
RelaisSMS/doc/maquette-afpma-sms.html

737 lines
16 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Maquette RelaisSMS</title>
<style>
:root {
--bg: #f4f7fb;
--panel: #ffffff;
--ink: #172033;
--muted: #687184;
--line: #dde4ef;
--soft: #eef3f8;
--brand: #156f73;
--brand-dark: #0d5558;
--accent: #f1b544;
--danger: #bf3d3d;
--ok: #2f8756;
--radius: 8px;
--shadow: 0 18px 40px rgba(31, 49, 78, 0.12);
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
color: var(--ink);
background: var(--bg);
overflow-x: hidden;
}
.app {
min-height: 100vh;
display: grid;
grid-template-columns: 248px minmax(0, 1fr);
}
.sidebar {
background: #102a35;
color: #e9f4f5;
padding: 22px 18px;
display: flex;
flex-direction: column;
gap: 24px;
}
.brand {
display: flex;
align-items: center;
gap: 12px;
font-weight: 760;
font-size: 18px;
}
.brand-mark {
width: 36px;
height: 36px;
display: grid;
place-items: center;
border-radius: 8px;
background: var(--accent);
color: #102a35;
font-weight: 820;
}
.nav {
display: grid;
gap: 6px;
}
.nav button,
.icon-button,
.primary,
.secondary,
.chip button {
font: inherit;
}
.nav button {
width: 100%;
height: 42px;
border: 0;
border-radius: 8px;
background: transparent;
color: #c7dadd;
display: flex;
align-items: center;
gap: 12px;
padding: 0 12px;
text-align: left;
cursor: default;
}
.nav button.active {
background: #1b4655;
color: #ffffff;
}
.nav .ico {
width: 22px;
text-align: center;
color: var(--accent);
}
.sync-card {
margin-top: auto;
border: 1px solid rgba(255, 255, 255, 0.14);
border-radius: 8px;
padding: 14px;
background: rgba(255, 255, 255, 0.06);
}
.sync-card strong {
display: block;
font-size: 13px;
margin-bottom: 4px;
}
.sync-card span {
display: block;
color: #b8ccd0;
font-size: 12px;
line-height: 1.4;
}
.main {
min-width: 0;
padding: 24px;
}
.topbar {
display: flex;
justify-content: space-between;
align-items: center;
gap: 16px;
margin-bottom: 20px;
}
.title h1 {
margin: 0;
font-size: 28px;
line-height: 1.15;
letter-spacing: 0;
}
.title p {
margin: 6px 0 0;
color: var(--muted);
font-size: 14px;
}
.actions {
display: flex;
gap: 10px;
align-items: center;
flex-wrap: wrap;
justify-content: flex-end;
}
.icon-button,
.primary,
.secondary {
border: 1px solid var(--line);
border-radius: 8px;
min-height: 40px;
background: var(--panel);
color: var(--ink);
padding: 0 14px;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
cursor: default;
white-space: nowrap;
}
.icon-button {
width: 40px;
padding: 0;
}
.primary {
background: var(--brand);
color: #ffffff;
border-color: var(--brand);
font-weight: 720;
}
.secondary {
background: #ffffff;
font-weight: 650;
}
.layout {
display: grid;
grid-template-columns: minmax(0, 1fr);
gap: 18px;
align-items: start;
max-width: 980px;
}
.layout > *,
.panel,
.composer,
.search {
min-width: 0;
}
.panel {
background: var(--panel);
border: 1px solid var(--line);
border-radius: 8px;
box-shadow: var(--shadow);
}
.panel-header {
display: flex;
justify-content: space-between;
gap: 12px;
align-items: center;
padding: 18px 18px 12px;
border-bottom: 1px solid var(--line);
}
.panel-header h2 {
margin: 0;
font-size: 17px;
letter-spacing: 0;
}
.tabs {
display: flex;
padding: 4px;
background: var(--soft);
border-radius: 8px;
gap: 4px;
}
.tabs span {
padding: 7px 10px;
border-radius: 6px;
font-size: 13px;
color: var(--muted);
}
.tabs span.active {
background: #ffffff;
color: var(--ink);
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
}
.composer {
padding: 18px;
display: grid;
gap: 18px;
}
.field {
display: grid;
gap: 8px;
}
label {
color: #374053;
font-weight: 700;
font-size: 13px;
}
.search {
min-height: 48px;
border: 1px solid var(--line);
border-radius: 8px;
padding: 7px;
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
background: #fbfcfe;
}
.chip {
display: inline-flex;
align-items: center;
gap: 7px;
max-width: 100%;
min-height: 30px;
padding: 0 8px 0 10px;
border-radius: 999px;
background: #e7f3f0;
color: #164f4d;
font-size: 13px;
font-weight: 670;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.chip.group {
background: #fff1d2;
color: #6c4b05;
}
.chip button {
border: 0;
width: 20px;
height: 20px;
border-radius: 50%;
background: rgba(0, 0, 0, 0.08);
color: inherit;
padding: 0;
}
.placeholder {
color: #8590a3;
font-size: 14px;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.suggestions {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 10px;
}
.suggestion {
border: 1px solid var(--line);
border-radius: 8px;
padding: 12px;
min-width: 0;
background: #ffffff;
}
.suggestion strong {
display: block;
font-size: 13px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.suggestion span {
display: block;
margin-top: 4px;
color: var(--muted);
font-size: 12px;
}
textarea {
width: 100%;
min-height: 178px;
resize: vertical;
border: 1px solid var(--line);
border-radius: 8px;
padding: 14px;
font: inherit;
line-height: 1.5;
color: var(--ink);
background: #fbfcfe;
}
.meta-row {
display: flex;
justify-content: space-between;
gap: 12px;
color: var(--muted);
font-size: 13px;
flex-wrap: wrap;
}
.delivery-options {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 10px;
}
.delivery-card {
border: 1px solid var(--line);
border-radius: 8px;
padding: 12px;
background: #fbfcfe;
min-width: 0;
}
.delivery-card.active {
border-color: var(--brand);
background: #eef8f6;
}
.delivery-card strong {
display: block;
font-size: 13px;
margin-bottom: 5px;
}
.delivery-card span {
display: block;
color: var(--muted);
font-size: 12px;
line-height: 1.35;
}
.compact-summary {
display: flex;
flex-wrap: wrap;
gap: 8px;
padding: 11px;
border: 1px solid var(--line);
border-radius: 8px;
background: #fbfcfe;
}
.summary-pill {
display: inline-flex;
align-items: center;
min-height: 26px;
padding: 0 9px;
border-radius: 999px;
background: var(--soft);
color: #374053;
font-size: 12px;
font-weight: 700;
white-space: nowrap;
}
.summary-pill.ok {
background: #e7f3f0;
color: var(--ok);
}
.summary-pill.warn {
background: #fff1d2;
color: #76530b;
}
.send-row {
display: flex;
justify-content: space-between;
gap: 14px;
align-items: center;
padding-top: 2px;
flex-wrap: wrap;
}
.warning {
display: inline-flex;
align-items: center;
gap: 8px;
color: #77520a;
background: #fff5dc;
border: 1px solid #f3d38b;
border-radius: 8px;
padding: 9px 11px;
font-size: 13px;
}
.history {
margin-top: 18px;
overflow: hidden;
}
table {
width: 100%;
border-collapse: collapse;
}
th,
td {
padding: 13px 16px;
border-bottom: 1px solid var(--line);
text-align: left;
font-size: 13px;
vertical-align: middle;
}
th {
color: var(--muted);
font-weight: 720;
background: #fbfcfe;
}
tr:last-child td {
border-bottom: 0;
}
.badge {
display: inline-flex;
align-items: center;
min-height: 24px;
padding: 0 9px;
border-radius: 999px;
font-size: 12px;
font-weight: 700;
background: #e7f3f0;
color: var(--ok);
white-space: nowrap;
}
.badge.pending {
background: #fff1d2;
color: #76530b;
}
.badge.error {
background: #ffe8e8;
color: var(--danger);
}
@media (max-width: 980px) {
.app {
grid-template-columns: 1fr;
}
.sidebar {
position: static;
}
.nav {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.layout {
grid-template-columns: 1fr;
}
}
@media (max-width: 680px) {
.main {
padding: 16px;
}
.topbar,
.panel-header,
.send-row {
align-items: stretch;
flex-direction: column;
}
.actions,
.primary,
.secondary {
width: 100%;
}
.actions {
display: grid;
grid-template-columns: 1fr;
}
.icon-button {
width: 100%;
}
.search {
display: grid;
grid-template-columns: 1fr;
}
.suggestions,
.delivery-options,
.nav {
grid-template-columns: 1fr;
}
table {
min-width: 620px;
}
.history {
overflow-x: auto;
}
}
</style>
</head>
<body>
<div class="app">
<aside class="sidebar" aria-label="Navigation principale">
<div class="brand">
<div class="brand-mark">R</div>
<div>RelaisSMS</div>
</div>
<nav class="nav">
<button class="active"><span class="ico">✉</span><span>Envoi</span></button>
<button><span class="ico">⌕</span><span>Contacts</span></button>
<button><span class="ico">▦</span><span>Groupes</span></button>
<button><span class="ico">↻</span><span>Sources</span></button>
<button><span class="ico">◷</span><span>Historique</span></button>
<button><span class="ico">⚙</span><span>Paramètres</span></button>
</nav>
<div class="sync-card">
<strong>Dernière synchronisation</strong>
<span>Galette il y a 18 min</span>
<span>CardDAV hier à 21:04</span>
</div>
</aside>
<main class="main">
<header class="topbar">
<div class="title">
<h1>Nouvel envoi SMS</h1>
<p>Connecté avec OVHcloud · 1 284 crédits disponibles</p>
</div>
<div class="actions">
<button class="icon-button" aria-label="Notifications">!</button>
<button class="secondary">↻ Synchroniser</button>
<button class="primary">+ Contact local</button>
</div>
</header>
<section class="layout">
<div>
<section class="panel">
<div class="panel-header">
<h2>Composer</h2>
<div class="tabs" aria-label="Mode d'envoi">
<span class="active">SMS</span>
<span>Modèle</span>
<span>Rappel</span>
</div>
</div>
<div class="composer">
<div class="field">
<label>Destinataires</label>
<div class="search">
<span class="chip group">Bénévoles soirée <button aria-label="Retirer">×</button></span>
<span class="chip">Claire Martin <button aria-label="Retirer">×</button></span>
<span class="chip group">Galette · CA <button aria-label="Retirer">×</button></span>
<span class="placeholder">Rechercher un contact ou un groupe...</span>
</div>
</div>
<div class="suggestions" aria-label="Favoris">
<div class="suggestion">
<strong>★ Encadrants</strong>
<span>18 contacts · local</span>
</div>
<div class="suggestion">
<strong>★ Adhérents actifs</strong>
<span>246 contacts · Galette</span>
</div>
<div class="suggestion">
<strong>★ Urgence bureau</strong>
<span>7 contacts · mixte</span>
</div>
</div>
<div class="field">
<label>Message</label>
<textarea>Bonjour, rappel pour la réunion AFPMA de ce soir à 19h30. Merci de confirmer votre présence si ce n'est pas déjà fait.</textarea>
<div class="meta-row">
<span>127 caractères · encodage GSM-7</span>
<span>1 SMS par destinataire</span>
</div>
</div>
<div class="field">
<label>Planification</label>
<div class="delivery-options">
<div class="delivery-card active">
<strong>Envoyer maintenant</strong>
<span>Départ immédiat après confirmation.</span>
</div>
<div class="delivery-card">
<strong>Programmer</strong>
<span>Demain à 09:00 · modifiable avant envoi.</span>
</div>
</div>
</div>
<div class="compact-summary" aria-label="Résumé avant envoi">
<span class="summary-pill ok">54 numéros valides</span>
<span class="summary-pill">1 SMS / destinataire</span>
<span class="summary-pill warn">3 sans portable</span>
<span class="summary-pill warn">2 refus SMS exclus</span>
<span class="summary-pill">Limite 100 SMS</span>
</div>
<div class="send-row">
<div class="warning">! 5 destinataires exclus avant envoi</div>
<button class="primary">Envoyer 54 SMS</button>
</div>
</div>
</section>
<section class="panel history">
<div class="panel-header">
<h2>Derniers envois</h2>
<button class="secondary">Voir tout</button>
</div>
<table>
<thead>
<tr>
<th>Date</th>
<th>Message</th>
<th>Destinataires</th>
<th>Statut</th>
</tr>
</thead>
<tbody>
<tr>
<td>Aujourd'hui 10:42</td>
<td>Rappel atelier</td>
<td>32</td>
<td><span class="badge">Envoyé</span></td>
</tr>
<tr>
<td>Hier 18:07</td>
<td>Changement de salle</td>
<td>19</td>
<td><span class="badge pending">Partiel</span></td>
</tr>
<tr>
<td>08/06 09:15</td>
<td>Convocation CA</td>
<td>11</td>
<td><span class="badge error">2 erreurs</span></td>
</tr>
</tbody>
</table>
</section>
</div>
</section>
</main>
</div>
</body>
</html>