"use client"
import { useState, useEffect } from "react"
import { useRouter } from "next/navigation"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { ScrollArea } from "@/components/ui/scroll-area"
import { ArrowLeft, Calendar, Database, FileText, Trash2, Clock, Activity, ThumbsUp, LogOut, ArrowRightLeft, Trophy } from "lucide-react"
import Link from "next/link"
import ComparisonChart from "@/components/neurolink/comparison-chart"
// --- CORRECTION ICI : On récupère l'URL du Cloud définie dans Vercel ---
const API_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:8000"
const CircularProgress = ({ value, color, label, icon: Icon }: any) => {
const radius = 30; const circumference = 2 * Math.PI * radius; const offset = circumference - (value / 100) * circumference
return (
)
}
export default function AdminPage() {
const [sessions, setSessions] = useState([])
const [isAuthorized, setIsAuthorized] = useState(false)
const router = useRouter()
const [isCompareMode, setIsCompareMode] = useState(false)
const [sessionA, setSessionA] = useState(null); const [dataA, setDataA] = useState([]); const [statsA, setStatsA] = useState(null)
const [sessionB, setSessionB] = useState(null); const [dataB, setDataB] = useState([]); const [statsB, setStatsB] = useState(null)
useEffect(() => {
const token = localStorage.getItem("startech_admin_token")
if (token !== "authorized_access_granted") { router.push("/admin/login") }
else {
setIsAuthorized(true);
// --- UTILISATION DE L'API CLOUD ---
fetch(`${API_URL}/api/sessions`)
.then(res => res.json())
.then(data => setSessions(data))
.catch(err => console.error("Erreur chargement sessions:", err))
}
}, [])
const handleSelectSession = (sessionId: number) => {
// --- UTILISATION DE L'API CLOUD ---
fetch(`${API_URL}/api/sessions/${sessionId}`).then(res => res.json()).then(response => {
const info = response.info; const data = response.data; const stats = calculateStatsInternal(data)
if (isCompareMode) {
if (!sessionA) { setSessionA(info); setDataA(data); setStatsA(stats) }
else if (!sessionB && sessionId !== sessionA.id) { setSessionB(info); setDataB(data); setStatsB(stats) }
else if (sessionA && sessionB) { setSessionA(info); setDataA(data); setStatsA(stats); setSessionB(null); setDataB([]); setStatsB(null) }
} else { setSessionA(info); setDataA(data); setStatsA(stats); setSessionB(null); setDataB([]); setStatsB(null) }
})
}
const calculateStatsInternal = (data: any[]) => {
if (data.length === 0) return null
const avg = (key: string) => Math.round(data.reduce((acc, curr) => acc + curr[key], 0) / data.length)
return { duration: data.length, avg_engagement: avg('engagement_val'), avg_satisfaction: avg('satisfaction_val'), dominant_label: data[data.length - 1]?.satisfaction_lbl || "N/A" }
}
const toggleCompareMode = () => { setIsCompareMode(!isCompareMode); setSessionB(null); setDataB([]); setStatsB(null) }
const handleDeleteSession = async (e: React.MouseEvent, sessionId: number) => {
e.stopPropagation(); if (!confirm("Supprimer définitivement ?")) return
// --- UTILISATION DE L'API CLOUD ---
const res = await fetch(`${API_URL}/api/sessions/${sessionId}`, { method: 'DELETE' })
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) } }
}
const handleExport = (session: any, data: any) => {
if (!data.length) return
const headers = ["Temps", "Emotion", "Score IA", "Engagement", "Label Engagement", "Satisfaction", "Label Satisfaction", "Confiance", "Fidelite", "Avis"]
const rows = data.map((row: any) => [ String(row.session_time).replace('.', ','), row.emotion, row.emotion_score ? String(row.emotion_score.toFixed(2)).replace('.', ',') : "0", String(row.engagement_val), `"${row.engagement_lbl}"`, String(row.satisfaction_val), `"${row.satisfaction_lbl}"`, String(row.trust_val), String(row.loyalty_val), `"${row.opinion_lbl}"` ])
const csvContent = [headers.join(";"), ...rows.map((e: any) => e.join(";"))].join("\n")
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)
}
const formatDate = (dateStr: string) => {
if (!dateStr) return "Date inconnue";
try { return new Date(dateStr).toLocaleString('fr-FR', { day: 'numeric', month: 'short', hour: '2-digit', minute:'2-digit' }) } catch (e) { return "Erreur date" }
}
if (!isAuthorized) return null
return (
Historique
{sessions.map((session) => {
const isA = sessionA?.id === session.id; const isB = sessionB?.id === session.id
let activeClass = "border-l-4 border-l-transparent"
if (isA) activeClass = "bg-blue-50 border-l-blue-500"; if (isB) activeClass = "bg-orange-50 border-l-orange-500"
return (
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}`}>
{session.first_name} {session.last_name} {isA && A} {isB && B}
{formatDate(session.created_at)}
)
})}
{!isCompareMode && sessionA && statsA && (
{sessionA.first_name} {sessionA.last_name}
Durée: {statsA.duration}s | ID: {sessionA.client_id || "N/A"}
Verdict{statsA.dominant_label}
Analyse Temporelle
Données Brutes Complètes| Temps | Émotion | Score IA | Engagement | Satisfaction | Confiance | Fidélité | Avis |
{dataA.map((row, i) => (| {row.session_time}s | {row.emotion} | {row.emotion_score?.toFixed(1)}% | {row.engagement_val}%{row.engagement_lbl} | 50 ? "text-green-600" : "text-orange-500"}`}>{row.satisfaction_val}%{row.satisfaction_lbl} | {row.trust_val}%{row.trust_lbl} | {row.loyalty_val}%{row.loyalty_lbl} | {row.opinion_lbl} |
))}
)}
{isCompareMode && sessionA && sessionB && statsA && statsB && (
{sessionA.first_name}
Session A
{sessionB.first_name}
Session B
Duel d'Engagement
statsB.avg_engagement ? "bg-blue-50" : ""}`}>{sessionA.first_name}{statsA.avg_engagement > statsB.avg_engagement && Vainqueur} statsA.avg_engagement ? "bg-orange-50" : ""}`}>{sessionB.first_name}{statsB.avg_engagement > statsA.avg_engagement && Vainqueur}
)}
{(!sessionA) &&
Sélectionnez une session à gauche pour commencer.
}
{(isCompareMode && sessionA && !sessionB) &&
Session A : {sessionA.first_name} sélectionnée.
Maintenant, sélectionnez la Session B dans la liste.
}
)
}