import React, { useEffect, useState, useCallback } from 'react';
import {
Box, Typography, Button, CircularProgress, Alert, Chip,
Table, TableHead, TableBody, TableRow, TableCell,
Card, CardContent, Grid, IconButton, Tooltip,
} from '@mui/material';
import { Refresh, School, People, EventNote, HourglassEmpty } from '@mui/icons-material';
import { useNavigate } from 'react-router';
import { useAuth } from '../../contexts/AuthContext';
const API_BASE = import.meta.env.VITE_API_BASE || import.meta.env.VITE_API_URL || '/api';
interface SchoolEntry {
id: string;
name: string;
urn: string | null;
website: string | null;
status: string;
created_at: string;
neo4j_uuid_string: string | null;
staff_count: number;
student_count: number;
has_calendar: boolean;
pending_invitations: number;
}
interface Stats {
schools: number;
profiles: number;
taught_lessons: number;
pending_invitations: number;
}
function StatCard({ label, value, icon: Icon }: { label: string; value: number; icon: React.ElementType }) {
return (
{value}
{label}
);
}
const PlatformAdminPage: React.FC = () => {
const { accessToken } = useAuth();
const navigate = useNavigate();
const [schools, setSchools] = useState([]);
const [stats, setStats] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const headers = { Authorization: `Bearer ${accessToken}` };
const loadData = useCallback(async () => {
if (!accessToken) return;
setLoading(true);
setError(null);
try {
const [schoolsRes, statsRes] = await Promise.all([
fetch(`${API_BASE}/admin/schools`, { headers }).then(r => r.json()),
fetch(`${API_BASE}/admin/stats`, { headers }).then(r => r.json()),
]);
if (schoolsRes.status === 'ok') setSchools(schoolsRes.schools || []);
else setError(schoolsRes.detail || 'Failed to load schools');
if (statsRes.status === 'ok') setStats(statsRes);
} catch (e: any) {
setError(e.message);
} finally {
setLoading(false);
}
}, [accessToken]);
useEffect(() => { loadData(); }, [loadData]);
return (
Platform Admin
Classroom Copilot — system overview
{error && setError(null)}>{error}}
{stats && (
)}
Schools ({loading ? '…' : schools.length})
{loading ? (
) : schools.length === 0 ? (
No schools registered.
) : (
School
URN
Staff
Students
Calendar
Invites
Neo4j
Registered
{schools.map(s => (
{s.name}
{s.urn || '—'}
{s.staff_count}
{s.student_count}
{s.pending_invitations > 0
?
: —}
{new Date(s.created_at).toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: '2-digit' })}
))}
)}
);
};
export default PlatformAdminPage;