diff --git a/packages/web/src/api.ts b/packages/web/src/api.ts index beb40d0..aaf9ee9 100644 --- a/packages/web/src/api.ts +++ b/packages/web/src/api.ts @@ -31,6 +31,7 @@ export interface OverviewData { } export interface Issue { + id?: string; url: string; issueType: string; severity: 'Critical' | 'Warning' | 'Info'; @@ -38,6 +39,12 @@ export interface Issue { pageRank: number; pageRankScore: number; lastSeen: string; + type?: string; + internalLinksCount?: number; + description?: string; + whyItMatters?: string; + howToFix?: string; + clusterId?: string; } export interface IssuesResponse { diff --git a/packages/web/src/components/CriticalPanel.tsx b/packages/web/src/components/CriticalPanel.tsx index 890ba38..2701188 100644 --- a/packages/web/src/components/CriticalPanel.tsx +++ b/packages/web/src/components/CriticalPanel.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState, useContext } from 'react'; +import { useEffect, useState, useContext } from 'react'; import { AlertTriangle, ExternalLink, Network, ChevronRight } from 'lucide-react'; import { DashboardContext } from '../App'; import * as API from '../api'; diff --git a/packages/web/src/components/GraphIntelligenceSection.tsx b/packages/web/src/components/GraphIntelligenceSection.tsx index 37d941f..b06767a 100644 --- a/packages/web/src/components/GraphIntelligenceSection.tsx +++ b/packages/web/src/components/GraphIntelligenceSection.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { PageRankTable } from './Graphs/PageRankTable'; import { SimpleBarChart } from './Graphs/SimpleBarChart'; import { DuplicateClusterChart } from './Graphs/DuplicateClusterChart'; diff --git a/packages/web/src/components/HealthSnapshot.tsx b/packages/web/src/components/HealthSnapshot.tsx index 3c8bea4..58828c1 100644 --- a/packages/web/src/components/HealthSnapshot.tsx +++ b/packages/web/src/components/HealthSnapshot.tsx @@ -1,7 +1,20 @@ -import { healthMetrics } from '../data'; +import { useContext } from 'react'; import { Activity, Link, Ghost, Copy, Layers, TrendingUp } from 'lucide-react'; +import { DashboardContext } from '../App'; export const HealthSnapshot = () => { + const { overview } = useContext(DashboardContext); + + if (!overview) return
; + + const healthMetrics = { + score: overview.health.score, + brokenLinks: overview.totals.brokenLinks, + orphanPages: overview.totals.orphanPages, + duplicateClusters: overview.totals.duplicateClusters, + pagesCrawled: overview.totals.crawled, + efficiency: overview.crawl.efficiency, + }; return (
diff --git a/packages/web/src/components/Issues/IssueDrawer.tsx b/packages/web/src/components/Issues/IssueDrawer.tsx index 2eae7eb..3dab08f 100644 --- a/packages/web/src/components/Issues/IssueDrawer.tsx +++ b/packages/web/src/components/Issues/IssueDrawer.tsx @@ -1,9 +1,8 @@ -import React from 'react'; import { X, ExternalLink, Link, AlertTriangle } from 'lucide-react'; -import { Issue } from '../../data'; +import * as API from '../../api'; interface IssueDrawerProps { - issue: Issue | null; + issue: API.Issue | null; onClose: () => void; isOpen: boolean; } diff --git a/packages/web/src/components/IssuesTable.tsx b/packages/web/src/components/IssuesTable.tsx index 580f5c6..5f743a2 100644 --- a/packages/web/src/components/IssuesTable.tsx +++ b/packages/web/src/components/IssuesTable.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect, useContext } from 'react'; +import { useState, useEffect, useContext } from 'react'; import { Link, useNavigate } from 'react-router-dom'; import { AlertTriangle, AlertCircle, Info, ChevronRight, Search, ArrowUp, ArrowDown } from 'lucide-react'; import { DashboardContext } from '../App'; @@ -50,10 +50,10 @@ export const IssuesTable = () => { // Client-side sort for current page (since API sort is limited in this scope) const sorted = [...issues].sort((a, b) => { - // @ts-expect-error - dynamic key access - if (a[key] < b[key]) return direction === 'asc' ? -1 : 1; - // @ts-expect-error - dynamic key access - if (a[key] > b[key]) return direction === 'asc' ? 1 : -1; + const aVal = a[key] as any; + const bVal = b[key] as any; + if (aVal < bVal) return direction === 'asc' ? -1 : 1; + if (aVal > bVal) return direction === 'asc' ? 1 : -1; return 0; }); setIssues(sorted); diff --git a/packages/web/src/components/WarningPanel.tsx b/packages/web/src/components/WarningPanel.tsx index 817fd35..c1f2b4a 100644 --- a/packages/web/src/components/WarningPanel.tsx +++ b/packages/web/src/components/WarningPanel.tsx @@ -1,7 +1,29 @@ -import { criticalIssues } from '../data.js'; +import { useState, useEffect, useContext } from 'react'; import { AlertTriangle, ArrowRight } from 'lucide-react'; +import { DashboardContext } from '../App'; +import * as API from '../api'; export const WarningPanel = () => { + const { currentSnapshot } = useContext(DashboardContext); + const [criticalIssues, setCriticalIssues] = useState([]); + const [loading, setLoading] = useState(false); + + useEffect(() => { + if (!currentSnapshot) return; + const fetch = async () => { + setLoading(true); + try { + const data = await API.fetchIssues(currentSnapshot, 'Critical', '', 1); + setCriticalIssues(data.results.slice(0, 5)); // show top 5 + } catch (e) { + console.error(e); + } finally { + setLoading(false); + } + }; + fetch(); + }, [currentSnapshot]); + return (
@@ -10,15 +32,17 @@ export const WarningPanel = () => {

Critical Attention

-

5 issues require immediate fix

+

+ {loading ? 'Loading...' : `${criticalIssues.length} issues require immediate fix`} +

- {criticalIssues.map((issue) => ( -
+ {criticalIssues.map((issue, idx) => ( +
- {issue.type} + {issue.issueType || issue.type}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8fcf51b..a3c5a3e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -747,79 +747,66 @@ packages: resolution: {integrity: sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==} cpu: [arm] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.59.0': resolution: {integrity: sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==} cpu: [arm] os: [linux] - libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.59.0': resolution: {integrity: sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==} cpu: [arm64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.59.0': resolution: {integrity: sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==} cpu: [arm64] os: [linux] - libc: [musl] '@rollup/rollup-linux-loong64-gnu@4.59.0': resolution: {integrity: sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==} cpu: [loong64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-loong64-musl@4.59.0': resolution: {integrity: sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==} cpu: [loong64] os: [linux] - libc: [musl] '@rollup/rollup-linux-ppc64-gnu@4.59.0': resolution: {integrity: sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==} cpu: [ppc64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-ppc64-musl@4.59.0': resolution: {integrity: sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==} cpu: [ppc64] os: [linux] - libc: [musl] '@rollup/rollup-linux-riscv64-gnu@4.59.0': resolution: {integrity: sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==} cpu: [riscv64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.59.0': resolution: {integrity: sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==} cpu: [riscv64] os: [linux] - libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.59.0': resolution: {integrity: sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==} cpu: [s390x] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.59.0': resolution: {integrity: sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==} cpu: [x64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-musl@4.59.0': resolution: {integrity: sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==} cpu: [x64] os: [linux] - libc: [musl] '@rollup/rollup-openbsd-x64@4.59.0': resolution: {integrity: sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==}