import React, { useState, useEffect } from "react"; import { DBService } from "../lib/db"; import { WebsiteMonitor } from "../types"; import { Activity, Plus, Trash, Play, AlertTriangle, CheckCircle, ArrowUpRight, TrendingUp, Clock, Shuffle } from "lucide-react"; export default function MonitorTab({ triggerHaptic }: { triggerHaptic: () => void }) { const [monitors, setMonitors] = useState([]); const [name, setName] = useState(""); const [url, setUrl] = useState(""); const [interval, setIntervalVal] = useState<"30s" | "1m" | "5m" | "15m" | "1h">("1m"); const [testingId, setTestingId] = useState(null); useEffect(() => { loadMonitors(); // Auto-ping cron simulation every 15 seconds const intervalId = window.setInterval(() => { runAutoPingSimulation(); }, 15000); return () => clearInterval(intervalId); }, []); const loadMonitors = async () => { const list = await DBService.getAll("monitors"); // Self-healing migration to replace unreliable httpstat.us connections const migratedList = list.map(m => { if (m.url && m.url.includes("httpstat.us")) { return { ...m, url: m.url.replace("httpstat.us/404", "httpbin.org/status/404").replace("httpstat.us", "httpbin.org") }; } return m; }); // Save changes back to local store if any were migrated let wasMigrated = false; for (let i = 0; i < list.length; i++) { if (list[i].url !== migratedList[i].url) { await DBService.put("monitors", migratedList[i]); wasMigrated = true; } } if (migratedList.length === 0) { // Seed some dynamic monitors representing standard platforms for first look demo const seed: WebsiteMonitor[] = [ { id: "mon_1", name: "Vercel Build Edge", url: "https://vercel.com", interval: "1m", status: "up", lastCheck: Date.now() - 60000, responseTime: 182, history: [ { timestamp: Date.now() - 300000, status: "up", responseTime: 190, code: 200 }, { timestamp: Date.now() - 240000, status: "up", responseTime: 212, code: 200 }, { timestamp: Date.now() - 180000, status: "up", responseTime: 180, code: 200 }, { timestamp: Date.now() - 120000, status: "up", responseTime: 185, code: 200 }, { timestamp: Date.now() - 60000, status: "up", responseTime: 182, code: 200 } ] }, { id: "mon_2", name: "قاعدة بيانات Supabase API", url: "https://supabase.com", interval: "5m", status: "up", lastCheck: Date.now() - 120000, responseTime: 295, history: [ { timestamp: Date.now() - 600000, status: "up", responseTime: 310, code: 200 }, { timestamp: Date.now() - 480000, status: "up", responseTime: 302, code: 200 }, { timestamp: Date.now() - 360000, status: "up", responseTime: 298, code: 200 }, { timestamp: Date.now() - 240000, status: "up", responseTime: 290, code: 200 }, { timestamp: Date.now() - 120000, status: "up", responseTime: 295, code: 200 } ] }, { id: "mon_3", name: "API الخادم الاحتياطي", url: "https://httpbin.org/status/404", interval: "15m", status: "down", lastCheck: Date.now() - 300000, responseTime: 1540, history: [ { timestamp: Date.now() - 1200000, status: "down", responseTime: 1200, code: 404 }, { timestamp: Date.now() - 900000, status: "up", responseTime: 420, code: 200 }, { timestamp: Date.now() - 600000, status: "down", responseTime: 1500, code: 504 }, { timestamp: Date.now() - 300000, status: "down", responseTime: 1540, code: 404 } ] } ]; for (const m of seed) { await DBService.put("monitors", m); } setMonitors(seed); } else { setMonitors(migratedList); } }; const runAutoPingSimulation = async () => { const list = await DBService.getAll("monitors"); if (list.length === 0) return; const randomIndex = Math.floor(Math.random() * list.length); const monitor = list[randomIndex]; if (monitor) { await executeSinglePing(monitor); } }; const executeSinglePing = async (m: WebsiteMonitor) => { setTestingId(m.id); const start = performance.now(); let status: "up" | "down" | "slow" = "up"; let code = 200; let respTime = 0; try { const formatUrl = m.url.startsWith("http") ? m.url : `https://${m.url}`; const res = await fetch(`/api/proxy?url=${encodeURIComponent(formatUrl)}`, { method: "GET" }); const end = performance.now(); respTime = Math.round(end - start); code = res.status; if (!res.ok) { status = "down"; } else if (respTime > 800) { status = "slow"; } } catch { status = "down"; code = 500; respTime = 2000; } const updatedHistoryItem = { timestamp: Date.now(), status, responseTime: respTime, code }; const newHistory = [updatedHistoryItem, ...m.history].slice(0, 100); const updated: WebsiteMonitor = { ...m, status, lastCheck: Date.now(), responseTime: respTime, history: newHistory }; await DBService.put("monitors", updated); if (m.status !== status) { await DBService.put("auditLog", { id: "log_" + Date.now(), timestamp: Date.now(), action: "تنبيه مراقبة المواقع", details: `مراقب المواقع [${m.name}] تغيرت حالته من [${m.status}] إلى [${status}]`, status: status === "up" ? "success" : "danger" }); } setMonitors(prev => prev.map(item => item.id === m.id ? updated : item)); setTestingId(null); }; const handleAddMonitor = async (e: React.FormEvent) => { e.preventDefault(); if (!name || !url) return; triggerHaptic(); const newMonitor: WebsiteMonitor = { id: "mon_" + Date.now(), name, url, interval, status: "unknown", history: [] }; await DBService.put("monitors", newMonitor); setMonitors(prev => [newMonitor, ...prev]); setName(""); setUrl(""); executeSinglePing(newMonitor); }; const handleDelete = async (id: string) => { triggerHaptic(); await DBService.delete("monitors", id); setMonitors(prev => prev.filter(m => m.id !== id)); }; return (
{/* Sidebar Add (Left) */}

إضافة مراقب تفاعلي جديد

setName(e.target.value)} className="bg-white border border-sky-200 rounded-xl px-4 py-2 text-xs text-slate-800 focus:outline-none focus:border-sky-500 w-full font-bold" />
setUrl(e.target.value)} className="bg-white border border-sky-200 rounded-xl px-4 py-2 text-xs text-slate-800 focus:outline-none focus:border-sky-500 w-full text-left font-mono" />
{/* Global Stats */}

ملخص الأداء والحيّوية

العدد الكلي للمراقبين: {monitors.length} قنوات
الخوادم النشطة (Up): {monitors.filter(m => m.status === "up").length}
الخوادم المتوقفة (Down): {monitors.filter(m => m.status === "down").length}
{/* Monitors Dashboard View (Right) */}
{monitors.map((m) => (
{/* Title Block */}

{m.name}

{m.status === "up" ? "متصل (UP)" : m.status === "down" ? "غير متصل (DOWN)" : "قيد الاختبار"} {m.interval}

{m.url}

سجل الأحداث المباشر:
{m.history.length === 0 ? ( لا يوجد سجل تاريخي ) : ( m.history.map((h, index) => (
)) )}
{/* Telemetry Actions Block */}
سرعة الاستجابة {m.responseTime ? ( {m.responseTime} ms ) : ( -- )}
{/* Run Test & Delete */}
))} {monitors.length === 0 && (
لا توجد مخدمات مراقبة نشطة مضافة بعد، أضف عنوان خدمة للبدء.
)}
); }