feat(client-portal) : portal front + client account admin (phases 1-2 front)

LST-69 (3.2) front. Client portal UI on the phase-1 backend.

- New frontend/modules/client-portal/ layer: /portal (project cards from the
  client's allowedProjects via /me), /portal/projects/[id] (tickets list,
  detail modal, create modal with document upload), client-tickets service +
  DTO, CT-XXX formatting.
- Front tenancy: auth.global.ts redirects a pure ROLE_CLIENT to /portal and
  blocks internal routes; portal pages open to any authenticated user.
- Admin: UserDrawer manages client accounts (ROLE_CLIENT + client +
  allowedProjects); new "Tickets client" admin tab (list, filters, status
  change with required comment on reject, detail modal).
- Kanban/my-tasks: client-ticket icon + tooltip when task.clientTicket is set
  (data via task:read, no extra call). TaskDocument upload generalized with a
  clientTicketId prop. getContent uses native fetch (text response).
- i18n portal/clientTicket keys; sidebar /portal item (module client-portal).

nuxt build passes; /portal routes present, existing routes intact.
This commit is contained in:
Matthieu
2026-06-21 01:03:58 +02:00
parent a2bbc8311d
commit 144a8a4685
24 changed files with 1189 additions and 29 deletions
+53 -3
View File
@@ -193,7 +193,10 @@
"updated": "Utilisateur mis à jour avec succès.",
"deleted": "Utilisateur supprimé avec succès.",
"addUser": "Ajouter un utilisateur",
"editUser": "Modifier un utilisateur"
"editUser": "Modifier un utilisateur",
"clientAccount": "Compte client (portail)",
"client": "Client",
"allowedProjects": "Projets autorisés"
},
"admin": {
"roles": {
@@ -354,7 +357,8 @@
"myTasks": "Mes tâches",
"projects": "Projets",
"timeTracking": "Suivi de temps",
"mail": "Messagerie"
"mail": "Messagerie",
"portal": "Portail client"
},
"admin": {
"section": "Administration",
@@ -423,7 +427,9 @@
"thisWeek": "Cette semaine",
"clear": "Effacer",
"day": "Jour",
"weekShort": "Sem."
"weekShort": "Sem.",
"submit": "Soumettre",
"close": "Fermer"
},
"gitea": {
"settings": {
@@ -943,5 +949,49 @@
"empty": "Aucun prospect trouvé.",
"allStatuses": "Tous les statuts"
}
},
"portal": {
"title": "Portail client",
"projects": "Mes projets",
"openTickets": "tickets ouverts",
"newTicket": "Nouveau ticket",
"ticketDetail": "Détail du ticket",
"noProjects": "Aucun projet accessible.",
"noTickets": "Aucun ticket pour le moment."
},
"clientTicket": {
"typeLabel": "Type",
"type": {
"bug": "Bug",
"improvement": "Amélioration",
"other": "Autre"
},
"status": {
"label": "Statut",
"new": "Nouveau",
"in_progress": "En cours",
"done": "Terminé",
"rejected": "Rejeté"
},
"title": "Titre",
"titleRequired": "Le titre est requis",
"description": "Description",
"descriptionRequired": "La description est requise",
"url": "URL (page concernée)",
"statusComment": "Commentaire de statut",
"project": "Projet",
"submittedBy": "Soumis par",
"date": "Date",
"created": "Ticket créé",
"statusChanged": "Statut mis à jour",
"confirmDelete": "Supprimer ce ticket ?",
"deleted": "Ticket supprimé",
"linkedTooltip": "Lié au ticket client {number}",
"rejectionRequired": "Un commentaire est requis pour rejeter un ticket",
"changeStatus": "Changer le statut",
"adminTab": "Tickets client",
"adminTitle": "Tickets client",
"filterProject": "Projet",
"filterStatus": "Statut"
}
}