forked from 0xWheatyz/SPARC
cb7d7121c5
Add modern React frontend to replace Streamlit dashboard: - Vite build system with TypeScript - Tailwind CSS for styling - Component structure in src/ - Production Dockerfile with nginx - Development server on port 5173 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
172 lines
5.8 KiB
TypeScript
172 lines
5.8 KiB
TypeScript
import { useQuery } from '@tanstack/react-query';
|
|
import axios from 'axios';
|
|
import { Search, FileText, Bot, Zap, Globe, BarChart3, CheckCircle, AlertTriangle, XCircle } from 'lucide-react';
|
|
|
|
const API_BASE_URL = import.meta.env.VITE_API_URL || '/api';
|
|
|
|
export function About() {
|
|
const { data: health } = useQuery({
|
|
queryKey: ['health'],
|
|
queryFn: async () => {
|
|
const response = await axios.get(`${API_BASE_URL}/health`);
|
|
return response.data;
|
|
},
|
|
refetchInterval: 30000,
|
|
});
|
|
|
|
const features = [
|
|
{
|
|
icon: Search,
|
|
title: 'Patent Retrieval',
|
|
description: 'Automated collection via SerpAPI\'s Google Patents',
|
|
},
|
|
{
|
|
icon: FileText,
|
|
title: 'Intelligent Parsing',
|
|
description: 'Extracts key sections from patent documents',
|
|
},
|
|
{
|
|
icon: Bot,
|
|
title: 'AI Analysis',
|
|
description: 'Deep analysis powered by Claude 3.5 Sonnet',
|
|
},
|
|
{
|
|
icon: Zap,
|
|
title: 'Batch Processing',
|
|
description: 'Analyze multiple companies concurrently',
|
|
},
|
|
{
|
|
icon: Globe,
|
|
title: 'REST API',
|
|
description: 'FastAPI web service for seamless integration',
|
|
},
|
|
{
|
|
icon: BarChart3,
|
|
title: 'Analytics',
|
|
description: 'Track and visualize historical analysis data',
|
|
},
|
|
];
|
|
|
|
const techStack = [
|
|
{ label: 'Backend', value: 'Python, FastAPI' },
|
|
{ label: 'AI Model', value: 'Claude 3.5 Sonnet' },
|
|
{ label: 'Database', value: 'PostgreSQL' },
|
|
{ label: 'Frontend', value: 'React, TailwindCSS' },
|
|
{ label: 'Data Source', value: 'SerpAPI Patents' },
|
|
];
|
|
|
|
return (
|
|
<div className="space-y-8">
|
|
{/* Header */}
|
|
<div>
|
|
<h2 className="text-xl font-semibold text-text-primary border-b-2 border-primary/30 pb-2 mb-2">
|
|
About SPARC
|
|
</h2>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
|
{/* Main Content */}
|
|
<div className="lg:col-span-2 space-y-6">
|
|
{/* Description */}
|
|
<p className="text-text-secondary leading-relaxed">
|
|
<strong className="text-text-primary">SPARC</strong> (Semiconductor Patent & Analytics Report Core)
|
|
is an AI-powered patent analysis platform that evaluates company performance by analyzing their
|
|
patent portfolios with cutting-edge language models.
|
|
</p>
|
|
|
|
{/* Features */}
|
|
<div>
|
|
<h3 className="text-lg font-semibold text-text-primary mb-4">Key Features</h3>
|
|
<div className="space-y-3">
|
|
{features.map(({ icon: Icon, title, description }) => (
|
|
<div
|
|
key={title}
|
|
className="flex items-start gap-4 py-3 border-b border-primary/10 last:border-0"
|
|
>
|
|
<div className="flex-shrink-0">
|
|
<Icon className="text-primary" size={20} />
|
|
</div>
|
|
<div>
|
|
<div className="font-medium text-text-primary">{title}</div>
|
|
<div className="text-sm text-text-secondary">{description}</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Sidebar */}
|
|
<div className="space-y-6">
|
|
{/* Tech Stack */}
|
|
<div className="bg-gradient-to-br from-primary/10 to-secondary/5 border border-primary/20 rounded-xl p-5">
|
|
<h3 className="font-semibold text-text-primary mb-4">Technology Stack</h3>
|
|
<div className="space-y-3">
|
|
{techStack.map(({ label, value }) => (
|
|
<div key={label}>
|
|
<div className="text-primary text-sm">{label}</div>
|
|
<div className="text-text-secondary text-sm">{value}</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
{/* API Endpoints */}
|
|
<div className="bg-bg-card/60 border border-primary/15 rounded-xl p-5">
|
|
<h3 className="font-semibold text-text-primary mb-4">API Endpoints</h3>
|
|
<div className="space-y-2">
|
|
<code className="block bg-bg-dark px-3 py-2 rounded text-sm text-text-secondary">
|
|
http://localhost:8000/docs
|
|
</code>
|
|
<code className="block bg-bg-dark px-3 py-2 rounded text-sm text-text-secondary">
|
|
http://localhost:8000/health
|
|
</code>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* System Status */}
|
|
<div>
|
|
<h3 className="text-lg font-semibold text-text-primary border-b-2 border-primary/30 pb-2 mb-4">
|
|
System Status
|
|
</h3>
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
<StatusCard
|
|
label="API"
|
|
status={health ? 'online' : 'offline'}
|
|
/>
|
|
<StatusCard
|
|
label="Database"
|
|
status="configured"
|
|
/>
|
|
<StatusCard
|
|
label="Dashboard"
|
|
status="online"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function StatusCard({ label, status }: { label: string; status: 'online' | 'offline' | 'configured' }) {
|
|
const statusConfig = {
|
|
online: { icon: CheckCircle, color: 'text-success', bg: 'bg-success' },
|
|
offline: { icon: XCircle, color: 'text-error', bg: 'bg-error' },
|
|
configured: { icon: AlertTriangle, color: 'text-warning', bg: 'bg-warning' },
|
|
};
|
|
|
|
const { icon: Icon, color, bg } = statusConfig[status];
|
|
|
|
return (
|
|
<div className="bg-gradient-to-br from-primary/10 to-secondary/10 border border-primary/20 rounded-xl p-5 text-center">
|
|
<div className={`inline-flex items-center justify-center w-8 h-8 rounded-full ${bg}/20 mb-2`}>
|
|
<Icon className={color} size={20} />
|
|
</div>
|
|
<div className="text-sm text-text-secondary uppercase tracking-wide">{label}</div>
|
|
<div className={`font-semibold ${color} capitalize`}>{status}</div>
|
|
</div>
|
|
);
|
|
}
|