import { useEffect, useState } from 'react' import axios from 'axios' import { X, Bot, Tag, Target, Users, Plus, Trash2, Save } from 'lucide-react' import clsx from 'clsx' interface RoboticsSettingsProps { isOpen: boolean onClose: () => void apiBase: string } export function RoboticsSettings({ isOpen, onClose, apiBase }: RoboticsSettingsProps) { const [activeTab, setActiveTab] = useState<'robotics' | 'industries' | 'roles'>( localStorage.getItem('roboticsSettingsActiveTab') as 'robotics' | 'industries' | 'roles' || 'robotics' ) const [roboticsCategories, setRoboticsCategories] = useState([]) const [industries, setIndustries] = useState([]) const [jobRoles, setJobRoles] = useState([]) const [isLoading, setIsLoading] = useState(false); const fetchAllData = async () => { setIsLoading(true); try { const [resRobotics, resIndustries, resJobRoles] = await Promise.all([ axios.get(`${apiBase}/robotics/categories`), axios.get(`${apiBase}/industries`), axios.get(`${apiBase}/job_roles`), ]); setRoboticsCategories(resRobotics.data); setIndustries(resIndustries.data); setJobRoles(resJobRoles.data); } catch (e) { console.error("Failed to fetch settings data:", e); alert("Fehler beim Laden der Settings. Siehe Konsole."); } finally { setIsLoading(false); } }; useEffect(() => { if (isOpen) { fetchAllData(); } }, [isOpen]); useEffect(() => { localStorage.setItem('roboticsSettingsActiveTab', activeTab); }, [activeTab]); const handleUpdateRobotics = async (id: number, description: string, reasoning: string) => { setIsLoading(true); try { await axios.put(`${apiBase}/robotics/categories/${id}`, { description, reasoning_guide: reasoning }); fetchAllData(); } catch (e) { alert("Update failed"); console.error(e); } finally { setIsLoading(false); } } const handleAddJobRole = async () => { setIsLoading(true); try { await axios.post(`${apiBase}/job_roles`, { pattern: "New Pattern", role: "Operativer Entscheider" }); fetchAllData(); } catch (e) { alert("Failed to add job role"); console.error(e); } finally { setIsLoading(false); } } const handleDeleteJobRole = async (id: number) => { setIsLoading(true); try { await axios.delete(`${apiBase}/job_roles/${id}`); fetchAllData(); } catch (e) { alert("Failed to delete job role"); console.error(e); } finally { setIsLoading(false); } } if (!isOpen) return null return (
{/* Header */}

Settings & Classification Logic

Define how AI evaluates leads and matches roles.

{/* Tab Nav */}
{[ { id: 'robotics', label: 'Robotics Potential', icon: Bot }, { id: 'industries', label: 'Industry Focus', icon: Target }, { id: 'roles', label: 'Job Role Mapping', icon: Users }, ].map(t => ( ))}
{/* Content */}
{isLoading &&
Loading...
} {!isLoading && activeTab === 'robotics' && (
{roboticsCategories.map(cat => ( ))}
)} {!isLoading && activeTab === 'industries' && (

Industry Verticals (Synced from Notion)

{industries.map(ind => (
{ind.notion_id && (
SYNCED
)}

{ind.name}

{ind.status_notion && {ind.status_notion}}
{ind.is_focus ? "Focus" : "Standard"}

{ind.description || "No definition"}

Whale >{ind.whale_threshold || "-"}
Min Req{ind.min_requirement || "-"}
Unit{ind.scraper_search_term || "-"}
Product{roboticsCategories.find(c => c.id === ind.primary_category_id)?.name || "-"}
{ind.scraper_keywords &&
Keywords:{ind.scraper_keywords}
} {ind.standardization_logic &&
Standardization:{ind.standardization_logic}
}
))}
)} {!isLoading && activeTab === 'roles' && (

Job Title Mapping Patterns

{jobRoles.map(role => ( ))} {jobRoles.length === 0 && ()}
Job Title Pattern (Regex/Text)Mapped Role
No patterns defined yet.
)}
) } function CategoryCard({ category, onSave }: { category: any, onSave: any }) { const [desc, setDesc] = useState(category.description) const [guide, setGuide] = useState(category.reasoning_guide) const [isDirty, setIsDirty] = useState(false) useEffect(() => { setIsDirty(desc !== category.description || guide !== category.reasoning_guide) }, [desc, guide]) return (
{category.name}