import { useState } from "react"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import { motion, useReducedMotion } from "framer-motion"; import Box from "@mui/material/Box"; import Typography from "@mui/material/Typography"; import IconButton from "@mui/material/IconButton"; import CircularProgress from "@mui/material/CircularProgress"; import { useAlert } from "../../context/AlertContext"; import { Card, Button, StatusChip, ConfirmDialog } from "../../ui"; import apiFetch from "../../utils/api"; import { formatSessionDate } from "../../utils/dashboardHelpers"; import { sessionsOptions, type Session } from "../../lib/queries/dashboard"; const API_BASE = "/api/admin"; interface DeleteModalState { isOpen: boolean; session: Session | null; } function getDeviceIcon(iconType?: string) { switch (iconType) { case "smartphone": return ( ); case "tablet": return ( ); default: return ( ); } } export default function DashSessions() { const alert = useAlert(); const queryClient = useQueryClient(); const reduce = useReducedMotion(); const { data: sessions = [], isPending: sessionsLoading } = useQuery(sessionsOptions()); const [deleteModal, setDeleteModal] = useState({ isOpen: false, session: null, }); const [deleteAllModal, setDeleteAllModal] = useState(false); const [deleting, setDeleting] = useState(false); const handleDeleteSession = async () => { if (!deleteModal.session) { return; } const sessionId = deleteModal.session.id; setDeleting(true); try { const response = await apiFetch(`${API_BASE}/sessions/${sessionId}`, { method: "DELETE", }); const data = await response.json(); if (data.success) { setDeleteModal({ isOpen: false, session: null }); queryClient.invalidateQueries({ queryKey: ["sessions"] }); alert.success("Relace byla ukončena"); } else { alert.error(data.error || "Nepodařilo se ukončit relaci"); } } catch { alert.error("Chyba připojení"); } finally { setDeleting(false); } }; const handleDeleteAllSessions = async () => { setDeleting(true); try { const response = await apiFetch(`${API_BASE}/sessions?action=all`, { method: "DELETE", }); const data = await response.json(); if (data.success) { setDeleteAllModal(false); queryClient.invalidateQueries({ queryKey: ["sessions"] }); alert.success(data.message || "Ostatní relace byly ukončeny"); } else { alert.error(data.error || "Nepodařilo se ukončit relace"); } } catch { alert.error("Chyba připojení"); } finally { setDeleting(false); } }; return ( <> Přihlášená zařízení {sessions.filter((s) => !s.is_current).length > 0 && ( )} {sessionsLoading ? ( ) : sessions.length === 0 ? ( Žádné aktivní relace ) : ( {sessions.map((session) => ( {getDeviceIcon(session.device_info?.icon)} {session.device_info?.browser} na{" "} {session.device_info?.os} {session.is_current && ( )} {session.ip_address} | {formatSessionDate(session.created_at)} {!session.is_current && ( setDeleteModal({ isOpen: true, session }) } color="error" size="small" title="Ukončit relaci" aria-label="Ukončit relaci" > )} ))} )} setDeleteModal({ isOpen: false, session: null })} onConfirm={handleDeleteSession} title="Ukončit relaci" message={`Opravdu chcete ukončit relaci na zařízení "${deleteModal.session?.device_info?.browser} na ${deleteModal.session?.device_info?.os}"? Toto zařízení bude odhlášeno.`} confirmText="Ukončit" cancelText="Zrušit" confirmVariant="danger" loading={deleting} /> setDeleteAllModal(false)} onConfirm={handleDeleteAllSessions} title="Odhlásit ostatní zařízení" message="Opravdu chcete ukončit všechny ostatní relace? Budete odhlášeni ze všech zařízení kromě tohoto." confirmText="Odhlásit vše" cancelText="Zrušit" confirmVariant="primary" loading={deleting} /> ); }