Files
Shadowbroker/frontend/src/hooks/useGtDossier.ts
T
Shadowbroker cfbeabda1e Feat/gt analytics openclaw (#392)
* feat(telegram): auto-translate OSINT channel posts to English

Cherry-picked from @Bobpick PR #391 (telegram-only slice): server-side translation during fetch, SHOW ORIGINAL toggle in TelegramOsintPopup, and on-demand /api/telegram-feed?lang=.

Co-authored-by: Robert Pickett <bobpickettsr@yahoo.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* feat(gt): experimental Derived OSINT analytics with lean-node safeguards

Cherry-picked from @Bobpick PR #391 (GT + OpenClaw slice): Bayesian strategic-risk engine, map overlay, OpenClaw commands, and telegram_rhetoric watchdog. Off by default (GT_ANALYTICS_ENABLED=false, gt_risk layer false). 1 vCPU nodes get cgroup detection, UI warning on layer toggle, and lean profile that skips scheduled ingest/Louvain unless GT_ANALYTICS_ACK_LOW_CPU=true. Backtest HUD removed from dashboard (OpenClaw/API regression only).

Co-authored-by: Robert Pickett <bobpickettsr@yahoo.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Robert Pickett <bobpickettsr@yahoo.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-16 17:05:46 -06:00

58 lines
1.6 KiB
TypeScript

import { useEffect, useState } from 'react';
import type { GtDossier } from '@/types/dashboard';
import { API_BASE } from '@/lib/api';
export function useGtDossier(
lat: number | undefined,
lng: number | undefined,
countryName?: string,
enabled = true,
) {
const [gtDossier, setGtDossier] = useState<GtDossier | null>(null);
const [gtDossierLoading, setGtDossierLoading] = useState(false);
useEffect(() => {
if (!enabled || lat == null || lng == null) {
setGtDossier(null);
setGtDossierLoading(false);
return;
}
let cancelled = false;
const regions = [
`${lat.toFixed(2)},${lng.toFixed(2)}`,
countryName?.trim().toLowerCase(),
].filter((value): value is string => Boolean(value));
const load = async () => {
setGtDossierLoading(true);
let best: GtDossier | null = null;
for (const region of regions) {
try {
const response = await fetch(
`${API_BASE}/api/analytics/dossier/${encodeURIComponent(region)}`,
);
if (!response.ok) continue;
const payload = (await response.json()) as GtDossier;
if (!payload.enabled) continue;
if (!best || (payload.current_risk ?? 0) > (best.current_risk ?? 0)) {
best = { ...payload, region };
}
} catch {
// GT analytics optional — ignore fetch errors
}
}
if (!cancelled) {
setGtDossier(best);
setGtDossierLoading(false);
}
};
void load();
return () => {
cancelled = true;
};
}, [lat, lng, countryName, enabled]);
return { gtDossier, gtDossierLoading };
}