From e32e3b8bc0552f2378ad10a46d1839b47f697941 Mon Sep 17 00:00:00 2001 From: Julien Froidefond Date: Thu, 21 Aug 2025 12:00:44 +0200 Subject: [PATCH] refactor: remove ProfileForm and update loading state display - Removed the ProfileForm component from HomePage, simplifying the UI during loading. - Added a loading spinner and message to indicate redirection to the login page, enhancing user experience. --- app/login/page.tsx | 113 +++++++++++++++++++++++++++++++++++++++++++++ app/page.tsx | 22 ++++----- middleware.ts | 54 ++++++++++++++++++++++ 3 files changed, 175 insertions(+), 14 deletions(-) create mode 100644 app/login/page.tsx create mode 100644 middleware.ts diff --git a/app/login/page.tsx b/app/login/page.tsx new file mode 100644 index 0000000..6e2fc77 --- /dev/null +++ b/app/login/page.tsx @@ -0,0 +1,113 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { useRouter } from "next/navigation"; +import { ProfileForm } from "@/components/profile-form"; +import { AuthService } from "@/lib/auth-utils"; +import { UserProfile, Team } from "@/lib/types"; +import { Code2 } from "lucide-react"; + +interface LoginPageProps {} + +export default function LoginPage({}: LoginPageProps) { + const [teams, setTeams] = useState([]); + const [loading, setLoading] = useState(true); + const [authenticating, setAuthenticating] = useState(false); + const router = useRouter(); + + useEffect(() => { + async function initialize() { + try { + // Vérifier si l'utilisateur est déjà connecté + const currentUser = await AuthService.getCurrentUser(); + if (currentUser) { + router.push("/"); + return; + } + + // Charger les équipes + const teamsResponse = await fetch("/api/teams"); + if (teamsResponse.ok) { + const teamsData = await teamsResponse.json(); + setTeams(teamsData); + } + } catch (error) { + console.error("Error initializing login page:", error); + } finally { + setLoading(false); + } + } + + initialize(); + }, [router]); + + const handleSubmit = async (profile: UserProfile) => { + setAuthenticating(true); + try { + await AuthService.login(profile); + router.push("/"); + } catch (error) { + console.error("Login failed:", error); + // Vous pouvez ajouter une notification d'erreur ici + } finally { + setAuthenticating(false); + } + }; + + if (loading) { + return ( +
+
+
+ +
+
+
+
+

Chargement...

+
+
+
+
+ ); + } + + return ( +
+
+
+ +
+
+
+ + + PeakSkills + +
+ +

+ Bienvenue sur PeakSkills +

+

+ Évaluez vos compétences techniques et suivez votre progression +

+
+ +
+
+ {authenticating && ( +
+
+
+

Connexion en cours...

+
+
+ )} + +
+
+
+
+ ); +} diff --git a/app/page.tsx b/app/page.tsx index 1bbec66..7818270 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -2,7 +2,6 @@ import { useEffect, useState } from "react"; import { useEvaluation } from "@/hooks/use-evaluation"; -import { ProfileForm } from "@/components/profile-form"; import { SkillsRadarChart } from "@/components/radar-chart"; import { Card, @@ -58,8 +57,7 @@ function getScoreColors(score: number) { } export default function HomePage() { - const { userEvaluation, skillCategories, teams, loading, updateProfile } = - useEvaluation(); + const { userEvaluation, skillCategories, teams, loading } = useEvaluation(); const { setUserInfo } = useUser(); const [expandedCategory, setExpandedCategory] = useState(null); @@ -104,17 +102,13 @@ export default function HomePage() {
-
-

- Bienvenue sur PeakSkills -

-

- Évaluez vos compétences techniques et suivez votre progression -

-
- -
- +
+
+
+

+ Redirection vers la page de connexion... +

+
diff --git a/middleware.ts b/middleware.ts new file mode 100644 index 0000000..aef0438 --- /dev/null +++ b/middleware.ts @@ -0,0 +1,54 @@ +import { NextRequest, NextResponse } from "next/server"; + +const COOKIE_NAME = "peakSkills_userId"; + +export function middleware(request: NextRequest) { + const { pathname } = request.nextUrl; + + // Pages qui ne nécessitent pas d'authentification + const publicPaths = ["/login"]; + + // Pages API qui ne nécessitent pas d'authentification + const publicApiPaths = ["/api/auth", "/api/teams"]; + + // Vérifier si c'est une route publique + if ( + publicPaths.includes(pathname) || + publicApiPaths.some((path) => pathname.startsWith(path)) + ) { + return NextResponse.next(); + } + + // Vérifier si c'est un fichier statique + if ( + pathname.includes("/_next/") || + pathname.includes("/favicon.ico") || + pathname.includes("/public/") + ) { + return NextResponse.next(); + } + + // Vérifier le cookie d'authentification + const userId = request.cookies.get(COOKIE_NAME)?.value; + + if (!userId) { + // Rediriger vers la page de login si pas authentifié + const loginUrl = new URL("/login", request.url); + return NextResponse.redirect(loginUrl); + } + + return NextResponse.next(); +} + +export const config = { + matcher: [ + /* + * Match all request paths except for the ones starting with: + * - api (API routes) + * - _next/static (static files) + * - _next/image (image optimization files) + * - favicon.ico (favicon file) + */ + "/((?!_next/static|_next/image|favicon.ico).*)", + ], +};