Linked backend data to detectors' meshes.
This commit is contained in:
@@ -15,55 +15,39 @@ const Dashboard: React.FC = () => {
|
||||
const objectId = currentObject?.id
|
||||
const objectTitle = currentObject?.title
|
||||
|
||||
const [detectorsArray, setDetectorsArray] = useState<any[]>([])
|
||||
const [dashboardAlerts, setDashboardAlerts] = useState<any[]>([])
|
||||
const [chartData, setChartData] = useState<{ timestamp: string; value: number }[]>([])
|
||||
|
||||
useEffect(() => {
|
||||
const loadDetectors = async () => {
|
||||
const loadDashboard = async () => {
|
||||
try {
|
||||
const res = await fetch('/api/get-detectors', { cache: 'no-store' })
|
||||
const res = await fetch('/api/get-dashboard', { cache: 'no-store' })
|
||||
if (!res.ok) return
|
||||
const payload = await res.json()
|
||||
console.log('[Dashboard] GET /api/get-detectors', { status: res.status, payload })
|
||||
const detectorsData = payload?.data?.detectors ?? {}
|
||||
const arr = Object.values(detectorsData).filter(
|
||||
(detector: any) => (objectId ? detector.object === objectId : true)
|
||||
)
|
||||
setDetectorsArray(arr as any[])
|
||||
console.log('[Dashboard] GET /api/get-dashboard', { status: res.status, payload })
|
||||
const tableData = payload?.data?.table_data ?? []
|
||||
const arr = (Array.isArray(tableData) ? tableData : [])
|
||||
.filter((a: any) => (objectTitle ? a.object === objectTitle : true))
|
||||
setDashboardAlerts(arr as any[])
|
||||
|
||||
const cd = Array.isArray(payload?.data?.chart_data) ? payload.data.chart_data : []
|
||||
setChartData(cd as any[])
|
||||
} catch (e) {
|
||||
console.error('Failed to load detectors:', e)
|
||||
console.error('Failed to load dashboard:', e)
|
||||
}
|
||||
}
|
||||
loadDetectors()
|
||||
}, [objectId])
|
||||
loadDashboard()
|
||||
}, [objectTitle])
|
||||
|
||||
const handleBackClick = () => {
|
||||
router.push('/objects')
|
||||
}
|
||||
|
||||
interface DetectorData {
|
||||
detector_id: number
|
||||
name: string
|
||||
object: string
|
||||
status: string
|
||||
type: string
|
||||
location: string
|
||||
floor: number
|
||||
checked?: boolean
|
||||
notifications: Array<{
|
||||
id: number
|
||||
type: string
|
||||
message: string
|
||||
timestamp: string
|
||||
acknowledged: boolean
|
||||
priority: string
|
||||
}>
|
||||
}
|
||||
|
||||
// Статусы
|
||||
const statusCounts = detectorsArray.reduce((acc: { critical: number; warning: number; normal: number }, detector: DetectorData) => {
|
||||
if (detector.status === '#b3261e') acc.critical++
|
||||
else if (detector.status === '#fd7c22') acc.warning++
|
||||
else if (detector.status === '#00ff00') acc.normal++
|
||||
const statusCounts = dashboardAlerts.reduce((acc: { critical: number; warning: number; normal: number }, a: any) => {
|
||||
if (a.severity === 'critical') acc.critical++
|
||||
else if (a.severity === 'warning') acc.warning++
|
||||
else acc.normal++
|
||||
return acc
|
||||
}, { critical: 0, warning: 0, normal: 0 })
|
||||
|
||||
@@ -139,14 +123,14 @@ const Dashboard: React.FC = () => {
|
||||
title="Показатель"
|
||||
subtitle="За последние 6 месяцев"
|
||||
>
|
||||
<AreaChart />
|
||||
<AreaChart data={chartData} />
|
||||
</ChartCard>
|
||||
|
||||
<ChartCard
|
||||
title="Статистика"
|
||||
subtitle="Данные за период"
|
||||
>
|
||||
<BarChart />
|
||||
<BarChart data={chartData?.map((d: any) => ({ value: d.value }))} />
|
||||
</ChartCard>
|
||||
</div>
|
||||
</div>
|
||||
@@ -174,36 +158,26 @@ const Dashboard: React.FC = () => {
|
||||
<thead>
|
||||
<tr className="border-b border-gray-700">
|
||||
<th className="text-left text-white font-medium py-3">Детектор</th>
|
||||
<th className="text-left text-white font-medium py-3">Статус</th>
|
||||
<th className="text-left text-white font-medium py-3">Местоположение</th>
|
||||
<th className="text-left text-white font-medium py-3">Проверен</th>
|
||||
<th className="text-left text-white font-medium py-3">Сообщение</th>
|
||||
<th className="text-left text-white font-medium py-3">Серьезность</th>
|
||||
<th className="text-left text-white font-medium py-3">Дата</th>
|
||||
<th className="text-left text-white font-medium py-3">Решен</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{detectorsArray.map((detector: DetectorData) => (
|
||||
<tr key={detector.detector_id} className="border-b border-gray-800">
|
||||
<td className="py-3 text-white text-sm">{detector.name}</td>
|
||||
{dashboardAlerts.map((alert: any) => (
|
||||
<tr key={alert.id} className="border-b border-gray-800">
|
||||
<td className="py-3 text-white text-sm">{alert.name}</td>
|
||||
<td className="py-3 text-gray-300 text-sm">{alert.message}</td>
|
||||
<td className="py-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<div
|
||||
className={`w-3 h-3 rounded-full`}
|
||||
style={{ backgroundColor: detector.status }}
|
||||
></div>
|
||||
<span className="text-sm text-gray-300">
|
||||
{detector.status === '#b3261e' ? 'Критическое' :
|
||||
detector.status === '#fd7c22' ? 'Предупреждение' : 'Норма'}
|
||||
</span>
|
||||
</div>
|
||||
<span className={`text-sm ${alert.severity === 'critical' ? 'text-red-500' : alert.severity === 'warning' ? 'text-orange-500' : 'text-green-500'}`}>
|
||||
{alert.severity === 'critical' ? 'Критическое' : alert.severity === 'warning' ? 'Предупреждение' : 'Норма'}
|
||||
</span>
|
||||
</td>
|
||||
<td className="py-3 text-gray-400 text-sm">{detector.location}</td>
|
||||
<td className="py-3 text-gray-400 text-sm">{new Date(alert.created_at).toLocaleString()}</td>
|
||||
<td className="py-3">
|
||||
{detector.checked ? (
|
||||
<div className="flex items-center gap-1">
|
||||
<svg className="w-4 h-4 text-green-500" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
|
||||
</svg>
|
||||
<span className="text-sm text-green-500">Да</span>
|
||||
</div>
|
||||
{alert.resolved ? (
|
||||
<span className="text-sm text-green-500">Да</span>
|
||||
) : (
|
||||
<span className="text-sm text-gray-500">Нет</span>
|
||||
)}
|
||||
@@ -217,7 +191,7 @@ const Dashboard: React.FC = () => {
|
||||
{/* Статы */}
|
||||
<div className="mt-6 grid grid-cols-4 gap-4">
|
||||
<div className="text-center">
|
||||
<div className="text-2xl font-bold text-white">{detectorsArray.length}</div>
|
||||
<div className="text-2xl font-bold text-white">{dashboardAlerts.length}</div>
|
||||
<div className="text-sm text-gray-400">Всего</div>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
|
||||
Reference in New Issue
Block a user