"use client"; /** * TEE OFF ADMIN DASHBOARD v1.4 - LIVE PROGRESSION * --------------------------------------------------------------------------- * PLASSERING: frontend/src/app/admin/page.tsx * FUNKSJON: Starter bakgrunnsjobber og oppdaterer tabellen live. * --------------------------------------------------------------------------- */ import { useState, useEffect } from 'react'; import { API_URL } from "@/config/constants"; import ScrapeMethodSelect from "@/components/ScrapeMethodSelect"; export default function AdminDashboard() { const [facilities, setFacilities] = useState([]); const [loading, setLoading] = useState(true); const [selectedFacilities, setSelectedFacilities] = useState([]); // NYTT: Holder styr på om en skraping pågår akkurat nå const [isScraping, setIsScraping] = useState(false); // Henter data fra databasen const fetchFacilities = () => { fetch(`${API_URL}/facilities`) .then(res => res.json()) .then(data => { setFacilities(Array.isArray(data) ? data : []); setLoading(false); }) .catch(() => setLoading(false)); }; // Hent data ved første innlasting useEffect(() => { fetchFacilities(); }, []); // NYTT: Hvis skraping pågår, oppdater tabellen hvert 10. sekund! useEffect(() => { let interval: NodeJS.Timeout; if (isScraping) { interval = setInterval(() => { fetchFacilities(); }, 10000); } return () => clearInterval(interval); }, [isScraping]); const handleSelectAll = (e: React.ChangeEvent) => { if (e.target.checked) { setSelectedFacilities(facilities.map(f => f.id)); } else { setSelectedFacilities([]); } }; const handleSelectOne = (id: number, checked: boolean) => { if (checked) { setSelectedFacilities([...selectedFacilities, id]); } else { setSelectedFacilities(selectedFacilities.filter(facilityId => facilityId !== id)); } }; // NYTT: Sender IDene til API-et og starter auto-oppdatering const handleRunScrapers = async () => { setIsScraping(true); try { const response = await fetch(`${API_URL}/admin/run-scraper`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ facility_ids: selectedFacilities }) }); if (!response.ok) throw new Error("Kunne ikke starte skraping"); // Valgfritt: Fjern avhukingene når jobben har startet setSelectedFacilities([]); // Stopper auto-oppdateringen etter 10 minutter (for sikkerhets skyld) setTimeout(() => setIsScraping(false), 10 * 60 * 1000); } catch (error) { console.error(error); alert("Feil ved start av skraperen."); setIsScraping(false); } }; if (loading) return
LASTER DASHBORD...
; return (

Scraping Monitor

Sjekker status på {facilities.length} anlegg

{/* NYTT: Knappen endrer utseende når skraping pågår */}
{facilities.map((f: any) => ( ))}
0} onChange={handleSelectAll} /> Anlegg Konfigurasjon Metode Siste Sjekk Banestatus Handling
handleSelectOne(f.id, e.target.checked)} />
{f.name}
{f.city}
{f.scrape_status_url}
{f.scrape_status_selector}
{f.status_updated_at ? new Date(f.status_updated_at).toLocaleDateString('nb-NO') : 'Aldri'}
{f.course_statuses && f.course_statuses.map((cs: any, idx: number) => { let badgeColor = "bg-gray-100 text-gray-500"; if (cs.status === "aapen") badgeColor = "bg-green-100 text-green-700"; if (cs.status === "stengt" || cs.status === "nedlagt") badgeColor = "bg-red-100 text-red-700"; if (cs.status === "aapen_med_vintergreener" || cs.status === "aapner_snart") badgeColor = "bg-yellow-100 text-yellow-700"; return (
{cs.name} {cs.status || 'UKJENT'}
) })}
); }