diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e11bfc9 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,26 @@ +# Changelog - Calendrier de l'Avent + +## [v1.0.0] - 2025-12-02 - Release complète + +### ✨ **Nouvelles fonctionnalités** +- **Multi-projets** : Gestion indépendante de plusieurs calendriers +- **Upload images** : Illustration personnalisée par projet (PNG/JPG/GIF) +- **Page publique** : Accès sans login `/public` et `/public/project/1` +- **Tirage catchup** : Rattrapage automatique des jours manqués +- **Import CSV UTF-8** : Accents + espaces internes préservés +- **Calcul quota auto** : `max_draws = ceil(total_days / nb_personnes)` +- **Thème Noël** : Design festif + animations +- **Docker 1-clic** : `./restart.sh` + +### 🐛 **Corrections** +- Fix `url_for('index')` → `url_for('dashboard')` +- Upload images : conservation image existante si pas modifiée +- CSV : `utf-8-sig` + strip bords seulement (espaces internes OK) + +### 📱 **Interface** +- **Public** : Liste projets + vue calendrier (lecture seule) +- **Admin** : Projets + utilisateurs/projet + upload images +- **Responsive** : Mobile/Desktop/Tablet + +### 🚀 **Accès** + diff --git a/app.py b/app.py index 62b64d0..c966cce 100644 --- a/app.py +++ b/app.py @@ -334,21 +334,31 @@ def admin_project_people(project_id): if 'csv_file' in request.files: csv_file = request.files['csv_file'] if csv_file.filename: - content = csv_file.read().decode('utf-8') + # Lecture UTF-8 avec gestion BOM + content = csv_file.read().decode('utf-8-sig') reader = csv.DictReader(StringIO(content)) count = 0 for row in reader: - name = row.get("name", "").strip() - if name: - cur = db.execute("SELECT id FROM people WHERE name = ? AND project_id = ?", - (name, project_id)) + # CONSERVE les espaces INTERNES, supprime SEULEMENT avant/après + raw_name = row.get("name", "").strip() # UNIQUEMENT les bords + if raw_name: + # Pas de .title() pour conserver la casse exacte + name = raw_name # ESPACES INTERNES préservés ! + + # Vérifier doublons exacts (espaces inclus) + cur = db.execute( + "SELECT id FROM people WHERE name = ? AND project_id = ?", + (name, project_id) + ) if not cur.fetchone(): - db.execute("INSERT INTO people (project_id, name, draws, max_draws) VALUES (?, ?, 0, 0)", - (project_id, name)) + db.execute( + "INSERT INTO people (project_id, name, draws, max_draws) VALUES (?, ?, 0, 0)", + (project_id, name) + ) count += 1 recalc_max_draws_for_project(project_id) db.commit() - flash(f"{count} personnes importées depuis le CSV.") + flash(f"✅ {count} personnes importées (espaces + accents préservés !)") elif action == "delete": person_id = int(request.form.get("person_id")) db.execute("DELETE FROM people WHERE id = ? AND project_id = ?", (person_id, project_id))