diff --git a/.gitea/workflows/pull-request.yml b/.gitea/workflows/pull-request.yml
index c161627..c0f9425 100644
--- a/.gitea/workflows/pull-request.yml
+++ b/.gitea/workflows/pull-request.yml
@@ -73,12 +73,20 @@ jobs:
run: vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --allow-risky=yes --dry-run --diff
- name: Bootstrap test database
+ # Aligne sur la cible `test-db-setup` du makefile : apres
+ # `schema:update --force`, on RECREE manuellement l'index unique
+ # partiel `uq_category_name_type_active` car Doctrine ORM ne sait
+ # pas exprimer les index fonctionnels partiels (LOWER(name) + WHERE
+ # deleted_at IS NULL) et `schema:update` les considere comme
+ # orphelins et les DROP — collisions non detectees, tests d'unicite
+ # qui attendent 409 recoivent 201.
run: |
php bin/console doctrine:database:create --env=test --if-not-exists --no-interaction
php bin/console doctrine:migrations:migrate --env=test --no-interaction
php bin/console doctrine:schema:update --env=test --force --no-interaction
php bin/console doctrine:fixtures:load --env=test --no-interaction
php bin/console app:sync-permissions --env=test --no-interaction
+ php bin/console --env=test dbal:run-sql "CREATE UNIQUE INDEX IF NOT EXISTS uq_category_name_type_active ON category (LOWER(name), category_type_id) WHERE deleted_at IS NULL"
- name: Run PHPUnit
run: php -d memory_limit=512M vendor/bin/phpunit
diff --git a/frontend/i18n/locales/fr.json b/frontend/i18n/locales/fr.json
index a71d4db..77849a7 100644
--- a/frontend/i18n/locales/fr.json
+++ b/frontend/i18n/locales/fr.json
@@ -230,6 +230,39 @@
"updated": "Site mis à jour avec succès",
"deleted": "Site supprimé avec succès"
}
+ },
+ "categories": {
+ "title": "Gestion des catégories",
+ "newCategory": "Ajouter",
+ "editCategory": "Modifier la catégorie",
+ "createCategory": "Créer une catégorie",
+ "viewCategory": "Détail de la catégorie",
+ "noCategories": "Aucune catégorie pour l'instant.",
+ "table": {
+ "name": "Nom",
+ "type": "Type"
+ },
+ "form": {
+ "name": "Nom",
+ "type": "Type de catégorie",
+ "typePlaceholder": "Sélectionner un type"
+ },
+ "validation": {
+ "nameRequired": "Le nom est obligatoire.",
+ "nameLength": "Le nom doit faire entre 2 et 120 caractères.",
+ "typeRequired": "Le type de catégorie est obligatoire."
+ },
+ "delete": {
+ "title": "Supprimer la catégorie",
+ "message": "Êtes-vous sûr de vouloir supprimer la catégorie \"{name}\" ? Cette action est irréversible."
+ },
+ "toast": {
+ "created": "Catégorie créée avec succès",
+ "updated": "Catégorie mise à jour avec succès",
+ "deleted": "Catégorie supprimée avec succès",
+ "duplicate": "Une catégorie nommée « {name} » existe déjà pour ce type.",
+ "typesLoadFailed": "Impossible de charger les types de catégorie. Réessayez."
+ }
}
}
}
diff --git a/frontend/modules/catalog/components/CategoryDeleteModal.vue b/frontend/modules/catalog/components/CategoryDeleteModal.vue
new file mode 100644
index 0000000..5842904
--- /dev/null
+++ b/frontend/modules/catalog/components/CategoryDeleteModal.vue
@@ -0,0 +1,48 @@
+
+
+
+