feat: add lint:fix command to package.json and update French text for consistency across various components

This commit is contained in:
Julien Froidefond
2025-10-12 16:09:31 +02:00
parent ad5d954182
commit 6db4921d0f
27 changed files with 49 additions and 44 deletions

3
.eslintrc.json Normal file
View File

@@ -0,0 +1,3 @@
{
"extends": "next"
}

View File

@@ -18,7 +18,7 @@ export default async function SkillsPage() {
<div className="container mx-auto p-6"> <div className="container mx-auto p-6">
<div className="flex items-center justify-center h-64"> <div className="flex items-center justify-center h-64">
<div className="text-lg text-red-500"> <div className="text-lg text-red-500">
Erreur lors du chargement des données d'administration Erreur lors du chargement des données d&apos;administration
</div> </div>
</div> </div>
</div> </div>

View File

@@ -14,7 +14,7 @@ export default async function TeamsPage() {
<div className="container mx-auto p-6"> <div className="container mx-auto p-6">
<div className="flex items-center justify-center h-64"> <div className="flex items-center justify-center h-64">
<div className="text-lg text-red-500"> <div className="text-lg text-red-500">
Erreur lors du chargement des données d'administration Erreur lors du chargement des données d&apos;administration
</div> </div>
</div> </div>
</div> </div>

View File

@@ -13,7 +13,7 @@ export default async function UsersPage() {
<div className="container mx-auto p-6"> <div className="container mx-auto p-6">
<div className="flex items-center justify-center h-64"> <div className="flex items-center justify-center h-64">
<div className="text-lg text-red-500"> <div className="text-lg text-red-500">
Erreur lors du chargement des données d'administration Erreur lors du chargement des données d&apos;administration
</div> </div>
</div> </div>
</div> </div>

View File

@@ -20,7 +20,7 @@ export default async function AdminPage() {
<div className="container mx-auto p-6"> <div className="container mx-auto p-6">
<div className="flex items-center justify-center h-64"> <div className="flex items-center justify-center h-64">
<div className="text-lg text-red-500"> <div className="text-lg text-red-500">
Erreur lors du chargement des données d'administration Erreur lors du chargement des données d&apos;administration
</div> </div>
</div> </div>
</div> </div>

View File

@@ -27,7 +27,7 @@ export default async function TeamDetailPage({ params }: TeamDetailPageProps) {
return ( return (
<div className="min-h-screen bg-gradient-to-br from-slate-950 via-slate-900 to-slate-950 flex items-center justify-center"> <div className="min-h-screen bg-gradient-to-br from-slate-950 via-slate-900 to-slate-950 flex items-center justify-center">
<div className="text-white text-xl text-red-500"> <div className="text-white text-xl text-red-500">
Erreur lors du chargement des détails de l'équipe Erreur lors du chargement des détails de l&apos;équipe
</div> </div>
</div> </div>
); );

View File

@@ -36,7 +36,7 @@ async function TeamReviewPage() {
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-white/5 border border-white/10 backdrop-blur-sm"> <div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-white/5 border border-white/10 backdrop-blur-sm">
<Users className="h-4 w-4 text-blue-400" /> <Users className="h-4 w-4 text-blue-400" />
<span className="text-sm font-medium text-slate-200"> <span className="text-sm font-medium text-slate-200">
Vue dquipe Vue d&apos;équipe
</span> </span>
</div> </div>
@@ -45,7 +45,7 @@ async function TeamReviewPage() {
</h1> </h1>
<p className="text-slate-400 max-w-2xl mx-auto leading-relaxed"> <p className="text-slate-400 max-w-2xl mx-auto leading-relaxed">
Vue d'ensemble et analyse des compétences de l'équipe{" "} Vue d&apos;ensemble et analyse des compétences de l&apos;équipe{" "}
{teamData.team.direction} {teamData.team.direction}
</p> </p>
</div> </div>

View File

@@ -254,7 +254,7 @@ export function AccountForm({ initialProfile, teams }: AccountFormProps) {
{Object.keys(teamsByDirection).length === 0 && ( {Object.keys(teamsByDirection).length === 0 && (
<div className="px-3 py-4 text-center text-sm text-muted-foreground"> <div className="px-3 py-4 text-center text-sm text-muted-foreground">
Aucune équipe trouvée pour "{searchTerm}" Aucune équipe trouvée pour &quot;{searchTerm}&quot;
</div> </div>
)} )}
</div> </div>

View File

@@ -1,6 +1,6 @@
"use client"; "use client";
import { useState, useEffect } from "react"; import { useState, useEffect, useCallback } from "react";
import { Users, User, Calendar, X, Trash2 } from "lucide-react"; import { Users, User, Calendar, X, Trash2 } from "lucide-react";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
@@ -31,13 +31,7 @@ export function TeamMembersModal({
const [deletingMemberId, setDeletingMemberId] = useState<string | null>(null); const [deletingMemberId, setDeletingMemberId] = useState<string | null>(null);
const { toast } = useToast(); const { toast } = useToast();
useEffect(() => { const fetchMembers = useCallback(async () => {
if (isOpen && teamId) {
fetchMembers();
}
}, [isOpen, teamId]);
const fetchMembers = async () => {
setIsLoading(true); setIsLoading(true);
setError(null); setError(null);
try { try {
@@ -48,7 +42,13 @@ export function TeamMembersModal({
} finally { } finally {
setIsLoading(false); setIsLoading(false);
} }
}; }, [teamId]);
useEffect(() => {
if (isOpen && teamId) {
fetchMembers();
}
}, [isOpen, teamId, fetchMembers]);
const handleRemoveMember = async (memberId: string, memberName: string) => { const handleRemoveMember = async (memberId: string, memberName: string) => {
if ( if (
@@ -91,7 +91,7 @@ export function TeamMembersModal({
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<Users className="w-6 h-6 text-blue-400" /> <Users className="w-6 h-6 text-blue-400" />
<div> <div>
<CardTitle className="text-xl">Membres de l'équipe</CardTitle> <CardTitle className="text-xl">Membres de l&apos;équipe</CardTitle>
<p className="text-sm text-slate-500 font-normal">{teamName}</p> <p className="text-sm text-slate-500 font-normal">{teamName}</p>
</div> </div>
</div> </div>
@@ -137,7 +137,7 @@ export function TeamMembersModal({
Aucun membre dans cette équipe Aucun membre dans cette équipe
</p> </p>
<p className="text-slate-500 text-sm mt-1"> <p className="text-slate-500 text-sm mt-1">
Les membres apparaîtront ici une fois qu'ils seront assignés Les membres apparaîtront ici une fois qu&apos;ils seront assignés
</p> </p>
</div> </div>
) : ( ) : (

View File

@@ -27,7 +27,7 @@ export function TeamDetailHeader({
className="text-slate-400 hover:text-white hover:bg-white/10" className="text-slate-400 hover:text-white hover:bg-white/10"
> >
<ArrowLeft className="h-4 w-4 mr-2" /> <ArrowLeft className="h-4 w-4 mr-2" />
Retour à l'admin Retour à l&apos;admin
</Button> </Button>
<div className="text-slate-400 text-sm">|</div> <div className="text-slate-400 text-sm">|</div>
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">

View File

@@ -116,7 +116,7 @@ export function TeamDetailModal({
</div> </div>
</DialogTitle> </DialogTitle>
<DialogDescription className="text-slate-400"> <DialogDescription className="text-slate-400">
Aperçu rapide de l'équipe. Cliquez sur "Voir tous les détails" pour Aperçu rapide de l&apos;équipe. Cliquez sur &quot;Voir tous les détails&quot; pour
une vue complète. une vue complète.
</DialogDescription> </DialogDescription>
</DialogHeader> </DialogHeader>

View File

@@ -69,7 +69,7 @@ export function TeamDetailTabs({
value="overview" value="overview"
className="data-[state=active]:bg-white/20 data-[state=active]:text-white text-slate-400 hover:text-white transition-colors" className="data-[state=active]:bg-white/20 data-[state=active]:text-white text-slate-400 hover:text-white transition-colors"
> >
Vue d'ensemble Vue d&apos;ensemble
</TabsTrigger> </TabsTrigger>
<TabsTrigger <TabsTrigger
value="skills" value="skills"

View File

@@ -204,7 +204,7 @@ export function TeamInsightsTab({
<div className="bg-white/5 backdrop-blur-sm border border-white/10 rounded-2xl p-6"> <div className="bg-white/5 backdrop-blur-sm border border-white/10 rounded-2xl p-6">
<h3 className="text-lg font-semibold text-white mb-6 flex items-center gap-2"> <h3 className="text-lg font-semibold text-white mb-6 flex items-center gap-2">
<Lightbulb className="h-5 w-5 text-yellow-400" /> <Lightbulb className="h-5 w-5 text-yellow-400" />
Recommandations pour lquipe Recommandations pour l&apos;équipe
</h3> </h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4"> <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="p-4 bg-red-500/10 border border-red-500/20 rounded-xl"> <div className="p-4 bg-red-500/10 border border-red-500/20 rounded-xl">
@@ -219,7 +219,7 @@ export function TeamInsightsTab({
{teamInsights.skillGaps.incontournable > 1 ? "s" : ""}{" "} {teamInsights.skillGaps.incontournable > 1 ? "s" : ""}{" "}
incontournable incontournable
{teamInsights.skillGaps.incontournable > 1 ? "s" : ""} sous {teamInsights.skillGaps.incontournable > 1 ? "s" : ""} sous
l'objectif de {COVERAGE_OBJECTIVES.incontournable}%. l&apos;objectif de {COVERAGE_OBJECTIVES.incontournable}%.
</> </>
) : ( ) : (
<> <>
@@ -239,9 +239,9 @@ export function TeamInsightsTab({
<> <>
Attention: {teamInsights.skillGaps.majeure} compétence Attention: {teamInsights.skillGaps.majeure} compétence
{teamInsights.skillGaps.majeure > 1 ? "s" : ""} majeure {teamInsights.skillGaps.majeure > 1 ? "s" : ""} majeure
{teamInsights.skillGaps.majeure > 1 ? "s" : ""} n'atteigne {teamInsights.skillGaps.majeure > 1 ? "s" : ""} n&apos;atteigne
{teamInsights.skillGaps.majeure > 1 ? "nt" : ""} pas {teamInsights.skillGaps.majeure > 1 ? "nt" : ""} pas
l'objectif de {COVERAGE_OBJECTIVES.majeure}%. l&apos;objectif de {COVERAGE_OBJECTIVES.majeure}%.
</> </>
) : ( ) : (
<> <>

View File

@@ -74,7 +74,7 @@ export function TeamOverviewTab({
<div className="bg-white/5 backdrop-blur-sm border border-white/10 rounded-2xl p-6"> <div className="bg-white/5 backdrop-blur-sm border border-white/10 rounded-2xl p-6">
<h3 className="text-lg font-semibold text-white mb-6 flex items-center gap-2"> <h3 className="text-lg font-semibold text-white mb-6 flex items-center gap-2">
<Star className="h-5 w-5 text-yellow-400" /> <Star className="h-5 w-5 text-yellow-400" />
Top Compétences de lquipe Top Compétences de l&apos;équipe
</h3> </h3>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4"> <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{team.topSkills.slice(0, 6).map((skill, idx) => ( {team.topSkills.slice(0, 6).map((skill, idx) => (
@@ -505,7 +505,7 @@ export function TeamOverviewTab({
</div> </div>
<div className="flex items-center justify-between p-3 bg-white/5 rounded-lg"> <div className="flex items-center justify-between p-3 bg-white/5 rounded-lg">
<span className="text-slate-300">Objectifs d'apprentissage</span> <span className="text-slate-300">Objectifs d&apos;apprentissage</span>
<span className="text-white font-bold"> <span className="text-white font-bold">
{teamInsights.totalLearners} {teamInsights.totalLearners}
</span> </span>

View File

@@ -55,7 +55,7 @@ export function TeamFormDialog({
</DialogHeader> </DialogHeader>
<div className="space-y-4"> <div className="space-y-4">
<div> <div>
<Label htmlFor="team-name">Nom de l'équipe *</Label> <Label htmlFor="team-name">Nom de l&apos;équipe *</Label>
<Input <Input
id="team-name" id="team-name"
value={formData.name} value={formData.name}

View File

@@ -23,7 +23,7 @@ export function AdminHeader() {
<h1 className="text-4xl font-bold text-white">Dashboard Managérial</h1> <h1 className="text-4xl font-bold text-white">Dashboard Managérial</h1>
<p className="text-slate-400 max-w-2xl mx-auto leading-relaxed"> <p className="text-slate-400 max-w-2xl mx-auto leading-relaxed">
Vue d'ensemble des compétences par équipe et direction pour pilotage Vue d&apos;ensemble des compétences par équipe et direction pour pilotage
stratégique stratégique
</p> </p>
@@ -40,7 +40,7 @@ export function AdminHeader() {
}`} }`}
> >
<Building2 className="w-4 h-4 mr-2" /> <Building2 className="w-4 h-4 mr-2" />
Vue d'ensemble Vue d&apos;ensemble
</Button> </Button>
</Link> </Link>
<Link href="/admin/manage"> <Link href="/admin/manage">

View File

@@ -9,7 +9,7 @@ export function ActionSection() {
size="lg" size="lg"
className="bg-blue-500 hover:bg-blue-600 text-white px-8 py-3 rounded-xl" className="bg-blue-500 hover:bg-blue-600 text-white px-8 py-3 rounded-xl"
> >
<Link href="/evaluation">Continuer l'évaluation</Link> <Link href="/evaluation">Continuer l&apos;évaluation</Link>
</Button> </Button>
</div> </div>
); );

View File

@@ -194,7 +194,7 @@ export function MentorSection({
}) })
) : ( ) : (
<p className="text-slate-400 text-sm"> <p className="text-slate-400 text-sm">
Aucun objectif d'apprentissage configuré Aucun objectif d&apos;apprentissage configuré
</p> </p>
)} )}
</div> </div>

View File

@@ -13,7 +13,7 @@ export function RadarSection({ radarData }: RadarSectionProps) {
<div className="bg-white/5 backdrop-blur-sm border border-white/10 rounded-2xl p-6"> <div className="bg-white/5 backdrop-blur-sm border border-white/10 rounded-2xl p-6">
<div className="mb-6"> <div className="mb-6">
<h3 className="text-xl font-bold text-white mb-2"> <h3 className="text-xl font-bold text-white mb-2">
Vue d'ensemble de vos compétences Vue d&apos;ensemble de vos compétences
</h3> </h3>
<p className="text-slate-400 text-sm"> <p className="text-slate-400 text-sm">
Radar chart représentant votre niveau par catégorie Radar chart représentant votre niveau par catégorie

View File

@@ -22,8 +22,8 @@ export function WelcomeScreen() {
Bienvenue ! Commencez votre parcours Bienvenue ! Commencez votre parcours
</h1> </h1>
<p className="text-lg text-slate-400 mb-12 max-w-2xl mx-auto"> <p className="text-lg text-slate-400 mb-12 max-w-2xl mx-auto">
Vous êtes connecté avec succès. Il est temps dvaluer vos Vous êtes connecté avec succès. Il est temps d&apos;évaluer vos
compétences techniques pour obtenir une vue d'ensemble personnalisée compétences techniques pour obtenir une vue d&apos;ensemble personnalisée
de votre expertise. de votre expertise.
</p> </p>
@@ -35,7 +35,7 @@ export function WelcomeScreen() {
Évaluez vos compétences Évaluez vos compétences
</h3> </h3>
<p className="text-slate-400 text-sm"> <p className="text-slate-400 text-sm">
Sélectionnez vos domaines d'expertise et évaluez votre niveau Sélectionnez vos domaines d&apos;expertise et évaluez votre niveau
</p> </p>
</div> </div>
<div className="bg-white/5 border border-white/10 rounded-xl p-6 backdrop-blur-sm"> <div className="bg-white/5 border border-white/10 rounded-xl p-6 backdrop-blur-sm">
@@ -63,7 +63,7 @@ export function WelcomeScreen() {
href="/evaluation" href="/evaluation"
className="group bg-blue-500 hover:bg-blue-600 text-white px-8 py-4 rounded-xl font-medium transition-all inline-flex items-center gap-2" className="group bg-blue-500 hover:bg-blue-600 text-white px-8 py-4 rounded-xl font-medium transition-all inline-flex items-center gap-2"
> >
Commencer l'évaluation Commencer l&apos;évaluation
<ArrowRight className="h-4 w-4 group-hover:translate-x-1 transition-transform" /> <ArrowRight className="h-4 w-4 group-hover:translate-x-1 transition-transform" />
</Link> </Link>
</div> </div>

View File

@@ -148,7 +148,7 @@ export function AuthWrapper({ teams, initialUser }: AuthWrapperProps) {
onClick={() => (window.location.href = "/")} onClick={() => (window.location.href = "/")}
className="px-6 py-3 bg-blue-500 hover:bg-blue-600 text-white rounded-lg" className="px-6 py-3 bg-blue-500 hover:bg-blue-600 text-white rounded-lg"
> >
Aller à l'accueil Aller à l&apos;accueil
</button> </button>
<button <button
onClick={handleLogout} onClick={handleLogout}

View File

@@ -298,7 +298,7 @@ export function RegisterForm({
{Object.keys(teamsByDirection).length === 0 && ( {Object.keys(teamsByDirection).length === 0 && (
<div className="px-3 py-4 text-center text-sm text-slate-400"> <div className="px-3 py-4 text-center text-sm text-slate-400">
Aucune équipe trouvée pour "{searchTerm}" Aucune équipe trouvée pour &quot;{searchTerm}&quot;
</div> </div>
)} )}
</div> </div>

View File

@@ -58,7 +58,8 @@ export function SkillEvaluation({
} else if (categories.length > 0 && !selectedCategory) { } else if (categories.length > 0 && !selectedCategory) {
setSelectedCategory(categories[0].category); setSelectedCategory(categories[0].category);
} }
}, [categoryParam, categories]); // Remove selectedCategory from deps to avoid loop // eslint-disable-next-line react-hooks/exhaustive-deps
}, [categoryParam, categories]); // selectedCategory intentionally excluded to avoid infinite loop
const currentCategory = categories.find( const currentCategory = categories.find(
(cat) => cat.category === selectedCategory (cat) => cat.category === selectedCategory

View File

@@ -236,7 +236,7 @@ export function SkillSelector({
<div className="text-center py-8 text-muted-foreground border-2 border-dashed border-muted rounded-lg"> <div className="text-center py-8 text-muted-foreground border-2 border-dashed border-muted rounded-lg">
<p className="mb-2">Aucune compétence sélectionnée</p> <p className="mb-2">Aucune compétence sélectionnée</p>
<p className="text-sm"> <p className="text-sm">
Cliquez sur "Ajouter une compétence" pour commencer Cliquez sur &quot;Ajouter une compétence&quot; pour commencer
</p> </p>
</div> </div>
)} )}

View File

@@ -92,7 +92,7 @@ export function TeamOverview({
return ( return (
<Card className="bg-white/5 border-white/10 backdrop-blur"> <Card className="bg-white/5 border-white/10 backdrop-blur">
<CardHeader> <CardHeader>
<CardTitle className="text-slate-200">Vue d'ensemble</CardTitle> <CardTitle className="text-slate-200">Vue d&apos;ensemble</CardTitle>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8"> <div className="grid grid-cols-1 md:grid-cols-3 gap-8">

View File

@@ -130,7 +130,7 @@ export function TeamStats({
<Card className="bg-white/5 border-white/10 backdrop-blur"> <Card className="bg-white/5 border-white/10 backdrop-blur">
<CardHeader> <CardHeader>
<CardTitle className="text-slate-200"> <CardTitle className="text-slate-200">
Statistiques de lquipe Statistiques de l&apos;équipe
</CardTitle> </CardTitle>
</CardHeader> </CardHeader>
<CardContent className="space-y-8"> <CardContent className="space-y-8">

View File

@@ -6,6 +6,7 @@
"build": "next build", "build": "next build",
"dev": "next dev --turbopack", "dev": "next dev --turbopack",
"lint": "next lint", "lint": "next lint",
"lint:fix": "next lint --fix",
"start": "next start", "start": "next start",
"generate-test-data": "tsx scripts/generate-test-data.ts", "generate-test-data": "tsx scripts/generate-test-data.ts",
"sync-skills": "tsx scripts/sync-skills.ts", "sync-skills": "tsx scripts/sync-skills.ts",