import React, { useState, useEffect, useRef } from 'react'; import { BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts'; import { initLocalEngine, routeInference } from '../utils/inferenceRouter'; import HCaptcha from '@hcaptcha/react-hcaptcha'; import { supabase, useAuth, GATEWAY_URL, LEMON_CHECKOUT_URL } from '../context'; export default function WatchDashboardSection({ usage, setPage }) { const [watches, setWatches] = useState([]); const [monitors, setMonitors] = useState([]); const [loading, setLoading] = useState(true); const [view, setView] = useState('opticparse'); // 'opticparse' or 'phishvision' const [showCreate, setShowCreate] = useState(false); const [createUrl, setCreateUrl] = useState(''); const [createQuery, setCreateQuery] = useState(''); const fetchData = async () => { setLoading(true); try { const resOp = await fetch('https://opticparse-python-sg.onrender.com/gateway/watches'); const dataOp = await resOp.json(); setWatches(dataOp.watches || []); const resPv = await fetch('https://opticparse-1opticparse-node-sg.onrender.com/api/monitors'); const dataPv = await resPv.json(); setMonitors(dataPv.monitors || []); } catch (e) { console.error(e); } setLoading(false); }; useEffect(() => { fetchData(); }, []); const handleDelete = async (id, type) => { if (!confirm("Delete this monitor?")) return; try { if (type === 'opticparse') { await fetch(`https://opticparse-python-sg.onrender.com/api/watch/${id}`, { method: 'DELETE' }); } else { await fetch(`https://opticparse-1opticparse-node-sg.onrender.com/api/monitor/${id}`, { method: 'DELETE' }); } fetchData(); } catch (e) { console.error(e); console.error(e); } }; const handleCreateOpticParseMonitor = async (e) => { e.preventDefault(); try { await fetch('https://opticparse-python-sg.onrender.com/gateway/watches', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ url: createUrl, query: createQuery }) }); setShowCreate(false); setCreateUrl(''); setCreateQuery(''); fetchData(); } catch (err) { console.error("Failed to create monitor", err); } }; const handleCreatePhishVisionMonitor = async (e) => { e.preventDefault(); try { await fetch('https://opticparse-1opticparse-node-sg.onrender.com/api/monitors', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ url: createUrl, webhook_url: localStorage.getItem('opticparse_webhook_url') || 'https://example.com/webhook', interval_minutes: 60 }) }); setShowCreate(false); setCreateUrl(''); fetchData(); } catch (err) { console.error("Failed to create PV monitor", err); } }; return (

Cron Jobs & Monitors

{showCreate && view === 'opticparse' && (

Create OpticParse Monitor

setCreateUrl(e.target.value)} placeholder="https://example.com" required />
setCreateQuery(e.target.value)} placeholder="What data to track?" required />
)} {showCreate && view === 'phishvision' && (

Create PhishVision Monitor

setCreateUrl(e.target.value)} placeholder="https://example.com" required />
)}
{loading ? (
Loading active monitors...
) : view === 'opticparse' ? ( watches.length === 0 ?
No active OpticParse watches.
: ( {watches.map(w => ( ))}
Target URL Created At Last Result Actions
{w.url} {new Date(w.created_at * 1000).toLocaleString()} {w.last_result?.substring(0, 50)}...
) ) : ( monitors.length === 0 ?
No active PhishVision monitors.
: ( {monitors.map(m => ( ))}
Target URL Interval (ms) Last Verdict Actions
{m.url} {m.interval_ms || m.intervalMs} {((m.last_run_verdict || m.lastRunVerdict) || 'pending').toUpperCase()}
) )}
To create a new watch/monitor, please use the API Docs endpoints or the Integrations tab.
); }