diff --git a/src/App.tsx b/src/App.tsx index 938b8ec..c98fd8e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,27 +1,75 @@ -import { Toaster } from "@/components/ui/toaster"; -import { Toaster as Sonner } from "@/components/ui/sonner"; -import { TooltipProvider } from "@/components/ui/tooltip"; -import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; -import { BrowserRouter, Routes, Route } from "react-router-dom"; -import Index from "./pages/Index"; -import NotFound from "./pages/NotFound"; - -const queryClient = new QueryClient(); - -const App = () => ( - - - - - - - } /> - {/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */} - } /> - - - - -); - -export default App; +import { Toaster } from "@/components/ui/toaster"; +import { Toaster as Sonner } from "@/components/ui/sonner"; +import { TooltipProvider } from "@/components/ui/tooltip"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom"; +import { useEffect, useState } from "react"; +import Index from "./pages/Index"; +import Login from "./pages/Login"; +import NotFound from "./pages/NotFound"; + +const queryClient = new QueryClient(); + +// Protected Route Component +const ProtectedRoute = ({ children }: { children: React.ReactNode }) => { + const token = localStorage.getItem("token"); + if (!token) { + return ; + } + return <>{children}; +}; + +const App = () => { + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + // Vérifier le token au démarrage + const token = localStorage.getItem("token"); + if (token) { + // Optionnel: Vérifier la validité du token avec le serveur + fetch("/api/auth/me", { + headers: { + Authorization: `Bearer ${token}`, + }, + }) + .catch(() => { + localStorage.removeItem("token"); + localStorage.removeItem("user"); + }) + .finally(() => { + setIsLoading(false); + }); + } else { + setIsLoading(false); + } + }, []); + + if (isLoading) { + return
Chargement...
; + } + + return ( + + + + + + + } /> + + + + } + /> + } /> + + + + + ); +}; + +export default App; \ No newline at end of file diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index 693bca9..b94263f 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -1,19 +1,118 @@ -// Update this page (the content is just a fallback if you fail to update the page) - -import { MadeWithDyad } from "@/components/made-with-dyad"; - -const Index = () => { - return ( -
-
-

Welcome to Your Blank App

-

- Start building your amazing project here! -

-
- -
- ); -}; - -export default Index; +import { useEffect, useState } from "react"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { showSuccess } from "@/utils/toast"; +import { MadeWithDyad } from "@/components/made-with-dyad"; + +const Index = () => { + const [user, setUser] = useState(null); + const [showAdmin, setShowAdmin] = useState(false); + + useEffect(() => { + const userStr = localStorage.getItem("user"); + if (userStr) { + setUser(JSON.parse(userStr)); + } + }, []); + + const handleLogout = () => { + localStorage.removeItem("token"); + localStorage.removeItem("user"); + showSuccess("Déconnexion réussie"); + window.location.href = "/login"; + }; + + return ( +
+ {/* Top Navigation */} + + + {/* Main Content */} +
+ {/* Sidebar */} + + + {/* Note Editor */} +
+
+ +
+
+
+
+ + {/* Admin Modal */} + {showAdmin && ( +
+
+
+

Administration

+ +
+ {/* Admin content will go here */} +
+
+ )} + + +
+ ); +}; + +export default Index; \ No newline at end of file diff --git a/src/pages/Login.tsx b/src/pages/Login.tsx new file mode 100644 index 0000000..09cb1e0 --- /dev/null +++ b/src/pages/Login.tsx @@ -0,0 +1,78 @@ +import { useState } from "react"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { showError, showSuccess } from "@/utils/toast"; + +const Login = () => { + const [username, setUsername] = useState(""); + const [password, setPassword] = useState(""); + + const handleLogin = async (e: React.FormEvent) => { + e.preventDefault(); + + try { + const response = await fetch("/api/auth/login", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ username, password }), + }); + + const data = await response.json(); + + if (!response.ok) { + throw new Error(data.message || "Erreur de connexion"); + } + + localStorage.setItem("token", data.token); + localStorage.setItem("user", JSON.stringify(data.user)); + showSuccess("Connexion réussie"); + window.location.href = "/"; + } catch (error) { + showError(error instanceof Error ? error.message : "Erreur de connexion"); + } + }; + + return ( +
+ + + Notes App + + +
+
+ + setUsername(e.target.value)} + required + /> +
+
+ + setPassword(e.target.value)} + required + /> +
+ +
+
+
+
+ ); +}; + +export default Login; \ No newline at end of file