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' && (
)}
{showCreate && view === 'phishvision' && (
)}
{loading ? (
Loading active monitors...
) : view === 'opticparse' ? (
watches.length === 0 ?
No active OpticParse watches.
: (
| Target URL |
Created At |
Last Result |
Actions |
{watches.map(w => (
| {w.url} |
{new Date(w.created_at * 1000).toLocaleString()} |
{w.last_result?.substring(0, 50)}... |
|
))}
)
) : (
monitors.length === 0 ?
No active PhishVision monitors.
: (
| Target URL |
Interval (ms) |
Last Verdict |
Actions |
{monitors.map(m => (
| {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.
);
}