'use client'; import { useState } from 'react'; import axios from 'axios'; import { Treemap, Tooltip as ReTooltip, ResponsiveContainer } from 'recharts'; export default function Home() { const [url, setUrl] = useState(''); const [loading, setLoading] = useState(false); const [reports, setReports] = useState(null); const [error, setError] = useState(''); const [activeTab, setActiveTab] = useState<'mobile' | 'desktop'>('mobile'); // --- Helper to parse estimated savings like "1.2 s" or "1200 ms" --- function parseSavings(value: string): number { if (!value) return 0; const val = parseFloat(value); if (value.toLowerCase().includes('ms')) return val; if (value.toLowerCase().includes('s')) return val * 1000; return val; } const handleAudit = async () => { if (!url) return setError('Enter a URL'); setLoading(true); setError(''); setReports(null); try { const { data } = await axios.post('https://api.crawlerx.co/api/lighthouse/audit', { url }); // normalize the results const normalizedResults: any = {}; ['mobile', 'desktop'].forEach((tab) => { const tabData = data.results?.[tab] || {}; normalizedResults[tab] = { report: { scores: tabData.scores || {}, metrics: tabData.metrics || {}, opportunities: Array.isArray(tabData.opportunities) ? tabData.opportunities : [], diagnostics: tabData.diagnostics || {}, screenshot: tabData.screenshot || '', }, }; }); setReports(normalizedResults); setActiveTab('mobile'); } catch (err: any) { setError(err.response?.data?.message || err.message || 'Error'); } finally { setLoading(false); } }; const renderScoreCircle = (score: number) => { const color = score >= 90 ? 'text-green-500 border-green-500' : score >= 50 ? 'text-yellow-500 border-yellow-500' : 'text-red-500 border-red-500'; return (
{score}
); }; const renderMetrics = (metrics: any = {}) => (
{Object.entries(metrics).map(([key, value]) => (

{key.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase())}

{value ?? '-'}

))}
); const renderOpportunities = (opportunities: any[] = []) => (

Opportunities

{opportunities.length === 0 &&

No suggestions available.

} {opportunities.map((op, idx) => (

{op.title ?? '-'}

{op.description ?? '-'}

{op.estimatedSavings && (

Estimated Savings: {op.estimatedSavings}

)}
))}
); const renderTreeMap = (opportunities: any[] = []) => { if (opportunities.length === 0) return null; const data = opportunities.map(op => ({ name: op.title || 'Untitled', size: parseSavings(op.estimatedSavings) })); return (

Opportunities Tree Map

{ if (!payload || payload.length === 0) return null; const item = payload[0].payload; return (

{item.name}

{item.size} ms estimated savings

); }} />
); }; const renderDiagnostics = (diagnostics: any = {}) => { const keys = Object.keys(diagnostics); return (

Diagnostics

{keys.length === 0 &&

No diagnostics available.

}
{keys.map((key) => (

{key.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase())}

{key === 'http2' && (

All resources should be served via HTTP/2 for better performance.

)}
{diagnostics[key] ? 'Pass' : 'Fail'}
))}
); }; const currentReport = reports?.[activeTab]?.report || { scores: {}, metrics: {}, opportunities: [], diagnostics: {}, screenshot: '', }; return (

Lighthouse PageSpeed Audit

{/* Input */}
setUrl(e.target.value)} placeholder="Enter URL" className="flex-1 px-4 py-2 border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500" />
{error &&

{error}

} {reports && (
{/* Tabs */}
{/* Top Scores */}
{['performance', 'accessibility', 'bestPractices', 'seo', 'pwa'].map((key) => { const score = currentReport.scores?.[key]; if (score === undefined || score === null) return null; return (

{key.charAt(0).toUpperCase() + key.slice(1)}

{renderScoreCircle(score)}
); })}
{/* Metrics */} {renderMetrics(currentReport.metrics)} {/* Opportunities */} {renderOpportunities(currentReport.opportunities)} {/* Tree Map */} {renderTreeMap(currentReport.opportunities)} {/* Diagnostics */} {renderDiagnostics(currentReport.diagnostics)} {/* Screenshot */} {currentReport.screenshot && (
{`${activeTab}
)}
)}
); }