diff --git a/DataSentinel/src/components/common/KpiCard.jsx b/DataSentinel/src/components/common/KpiCard.jsx
new file mode 100644
index 0000000..c12f4f1
--- /dev/null
+++ b/DataSentinel/src/components/common/KpiCard.jsx
@@ -0,0 +1,10 @@
+import styles from './KpiCard.module.css';
+
+export default function KpiCard({ label, value, color }) {
+ return (
+
+ {value}
+ {label}
+
+ );
+}
diff --git a/DataSentinel/src/components/common/KpiCard.module.css b/DataSentinel/src/components/common/KpiCard.module.css
new file mode 100644
index 0000000..cf8ef75
--- /dev/null
+++ b/DataSentinel/src/components/common/KpiCard.module.css
@@ -0,0 +1,28 @@
+.kpiCard {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: 20px;
+ background: var(--color-white);
+ border-radius: var(--radius);
+ box-shadow: var(--shadow);
+}
+
+.kpiValue {
+ font-size: 36px;
+ font-weight: 700;
+ line-height: 1;
+ margin-bottom: 6px;
+}
+
+.kpiLabel {
+ font-size: 12px;
+ color: var(--color-muted, #888);
+ text-align: center;
+}
+
+@media (max-width: 768px) {
+ .kpiValue {
+ font-size: 28px;
+ }
+}
diff --git a/DataSentinel/src/context/AuthContext.jsx b/DataSentinel/src/context/AuthContext.jsx
index 931718e..aac8a26 100644
--- a/DataSentinel/src/context/AuthContext.jsx
+++ b/DataSentinel/src/context/AuthContext.jsx
@@ -2,16 +2,15 @@
import { createContext, useContext, useState } from 'react';
import * as api from '../services/api';
+import { USER_KEY } from '../services/api';
const AuthContext = createContext(null);
-const STORAGE_KEY = 'ds_user';
-
/* Fournisseur du contexte d'authentification */
export function AuthProvider({ children }) {
const [user, setUser] = useState(() => {
/* Restauration de la session depuis le localStorage au montage */
- const stored = localStorage.getItem(STORAGE_KEY);
+ const stored = localStorage.getItem(USER_KEY);
return stored ? JSON.parse(stored) : null;
});
@@ -19,7 +18,7 @@ export function AuthProvider({ children }) {
async function login(username, password) {
const connectedUser = await api.login(username, password);
setUser(connectedUser);
- localStorage.setItem(STORAGE_KEY, JSON.stringify(connectedUser));
+ localStorage.setItem(USER_KEY, JSON.stringify(connectedUser));
return connectedUser;
}
@@ -27,7 +26,7 @@ export function AuthProvider({ children }) {
function logout() {
api.clearToken();
setUser(null);
- localStorage.removeItem(STORAGE_KEY);
+ localStorage.removeItem(USER_KEY);
}
/* Booléen pratique pour savoir si l'utilisateur est connecté */
diff --git a/DataSentinel/src/hooks/useApi.js b/DataSentinel/src/hooks/useApi.js
deleted file mode 100644
index 7239bb7..0000000
--- a/DataSentinel/src/hooks/useApi.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/* Hook générique pour les appels API : retourne { data, loading, error, refetch } */
-
-import { useState, useEffect, useCallback } from 'react';
-
-/**
- * @param {Function} fetchFn - Fonction async à appeler (depuis api.js)
- * @param {Array} deps - Dépendances qui déclenchent un re-fetch (optionnel)
- */
-export function useApi(fetchFn, deps = []) {
- const [data, setData] = useState(null);
- const [loading, setLoading] = useState(true);
- const [error, setError] = useState(null);
-
- const fetch = useCallback(async () => {
- setLoading(true);
- setError(null);
- try {
- const result = await fetchFn();
- setData(result);
- } catch (err) {
- setError(err.message || 'Une erreur est survenue.');
- } finally {
- setLoading(false);
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, deps);
-
- useEffect(() => {
- fetch();
- }, [fetch]);
-
- return { data, loading, error, refetch: fetch };
-}
diff --git a/DataSentinel/src/pages/Dashboard/Dashboard.jsx b/DataSentinel/src/pages/Dashboard/Dashboard.jsx
index 79c30e2..979484a 100644
--- a/DataSentinel/src/pages/Dashboard/Dashboard.jsx
+++ b/DataSentinel/src/pages/Dashboard/Dashboard.jsx
@@ -4,20 +4,11 @@ import { useState, useEffect, useCallback, useMemo } from 'react';
import { RefreshCw } from 'lucide-react';
import { getDashboard, getDashboardSummary, getDashboardFiltres } from '../../services/api';
import MonitoringCard from '../../components/common/MonitoringCard';
+import KpiCard from '../../components/common/KpiCard';
import LoadingSpinner from '../../components/common/LoadingSpinner';
import ErrorMessage from '../../components/common/ErrorMessage';
import styles from './Dashboard.module.css';
-/* Carte KPI affichant un indicateur clé */
-function KpiCard({ label, value, color }) {
- return (
-
- {value}
- {label}
-
- );
-}
-
export default function Dashboard() {
const [summary, setSummary] = useState(null);
const [monitorings, setMonitorings] = useState([]);
diff --git a/DataSentinel/src/pages/Dashboard/Dashboard.module.css b/DataSentinel/src/pages/Dashboard/Dashboard.module.css
index 4469834..7113e81 100644
--- a/DataSentinel/src/pages/Dashboard/Dashboard.module.css
+++ b/DataSentinel/src/pages/Dashboard/Dashboard.module.css
@@ -55,29 +55,6 @@
margin-bottom: 32px;
}
-.kpiCard {
- display: flex;
- flex-direction: column;
- align-items: center;
- padding: 20px;
- background: var(--color-white);
- border-radius: var(--radius);
- box-shadow: var(--shadow);
-}
-
-.kpiValue {
- font-size: 36px;
- font-weight: 700;
- line-height: 1;
- margin-bottom: 6px;
-}
-
-.kpiLabel {
- font-size: 12px;
- color: var(--color-muted, #888);
- text-align: center;
-}
-
.filtres {
display: flex;
gap: 12px;
@@ -131,10 +108,6 @@
gap: 10px;
}
- .kpiValue {
- font-size: 28px;
- }
-
.filtres {
flex-direction: column;
}