Spaces:
Configuration error
Configuration error
| /** | |
| * CommandPillar.tsx — 4 Pillar Navigation System | |
| * Sostituisce il menu laterale con 4 bottoni principali (Pillar) che espandono sottocategorie logiche. | |
| * | |
| * Pillar 1: 🔍 RICERCA & ANALISI | |
| * - Web Search, News, Meteo, Analisi Dati | |
| * | |
| * Pillar 2: 💻 SVILUPPO & CODING | |
| * - Code Review, Refactor, Debug, Test | |
| * | |
| * Pillar 3: 🤖 AUTOMAZIONE & TASK | |
| * - Task Automation, Workflow, Scheduling, Integration | |
| * | |
| * Pillar 4: 🎨 CREATIVITÀ & CONTENUTI | |
| * - Generazione Testo, Immagini, Audio, Brainstorming | |
| */ | |
| import React, { useState } from "react"; | |
| import { Search, Code2, Zap, Sparkles, ChevronDown, X } from "lucide-react"; | |
| export interface PillarCommand { | |
| id: string; | |
| label: string; | |
| description?: string; | |
| icon?: React.ReactNode; | |
| shortcut?: string; | |
| action: () => void; | |
| } | |
| export interface Pillar { | |
| id: string; | |
| name: string; | |
| icon: React.ReactNode; | |
| color: string; | |
| commands: PillarCommand[]; | |
| } | |
| interface CommandPillarProps { | |
| onCommandSelect: (cmd: PillarCommand) => void; | |
| isOpen?: boolean; | |
| onClose?: () => void; | |
| } | |
| const PILLARS: Pillar[] = [ | |
| { | |
| id: "search", | |
| name: "Ricerca & Analisi", | |
| icon: <Search size={20} />, | |
| color: "#3b82f6", | |
| commands: [ | |
| { id: "web-search", label: "Web Search", description: "Cerca il web in tempo reale", action: () => {} }, | |
| { id: "news", label: "Notizie", description: "Ultime notizie e trend", action: () => {} }, | |
| { id: "weather", label: "Meteo", description: "Previsioni meteo per città", action: () => {} }, | |
| { id: "data-analysis", label: "Analisi Dati", description: "Elabora e visualizza dati", action: () => {} }, | |
| ], | |
| }, | |
| { | |
| id: "coding", | |
| name: "Sviluppo & Coding", | |
| icon: <Code2 size={20} />, | |
| color: "#10b981", | |
| commands: [ | |
| { id: "code-review", label: "Code Review", description: "Analizza e migliora codice", action: () => {} }, | |
| { id: "refactor", label: "Refactor", description: "Rifattorizza il codice", action: () => {} }, | |
| { id: "debug", label: "Debug", description: "Trova e risolvi bug", action: () => {} }, | |
| { id: "test", label: "Test", description: "Genera test e verifica", action: () => {} }, | |
| ], | |
| }, | |
| { | |
| id: "automation", | |
| name: "Automazione & Task", | |
| icon: <Zap size={20} />, | |
| color: "#f59e0b", | |
| commands: [ | |
| { id: "task-auto", label: "Task Automation", description: "Automatizza compiti ripetitivi", action: () => {} }, | |
| { id: "workflow", label: "Workflow", description: "Crea flussi di lavoro", action: () => {} }, | |
| { id: "scheduling", label: "Scheduling", description: "Pianifica esecuzioni", action: () => {} }, | |
| { id: "integration", label: "Integrazione", description: "Connetti servizi esterni", action: () => {} }, | |
| ], | |
| }, | |
| { | |
| id: "creative", | |
| name: "Creatività & Contenuti", | |
| icon: <Sparkles size={20} />, | |
| color: "#a855f7", | |
| commands: [ | |
| { id: "text-gen", label: "Generazione Testo", description: "Crea contenuti scritti", action: () => {} }, | |
| { id: "image-gen", label: "Generazione Immagini", description: "Crea immagini con IA", action: () => {} }, | |
| { id: "audio-gen", label: "Generazione Audio", description: "Crea audio e musica", action: () => {} }, | |
| { id: "brainstorm", label: "Brainstorming", description: "Genera idee creative", action: () => {} }, | |
| ], | |
| }, | |
| ]; | |
| export const CommandPillar: React.FC<CommandPillarProps> = ({ onCommandSelect, isOpen = false, onClose }) => { | |
| const [expandedPillar, setExpandedPillar] = useState<string | null>(null); | |
| const handlePillarClick = (pillarId: string) => { | |
| setExpandedPillar(expandedPillar === pillarId ? null : pillarId); | |
| }; | |
| const handleCommandClick = (cmd: PillarCommand) => { | |
| onCommandSelect(cmd); | |
| setExpandedPillar(null); | |
| onClose?.(); | |
| }; | |
| if (!isOpen) return null; | |
| return ( | |
| <div | |
| style={{ | |
| position: "fixed", | |
| inset: 0, | |
| background: "rgba(0,0,0,0.5)", | |
| display: "flex", | |
| alignItems: "flex-end", | |
| zIndex: 1000, | |
| animation: "fadeIn 0.2s ease-out", | |
| }} | |
| onClick={onClose} | |
| > | |
| <div | |
| style={{ | |
| background: "var(--bg-secondary)", | |
| borderRadius: "16px 16px 0 0", | |
| width: "100%", | |
| maxWidth: "600px", | |
| maxHeight: "80vh", | |
| overflowY: "auto", | |
| padding: "16px", | |
| boxShadow: "0 -4px 20px rgba(0,0,0,0.3)", | |
| animation: "slideUp 0.3s ease-out", | |
| }} | |
| onClick={(e) => e.stopPropagation()} | |
| > | |
| {/* Header */} | |
| <div | |
| style={{ | |
| display: "flex", | |
| justifyContent: "space-between", | |
| alignItems: "center", | |
| marginBottom: "16px", | |
| paddingBottom: "12px", | |
| borderBottom: "1px solid rgba(99,102,241,0.1)", | |
| }} | |
| > | |
| <h2 style={{ margin: 0, fontSize: "1.2rem", fontWeight: 600 }}>Comandi Rapidi</h2> | |
| <button | |
| onClick={onClose} | |
| style={{ | |
| background: "none", | |
| border: "none", | |
| cursor: "pointer", | |
| color: "var(--text-dim)", | |
| padding: "4px", | |
| display: "flex", | |
| alignItems: "center", | |
| justifyContent: "center", | |
| }} | |
| > | |
| <X size={20} /> | |
| </button> | |
| </div> | |
| {/* Pillars */} | |
| <div style={{ display: "flex", flexDirection: "column", gap: "8px" }}> | |
| {PILLARS.map((pillar) => ( | |
| <div key={pillar.id}> | |
| {/* Pillar Button */} | |
| <button | |
| onClick={() => handlePillarClick(pillar.id)} | |
| style={{ | |
| width: "100%", | |
| display: "flex", | |
| alignItems: "center", | |
| gap: "12px", | |
| padding: "12px 16px", | |
| background: expandedPillar === pillar.id ? `${pillar.color}20` : "rgba(99,102,241,0.05)", | |
| border: expandedPillar === pillar.id ? `2px solid ${pillar.color}` : "1px solid rgba(99,102,241,0.1)", | |
| borderRadius: "12px", | |
| cursor: "pointer", | |
| transition: "all 0.2s ease", | |
| color: expandedPillar === pillar.id ? pillar.color : "var(--text-primary)", | |
| fontWeight: expandedPillar === pillar.id ? 600 : 500, | |
| fontSize: "1rem", | |
| }} | |
| > | |
| <div style={{ color: pillar.color, display: "flex", alignItems: "center" }}> | |
| {pillar.icon} | |
| </div> | |
| <span style={{ flex: 1, textAlign: "left" }}>{pillar.name}</span> | |
| <ChevronDown | |
| size={18} | |
| style={{ | |
| transform: expandedPillar === pillar.id ? "rotate(180deg)" : "rotate(0deg)", | |
| transition: "transform 0.2s ease", | |
| }} | |
| /> | |
| </button> | |
| {/* Expanded Commands */} | |
| {expandedPillar === pillar.id && ( | |
| <div | |
| style={{ | |
| display: "flex", | |
| flexDirection: "column", | |
| gap: "6px", | |
| padding: "8px 0 0 0", | |
| animation: "slideDown 0.2s ease-out", | |
| }} | |
| > | |
| {pillar.commands.map((cmd) => ( | |
| <button | |
| key={cmd.id} | |
| onClick={() => handleCommandClick(cmd)} | |
| style={{ | |
| display: "flex", | |
| flexDirection: "column", | |
| gap: "4px", | |
| padding: "10px 16px", | |
| marginLeft: "12px", | |
| background: "rgba(99,102,241,0.08)", | |
| border: "1px solid rgba(99,102,241,0.15)", | |
| borderRadius: "8px", | |
| cursor: "pointer", | |
| transition: "all 0.15s ease", | |
| textAlign: "left", | |
| color: "var(--text-primary)", | |
| }} | |
| onMouseEnter={(e) => { | |
| (e.currentTarget as HTMLButtonElement).style.background = `${pillar.color}25`; | |
| (e.currentTarget as HTMLButtonElement).style.borderColor = pillar.color; | |
| }} | |
| onMouseLeave={(e) => { | |
| (e.currentTarget as HTMLButtonElement).style.background = "rgba(99,102,241,0.08)"; | |
| (e.currentTarget as HTMLButtonElement).style.borderColor = "rgba(99,102,241,0.15)"; | |
| }} | |
| > | |
| <span style={{ fontWeight: 500, fontSize: "0.95rem" }}>{cmd.label}</span> | |
| {cmd.description && ( | |
| <span style={{ fontSize: "0.8rem", color: "var(--text-dim)" }}> | |
| {cmd.description} | |
| </span> | |
| )} | |
| </button> | |
| ))} | |
| </div> | |
| )} | |
| </div> | |
| ))} | |
| </div> | |
| </div> | |
| <style>{` | |
| @keyframes fadeIn { | |
| from { opacity: 0; } | |
| to { opacity: 1; } | |
| } | |
| @keyframes slideUp { | |
| from { transform: translateY(100%); } | |
| to { transform: translateY(0); } | |
| } | |
| @keyframes slideDown { | |
| from { opacity: 0; max-height: 0; } | |
| to { opacity: 1; max-height: 500px; } | |
| } | |
| `}</style> | |
| </div> | |
| ); | |
| }; | |
| export default CommandPillar; | |