Spaces:
Sleeping
Sleeping
| import React from 'react'; | |
| import { | |
| Database, GitBranch, Bot, Globe, Server, ArrowRight, | |
| Cpu, HardDrive, Share2 | |
| } from 'lucide-react'; | |
| import { motion } from 'framer-motion'; | |
| import { useTranslation } from 'react-i18next'; | |
| export default function ArchitectureMap() { | |
| const { t } = useTranslation(); | |
| const nodes = [ | |
| { | |
| id: 'data', | |
| label: t('overview.arch.data_layer'), | |
| icon: Database, | |
| color: 'bg-emerald-500', | |
| desc: t('overview.arch.data_desc'), | |
| status: 'operational' | |
| }, | |
| { | |
| id: 'workflow', | |
| label: t('overview.arch.orchestration'), | |
| icon: GitBranch, | |
| color: 'bg-blue-500', | |
| desc: t('overview.arch.orch_desc'), | |
| status: 'processing' | |
| }, | |
| { | |
| id: 'agent', | |
| label: t('overview.arch.agent_core'), | |
| icon: Bot, | |
| color: 'bg-purple-500', | |
| desc: t('overview.arch.agent_desc'), | |
| status: 'operational' | |
| }, | |
| { | |
| id: 'app', | |
| label: t('overview.arch.application'), | |
| icon: Globe, | |
| color: 'bg-orange-500', | |
| desc: t('overview.arch.app_desc'), | |
| status: 'active' | |
| } | |
| ]; | |
| return ( | |
| <div className="bg-white p-6 rounded-3xl border border-zinc-200 shadow-sm mb-8 overflow-hidden relative"> | |
| <div className="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-emerald-500 via-blue-500 to-purple-500 opacity-20"></div> | |
| <div className="flex items-center justify-between mb-6"> | |
| <h3 className="font-bold text-zinc-900 flex items-center gap-2"> | |
| <Share2 size={18} className="text-zinc-500" /> | |
| {t('overview.arch.title')} | |
| </h3> | |
| <span className="text-xs font-mono text-green-600 bg-green-50 px-2 py-1 rounded-full flex items-center gap-1"> | |
| <span className="w-1.5 h-1.5 bg-green-500 rounded-full animate-pulse"></span> | |
| {t('overview.arch.system_online')} | |
| </span> | |
| </div> | |
| <div className="relative flex flex-col md:flex-row items-center justify-between gap-4 md:gap-0 px-4 py-4"> | |
| {/* Connecting Line (Desktop) */} | |
| <div className="hidden md:block absolute top-1/2 left-10 right-10 h-0.5 bg-zinc-100 -z-0"></div> | |
| {nodes.map((node, idx) => ( | |
| <React.Fragment key={node.id}> | |
| <motion.div | |
| initial={{ opacity: 0, y: 20 }} | |
| animate={{ opacity: 1, y: 0 }} | |
| transition={{ delay: idx * 0.1 }} | |
| className="relative z-10 flex flex-col items-center group cursor-pointer" | |
| > | |
| <div className={` | |
| w-16 h-16 rounded-2xl flex items-center justify-center text-white shadow-lg mb-3 transition-all duration-300 | |
| ${node.color} group-hover:scale-110 group-hover:shadow-xl | |
| `}> | |
| <node.icon size={28} /> | |
| {node.status === 'processing' && ( | |
| <span className="absolute -top-1 -right-1 flex h-3 w-3"> | |
| <span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-white opacity-75"></span> | |
| <span className="relative inline-flex rounded-full h-3 w-3 bg-white"></span> | |
| </span> | |
| )} | |
| </div> | |
| <div className="text-center"> | |
| <div className="font-bold text-zinc-800 text-sm">{node.label}</div> | |
| <div className="text-[10px] text-zinc-400 font-medium mt-0.5">{node.desc}</div> | |
| </div> | |
| {/* Status Dot */} | |
| <div className="mt-2 flex items-center gap-1"> | |
| <div className={`w-1.5 h-1.5 rounded-full ${node.status === 'operational' || node.status === 'active' || node.status === 'processing' ? 'bg-green-500' : 'bg-red-500'}`}></div> | |
| <span className="text-[10px] text-zinc-400 uppercase">{t(`overview.arch.status.${node.status}`)}</span> | |
| </div> | |
| </motion.div> | |
| {/* Arrow (except last) */} | |
| {idx < nodes.length - 1 && ( | |
| <div className="md:hidden text-zinc-300"> | |
| <ArrowRight size={20} className="rotate-90 md:rotate-0" /> | |
| </div> | |
| )} | |
| {idx < nodes.length - 1 && ( | |
| <motion.div | |
| initial={{ opacity: 0, scale: 0 }} | |
| animate={{ opacity: 1, scale: 1 }} | |
| transition={{ delay: idx * 0.1 + 0.2 }} | |
| className="hidden md:flex items-center justify-center bg-white p-1 rounded-full border border-zinc-100 shadow-sm z-10 text-zinc-300" | |
| > | |
| <ArrowRight size={16} /> | |
| </motion.div> | |
| )} | |
| </React.Fragment> | |
| ))} | |
| </div> | |
| {/* Metrics Row */} | |
| <div className="grid grid-cols-3 gap-4 mt-8 pt-6 border-t border-zinc-100 bg-zinc-50/50 -mx-6 -mb-6 px-6 pb-6"> | |
| <div className="flex items-center gap-3"> | |
| <div className="p-2 bg-zinc-200 rounded-lg text-zinc-500"><Server size={16} /></div> | |
| <div> | |
| <div className="text-[10px] text-zinc-400 font-bold uppercase">{t('overview.arch.load')}</div> | |
| <div className="text-sm font-bold text-zinc-700">34%</div> | |
| </div> | |
| </div> | |
| <div className="flex items-center gap-3"> | |
| <div className="p-2 bg-zinc-200 rounded-lg text-zinc-500"><Cpu size={16} /></div> | |
| <div> | |
| <div className="text-[10px] text-zinc-400 font-bold uppercase">{t('overview.arch.latency')}</div> | |
| <div className="text-sm font-bold text-zinc-700">45ms</div> | |
| </div> | |
| </div> | |
| <div className="flex items-center gap-3"> | |
| <div className="p-2 bg-zinc-200 rounded-lg text-zinc-500"><HardDrive size={16} /></div> | |
| <div> | |
| <div className="text-[10px] text-zinc-400 font-bold uppercase">{t('overview.arch.storage')}</div> | |
| <div className="text-sm font-bold text-zinc-700">1.2GB</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| } | |