diff --git a/.env.example b/.env.example
index 20331f4..c779814 100644
--- a/.env.example
+++ b/.env.example
@@ -36,3 +36,11 @@ APP_DOMAIN=octane.dandrove.com
# Only used by docker-compose.dev.yml (local testing without Traefik)
APP_PORT=3000
+
+# Optional — auto-fill YouTube/Spotify links when adding a song from the
+# title/artist autocomplete (which itself needs no key, it uses Apple's free
+# iTunes Search API). Leave blank to skip auto-fill and enter links by hand;
+# see README "Recherche automatique de morceaux" for how to obtain these.
+SPOTIFY_CLIENT_ID=
+SPOTIFY_CLIENT_SECRET=
+YOUTUBE_API_KEY=
diff --git a/README.md b/README.md
index fec1ae2..78eb684 100644
--- a/README.md
+++ b/README.md
@@ -237,7 +237,7 @@ erDiagram
| Page | Accès | Description |
|---|---|---|
-| `/index.html` | Tous (lecture et écriture) | Répertoire des morceaux travaillés, liens/vignettes YouTube et Spotify, tutos embarqués par morceau et par instrument |
+| `/index.html` | Tous (lecture et écriture) | Répertoire des morceaux travaillés, liens/vignettes YouTube et Spotify, tutos embarqués par morceau et par instrument. Ajout avec autocomplete titre/artiste + liens auto-trouvés ([détails](#recherche-automatique-de-morceaux)) |
| `/suggestions.html` | Tous | Proposer un morceau (avec lien YouTube embarqué + note libre), voter approuver/rejeter avec commentaire, attribué nominativement |
| `/setlist.html` | Tous (lecture et écriture) | Setlist du prochain concert : choix des morceaux du répertoire, ordre, notes, section rappel |
| `/history.html`, `/history-detail.html` | Tous (lecture seule) | Historique des setlists des concerts passés |
@@ -254,6 +254,21 @@ Un bouton clair/sombre dans la barre de navigation permet de forcer un thème (m
Le rôle admin n'est volontairement pas plus étendu pour l'instant : son périmètre exact (au-delà de la modération des suggestions) reste ouvert et pourra évoluer. Il n'y a pas de gestion des utilisateurs dans l'application elle-même — Authentik reste la seule source de vérité pour qui a accès et qui est admin (claim `groups`, recalculé à chaque connexion).
+## Recherche automatique de morceaux
+
+En tapant un titre dans le formulaire "Ajouter un morceau" du répertoire, une liste de suggestions apparaît (titre, artiste, pochette), basée sur l'[iTunes Search API](https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/iTuneSearchAPI/) d'Apple — **gratuite, sans clé, sans inscription**, donc ça fonctionne dès le premier déploiement sans rien configurer.
+
+En sélectionnant une suggestion, l'app tente aussi de retrouver automatiquement les liens **YouTube** et **Spotify** correspondants. Ça, en revanche, nécessite des identifiants (facultatifs) :
+
+| Variable | Obtenir | Sans elle |
+|---|---|---|
+| `YOUTUBE_API_KEY` | [Google Cloud Console](https://console.cloud.google.com/) → activer "YouTube Data API v3" → créer une clé API (quota gratuit largement suffisant pour un groupe) | Le champ lien YouTube reste vide, saisie manuelle |
+| `SPOTIFY_CLIENT_ID` / `SPOTIFY_CLIENT_SECRET` | [Spotify for Developers](https://developer.spotify.com/dashboard) → créer une app → Client ID/Secret (flux "Client Credentials", pas de compte utilisateur impliqué) | Le champ lien Spotify reste vide, saisie manuelle |
+
+Si aucune des deux n'est configurée, l'autocomplete titre/artiste marche quand même — seuls les liens ne se remplissent pas tout seuls. Vous pouvez ajouter ces clés à tout moment dans `.env` sans changement de code, juste un redémarrage du conteneur `app`.
+
+Si la recherche ne trouve rien (morceau trop obscur, faute de frappe...), rien ne bloque : titre, artiste et liens restent modifiables à la main comme avant.
+
## Prérequis
- Docker + Docker Compose
diff --git a/public/css/style.css b/public/css/style.css
index 810cb4e..c76c0d0 100644
--- a/public/css/style.css
+++ b/public/css/style.css
@@ -289,6 +289,17 @@ h3 { font-size: 1rem; margin: 0 0 0.5rem; }
margin: 0 0 1.5rem;
}
+.section-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 1rem;
+ flex-wrap: wrap;
+ margin: 2.25rem 0 0.75rem;
+}
+
+.section-header h2 { margin: 0; }
+
/* ---------- Cards / grids ---------- */
.card-grid {
@@ -491,6 +502,56 @@ form.stacked-form label {
gap: 0.3rem;
}
+/* ---------- Title autocomplete (add song) ---------- */
+
+.autocomplete-wrapper { position: relative; }
+
+.autocomplete-dropdown {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ right: 0;
+ margin-top: 0.25rem;
+ background: var(--surface);
+ border: 1px solid var(--border);
+ border-radius: var(--radius-sm);
+ box-shadow: var(--shadow);
+ max-height: 260px;
+ overflow-y: auto;
+ z-index: 30;
+}
+
+.autocomplete-item {
+ display: flex;
+ align-items: center;
+ gap: 0.6rem;
+ padding: 0.45rem 0.6rem;
+ cursor: pointer;
+ font-size: 0.85rem;
+}
+
+.autocomplete-item:hover,
+.autocomplete-item.active {
+ background: var(--surface-alt);
+}
+
+.autocomplete-item img,
+.autocomplete-thumb-placeholder {
+ width: 32px;
+ height: 32px;
+ border-radius: 6px;
+ object-fit: cover;
+ flex: 0 0 auto;
+}
+
+.autocomplete-thumb-placeholder {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: var(--surface-alt);
+ color: var(--muted);
+}
+
input, select, textarea {
font: inherit;
padding: 0.5rem 0.65rem;
diff --git a/public/index.html b/public/index.html
index d4fcf61..c173057 100644
--- a/public/index.html
+++ b/public/index.html
@@ -16,19 +16,28 @@
Les morceaux travaillés par le groupe, avec liens d'écoute et tutos par instrument.