Spaces:
Running
Running
Commit
·
89ff6a0
1
Parent(s):
5ddbc46
Fix Admin API URL
Browse files- app/admin/page.tsx +16 -8
app/admin/page.tsx
CHANGED
|
@@ -10,6 +10,9 @@ import { ArrowLeft, Calendar, Database, FileText, Trash2, Clock, Activity, Thumb
|
|
| 10 |
import Link from "next/link"
|
| 11 |
import ComparisonChart from "@/components/neurolink/comparison-chart"
|
| 12 |
|
|
|
|
|
|
|
|
|
|
| 13 |
const CircularProgress = ({ value, color, label, icon: Icon }: any) => {
|
| 14 |
const radius = 30; const circumference = 2 * Math.PI * radius; const offset = circumference - (value / 100) * circumference
|
| 15 |
return (
|
|
@@ -37,11 +40,19 @@ export default function AdminPage() {
|
|
| 37 |
useEffect(() => {
|
| 38 |
const token = localStorage.getItem("startech_admin_token")
|
| 39 |
if (token !== "authorized_access_granted") { router.push("/admin/login") }
|
| 40 |
-
else {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
}, [])
|
| 42 |
|
| 43 |
const handleSelectSession = (sessionId: number) => {
|
| 44 |
-
|
|
|
|
| 45 |
const info = response.info; const data = response.data; const stats = calculateStatsInternal(data)
|
| 46 |
if (isCompareMode) {
|
| 47 |
if (!sessionA) { setSessionA(info); setDataA(data); setStatsA(stats) }
|
|
@@ -59,7 +70,8 @@ export default function AdminPage() {
|
|
| 59 |
const toggleCompareMode = () => { setIsCompareMode(!isCompareMode); setSessionB(null); setDataB([]); setStatsB(null) }
|
| 60 |
const handleDeleteSession = async (e: React.MouseEvent, sessionId: number) => {
|
| 61 |
e.stopPropagation(); if (!confirm("Supprimer définitivement ?")) return
|
| 62 |
-
|
|
|
|
| 63 |
if (res.ok) { setSessions(prev => prev.filter(s => s.id !== sessionId)); if (sessionA?.id === sessionId) { setSessionA(null); setDataA([]); setStatsA(null) }; if (sessionB?.id === sessionId) { setSessionB(null); setDataB([]); setStatsB(null) } }
|
| 64 |
}
|
| 65 |
const handleExport = (session: any, data: any) => {
|
|
@@ -70,12 +82,9 @@ export default function AdminPage() {
|
|
| 70 |
const blob = new Blob(["\uFEFF" + csvContent], { type: "text/csv;charset=utf-8;" }); const link = document.createElement("a"); link.href = URL.createObjectURL(blob); link.setAttribute("download", `Rapport_${session.first_name}.csv`); document.body.appendChild(link); link.click(); document.body.removeChild(link)
|
| 71 |
}
|
| 72 |
|
| 73 |
-
// CORRECTION DE LA DATE ICI : On gère created_at de Supabase
|
| 74 |
const formatDate = (dateStr: string) => {
|
| 75 |
if (!dateStr) return "Date inconnue";
|
| 76 |
-
try {
|
| 77 |
-
return new Date(dateStr).toLocaleString('fr-FR', { day: 'numeric', month: 'short', hour: '2-digit', minute:'2-digit' })
|
| 78 |
-
} catch (e) { return "Erreur date" }
|
| 79 |
}
|
| 80 |
|
| 81 |
if (!isAuthorized) return null
|
|
@@ -106,7 +115,6 @@ export default function AdminPage() {
|
|
| 106 |
<div key={session.id} onClick={() => handleSelectSession(session.id)} className={`group flex items-center justify-between p-4 border-b border-slate-100 hover:bg-slate-50 cursor-pointer transition-all ${activeClass}`}>
|
| 107 |
<div>
|
| 108 |
<div className="font-bold flex items-center gap-2 text-slate-800">{session.first_name} {session.last_name} {isA && <Badge className="bg-blue-500 h-4 px-1 text-[9px]">A</Badge>} {isB && <Badge className="bg-orange-500 h-4 px-1 text-[9px]">B</Badge>}</div>
|
| 109 |
-
{/* CORRECTION ICI : created_at au lieu de start_time */}
|
| 110 |
<div className="text-xs text-slate-500 mt-1 flex items-center gap-2"><Calendar className="w-3 h-3" /> {formatDate(session.created_at)}</div>
|
| 111 |
</div>
|
| 112 |
<Button variant="ghost" size="icon" className="h-8 w-8 text-slate-400 opacity-0 group-hover:opacity-100" onClick={(e) => handleDeleteSession(e, session.id)}><Trash2 className="w-4 h-4 hover:text-red-500" /></Button>
|
|
|
|
| 10 |
import Link from "next/link"
|
| 11 |
import ComparisonChart from "@/components/neurolink/comparison-chart"
|
| 12 |
|
| 13 |
+
// --- CORRECTION ICI : On récupère l'URL du Cloud définie dans Vercel ---
|
| 14 |
+
const API_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000"
|
| 15 |
+
|
| 16 |
const CircularProgress = ({ value, color, label, icon: Icon }: any) => {
|
| 17 |
const radius = 30; const circumference = 2 * Math.PI * radius; const offset = circumference - (value / 100) * circumference
|
| 18 |
return (
|
|
|
|
| 40 |
useEffect(() => {
|
| 41 |
const token = localStorage.getItem("startech_admin_token")
|
| 42 |
if (token !== "authorized_access_granted") { router.push("/admin/login") }
|
| 43 |
+
else {
|
| 44 |
+
setIsAuthorized(true);
|
| 45 |
+
// --- UTILISATION DE L'API CLOUD ---
|
| 46 |
+
fetch(`${API_URL}/api/sessions`)
|
| 47 |
+
.then(res => res.json())
|
| 48 |
+
.then(data => setSessions(data))
|
| 49 |
+
.catch(err => console.error("Erreur chargement sessions:", err))
|
| 50 |
+
}
|
| 51 |
}, [])
|
| 52 |
|
| 53 |
const handleSelectSession = (sessionId: number) => {
|
| 54 |
+
// --- UTILISATION DE L'API CLOUD ---
|
| 55 |
+
fetch(`${API_URL}/api/sessions/${sessionId}`).then(res => res.json()).then(response => {
|
| 56 |
const info = response.info; const data = response.data; const stats = calculateStatsInternal(data)
|
| 57 |
if (isCompareMode) {
|
| 58 |
if (!sessionA) { setSessionA(info); setDataA(data); setStatsA(stats) }
|
|
|
|
| 70 |
const toggleCompareMode = () => { setIsCompareMode(!isCompareMode); setSessionB(null); setDataB([]); setStatsB(null) }
|
| 71 |
const handleDeleteSession = async (e: React.MouseEvent, sessionId: number) => {
|
| 72 |
e.stopPropagation(); if (!confirm("Supprimer définitivement ?")) return
|
| 73 |
+
// --- UTILISATION DE L'API CLOUD ---
|
| 74 |
+
const res = await fetch(`${API_URL}/api/sessions/${sessionId}`, { method: 'DELETE' })
|
| 75 |
if (res.ok) { setSessions(prev => prev.filter(s => s.id !== sessionId)); if (sessionA?.id === sessionId) { setSessionA(null); setDataA([]); setStatsA(null) }; if (sessionB?.id === sessionId) { setSessionB(null); setDataB([]); setStatsB(null) } }
|
| 76 |
}
|
| 77 |
const handleExport = (session: any, data: any) => {
|
|
|
|
| 82 |
const blob = new Blob(["\uFEFF" + csvContent], { type: "text/csv;charset=utf-8;" }); const link = document.createElement("a"); link.href = URL.createObjectURL(blob); link.setAttribute("download", `Rapport_${session.first_name}.csv`); document.body.appendChild(link); link.click(); document.body.removeChild(link)
|
| 83 |
}
|
| 84 |
|
|
|
|
| 85 |
const formatDate = (dateStr: string) => {
|
| 86 |
if (!dateStr) return "Date inconnue";
|
| 87 |
+
try { return new Date(dateStr).toLocaleString('fr-FR', { day: 'numeric', month: 'short', hour: '2-digit', minute:'2-digit' }) } catch (e) { return "Erreur date" }
|
|
|
|
|
|
|
| 88 |
}
|
| 89 |
|
| 90 |
if (!isAuthorized) return null
|
|
|
|
| 115 |
<div key={session.id} onClick={() => handleSelectSession(session.id)} className={`group flex items-center justify-between p-4 border-b border-slate-100 hover:bg-slate-50 cursor-pointer transition-all ${activeClass}`}>
|
| 116 |
<div>
|
| 117 |
<div className="font-bold flex items-center gap-2 text-slate-800">{session.first_name} {session.last_name} {isA && <Badge className="bg-blue-500 h-4 px-1 text-[9px]">A</Badge>} {isB && <Badge className="bg-orange-500 h-4 px-1 text-[9px]">B</Badge>}</div>
|
|
|
|
| 118 |
<div className="text-xs text-slate-500 mt-1 flex items-center gap-2"><Calendar className="w-3 h-3" /> {formatDate(session.created_at)}</div>
|
| 119 |
</div>
|
| 120 |
<Button variant="ghost" size="icon" className="h-8 w-8 text-slate-400 opacity-0 group-hover:opacity-100" onClick={(e) => handleDeleteSession(e, session.id)}><Trash2 className="w-4 h-4 hover:text-red-500" /></Button>
|