| import { useEffect, useState } from 'react'; |
|
|
| interface RadioNavProps { |
| active: string; |
| onNavigate: (id: string) => void; |
| } |
|
|
| const items = [ |
| { |
| id: 'dashboard', |
| label: 'Dashboard', |
| icon: ( |
| <path d="M4 13h6a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1zm-1 7a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1v-4a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v4zm10 0a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1v-7a1 1 0 0 0-1-1h-6a1 1 0 0 0-1 1v7zm1-10h6a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1h-6a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1z" /> |
| ), |
| }, |
| { |
| id: 'analyze', |
| label: 'Analyze', |
| icon: ( |
| <path d="M12 2a5 5 0 1 0 5 5 5 5 0 0 0-5-5zm0 8a3 3 0 1 1 3-3 3 3 0 0 1-3 3zm9 11v-1a7 7 0 0 0-7-7h-4a7 7 0 0 0-7 7v1h2v-1a5 5 0 0 1 5-5h4a5 5 0 0 1 5 5v1z" /> |
| ), |
| }, |
| { |
| id: 'pricing', |
| label: 'Pricing', |
| icon: ( |
| <path d="M5 18v3.766l1.515-.909L11.277 18H16c1.103 0 2-.897 2-2V8c0-1.103-.897-2-2-2H4c-1.103 0-2 .897-2 2v8c0 1.103.897 2 2 2h1zM4 8h12v8h-5.277L7 18.234V16H4V8zm16-6H8c-1.103 0-2 .897-2 2h12c1.103 0 2 .897 2 2v8c1.103 0 2-.897 2-2V4c0-1.103-.897-2-2-2z" /> |
| ), |
| }, |
| { |
| id: 'agents', |
| label: 'Agents', |
| icon: ( |
| <path d="M11.953 2C6.465 2 2 6.486 2 12s4.486 10 10 10 10-4.486 10-10S17.493 2 11.953 2zM12 20c-4.411 0-8-3.589-8-8s3.567-8 7.953-8C16.391 4 20 7.589 20 12s-3.589 8-8 8zm-1-5h2v2h-2zm0-8h2v6h-2z" /> |
| ), |
| }, |
| { |
| id: 'settings', |
| label: 'Settings', |
| icon: ( |
| <> |
| <path d="M12 16c2.206 0 4-1.794 4-4s-1.794-4-4-4-4 1.794-4 4 1.794 4 4 4zm0-6c1.084 0 2 .916 2 2s-.916 2-2 2-2-.916-2-2 .916-2 2-2z" /> |
| <path d="m2.845 16.136 1 1.73c.531.917 1.809 1.261 2.73.73l.529-.306A8.1 8.1 0 0 0 9 19.402V20c0 1.103.897 2 2 2h2c1.103 0 2-.897 2-2v-.598a8.132 8.132 0 0 0 1.896-1.111l.529.306c.923.53 2.198.188 2.731-.731l.999-1.729a2.001 2.001 0 0 0-.731-2.732l-.505-.292a7.718 7.718 0 0 0 0-2.224l.505-.292a2.002 2.002 0 0 0 .731-2.732l-.999-1.729c-.531-.92-1.808-1.265-2.731-.732l-.529.306A8.1 8.1 0 0 0 15 4.598V4c0-1.103-.897-2-2-2h-2c-1.103 0-2 .897-2 2v.598a8.132 8.132 0 0 0-1.896 1.111l-.529-.306c-.924-.531-2.2-.187-2.731.732l-.999 1.729a2.001 2.001 0 0 0 .731 2.732l.505.292a7.683 7.683 0 0 0 0 2.223l-.505.292a2.003 2.003 0 0 0-.731 2.733zm3.326-2.758A5.703 5.703 0 0 1 6 12c0-.462.058-.926.17-1.378a.999.999 0 0 0-.47-1.108l-1.123-.65.998-1.729 1.145.662a.997.997 0 0 0 1.188-.142 6.071 6.071 0 0 1 2.384-1.399A1 1 0 0 0 11 5.3V4h2v1.3a1 1 0 0 0 .708.956 6.083 6.083 0 0 1 2.384 1.399.999.999 0 0 0 1.188.142l1.144-.661 1 1.729-1.124.649a1 1 0 0 0-.47 1.108c.112.452.17.916.17 1.378 0 .461-.058.925-.171 1.378a1 1 0 0 0 .471 1.108l1.123.649-.998 1.729-1.145-.661a.996.996 0 0 0-1.188.142 6.071 6.071 0 0 1-2.384 1.399A1 1 0 0 0 13 18.7l.002 1.3H11v-1.3a1 1 0 0 0-.708-.956 6.083 6.083 0 0 1-2.384-1.399.992.992 0 0 0-1.188-.141l-1.144.662-1-1.729 1.124-.651a1 1 0 0 0 .471-1.108z" /> |
| </> |
| ), |
| }, |
| ]; |
|
|
| export default function RadioNav({ active, onNavigate }: RadioNavProps) { |
| const [hovered, setHovered] = useState<string | null>(null); |
|
|
| |
| useEffect(() => { |
| const el = document.getElementById(active) as HTMLInputElement | null; |
| if (el) el.checked = true; |
| }, [active]); |
|
|
| return ( |
| <div className="fixed top-4 left-1/2 z-50 -translate-x-1/2 transition-all duration-450 ease-in-out w-auto px-4"> |
| <article |
| className="flex rounded-2xl overflow-hidden" |
| style={{ |
| background: '#0d0720', |
| border: '1px solid rgba(168,85,247,0.18)', |
| boxShadow: '0 8px 32px rgba(0,0,0,0.5), 0 0 0 1px rgba(88,28,135,0.15)', |
| }} |
| > |
| {items.map(item => { |
| const isActive = active === item.id; |
| const isHovered = hovered === item.id; |
| |
| return ( |
| <label |
| key={item.id} |
| htmlFor={item.id} |
| className="relative flex flex-col items-center justify-center cursor-pointer select-none transition-all duration-300" |
| style={{ |
| width: 72, |
| height: 64, |
| padding: '8px 4px 4px', |
| gap: 4, |
| borderRadius: 12, |
| background: isActive |
| ? 'rgba(124,58,237,0.25)' |
| : isHovered |
| ? 'rgba(88,28,135,0.15)' |
| : 'transparent', |
| boxShadow: isActive |
| ? 'inset 0 1px 0 rgba(192,132,252,0.15), 0 0 16px rgba(124,58,237,0.2)' |
| : 'none', |
| borderBottom: isActive ? '2px solid rgba(168,85,247,0.7)' : '2px solid transparent', |
| }} |
| onMouseEnter={() => setHovered(item.id)} |
| onMouseLeave={() => setHovered(null)} |
| onClick={() => onNavigate(item.id)} |
| > |
| <input |
| id={item.id} |
| name="nav" |
| type="radio" |
| className="hidden" |
| defaultChecked={isActive} |
| /> |
| |
| <svg |
| viewBox="0 0 24 24" |
| width={20} |
| height={20} |
| xmlns="http://www.w3.org/2000/svg" |
| style={{ |
| fill: isActive ? '#c084fc' : isHovered ? '#a855f7' : 'rgba(168,85,247,0.35)', |
| filter: isActive ? 'drop-shadow(0 0 6px rgba(192,132,252,0.7))' : 'none', |
| transform: isActive || isHovered ? 'scale(1.2)' : 'scale(1)', |
| transition: 'all 0.3s ease', |
| }} |
| > |
| {item.icon} |
| </svg> |
| |
| <span |
| className="font-bold uppercase tracking-wider" |
| style={{ |
| fontSize: 8, |
| letterSpacing: '0.08em', |
| color: isActive ? '#c084fc' : isHovered ? '#a855f7' : 'rgba(168,85,247,0.3)', |
| transition: 'color 0.3s ease', |
| }} |
| > |
| {item.label} |
| </span> |
| </label> |
| ); |
| })} |
| </article> |
| </div> |
| ); |
| } |
|
|