import React, { useState, useEffect } from 'react'; import { ChevronDown, Plus, Info, MessageSquare, BookOpen, LogOut, PanelLeftClose, MessageCircle, Menu, PanelRightClose, RefreshCw } from 'lucide-react'; import SimulationGraph from './SimulationGraph'; import { GradioService } from '../services/gradioService'; interface SimulationPageProps { onBack: () => void; onOpenChat: () => void; onOpenGuide: () => void; user?: any; onLogin?: () => void; onLogout?: () => void; simulationResult: any; setSimulationResult: (res: any) => void; } // Define the data structure for filters const VIEW_FILTERS: Record> = { 'Country': [ { label: "United States", color: "bg-blue-600" }, { label: "United Kingdom", color: "bg-purple-600" }, { label: "Netherlands", color: "bg-teal-600" }, { label: "France", color: "bg-orange-600" }, { label: "India", color: "bg-pink-600" } ], 'Job Title': [ { label: "Founder", color: "bg-indigo-500" }, { label: "Product Manager", color: "bg-emerald-500" }, { label: "Engineer", color: "bg-rose-500" }, { label: "Investor", color: "bg-amber-500" }, { label: "Designer", color: "bg-fuchsia-500" } ], 'Sentiment': [ { label: "Positive", color: "bg-green-500" }, { label: "Neutral", color: "bg-gray-500" }, { label: "Negative", color: "bg-red-500" }, { label: "Mixed", color: "bg-yellow-500" } ], 'Activity Level': [ { label: "Power User", color: "bg-red-600" }, { label: "Daily Active", color: "bg-orange-500" }, { label: "Weekly Active", color: "bg-blue-500" }, { label: "Lurker", color: "bg-slate-600" } ] }; const SimulationPage: React.FC = ({ onBack, onOpenChat, onOpenGuide, user, onLogin, onLogout, simulationResult, setSimulationResult }) => { const [society, setSociety] = useState(''); const [societies, setSocieties] = useState([]); const [viewMode, setViewMode] = useState('Job Title'); const [isRefreshing, setIsRefreshing] = useState(false); const [isBuilding, setIsBuilding] = useState(false); const [isRightPanelOpen, setIsRightPanelOpen] = useState(window.innerWidth > 1200); const [isLeftPanelOpen, setIsLeftPanelOpen] = useState(window.innerWidth > 768); const [activeModal, setActiveModal] = useState<'none' | 'assemble' | 'feedback' | 'context' | 'test'>('none'); const [formData, setFormData] = useState({ customerProfile: '', companyInfo: '', personaScale: 50, feedback: '', context: '', testName: '' }); // Handle window resize for mobile responsiveness useEffect(() => { const handleResize = () => { if (window.innerWidth < 768) { setIsLeftPanelOpen(false); setIsRightPanelOpen(false); } }; window.addEventListener('resize', handleResize); // Fetch real focus groups const fetchSocieties = async () => { try { let names: string[] = []; // 1. Fetch from Gradio (Templates/Global) const result = await GradioService.listSimulations(); const list = Array.isArray(result) ? result : (result?.data?.[0] || []); // GradioService now returns the array of focus group objects directly if (Array.isArray(list)) { const gradioNames = list .map((s: any) => { if (typeof s === 'string') return s; if (typeof s === 'object' && s !== null) return s.id || s.name || ''; return ''; }) // Filter out non-user groups as requested .filter(name => name.length > 0 && !name.toLowerCase().includes('default') && !name.toLowerCase().includes('template') && !name.toLowerCase().includes('current')); names = [...gradioNames]; } // 2. Fetch User-created groups from local storage if (user?.preferred_username) { try { const localResp = await fetch(`/api/list-data?type=assemble&user=${user.preferred_username}`); if (localResp.ok) { const localData = await localResp.json(); const localNames = localData.map((d: any) => d.data.customerProfile.substring(0, 20) + '...'); names = [...names, ...localNames]; } } catch (e) { console.error("Failed to fetch local groups", e); } } // Remove duplicates const uniqueNames = Array.from(new Set(names)); setSocieties(uniqueNames); if (uniqueNames.length > 0) { if (!society || !uniqueNames.includes(society)) { setSociety(uniqueNames[0]); } } else { setSociety('Standard Example'); } } catch (e) { console.error("Failed to fetch focus groups", e); } }; fetchSocieties(); return () => window.removeEventListener('resize', handleResize); }, []); // Function to simulate rebuilding the graph when settings change const handleSettingChange = (setter: (val: string) => void, value: string) => { if (value === society || (value === viewMode && setter === setViewMode)) return; // No change setter(value); setIsBuilding(true); // Simulate network delay setTimeout(() => { setIsBuilding(false); }, 1500); }; const currentFilters = VIEW_FILTERS[viewMode] || VIEW_FILTERS['Country']; return (
{/* Sidebar */} {/* Main Content Area */}
{/* Top Navigation Overlay */}
{/* Left Toggle (when sidebar closed) */} {/* Right Toggle (when output closed) */}
{/* Legend / Filter Chips */}
{currentFilters.map((filter, idx) => ( ))}
{/* Graph Container */}
{/* Modals */} {activeModal !== 'none' && (

{activeModal === 'assemble' && "Assemble New Group"} {activeModal === 'feedback' && "Leave Feedback"} {activeModal === 'context' && "Request New Context"} {activeModal === 'test' && "Create New Test"}

{activeModal === 'assemble' && ( <>