import { useEffect, useState } from 'react'; import type { ConditionKind, Entrance, FurniturePreset, LayoutState, RoomConfig } from '../types'; import { NumberField } from './NumberField'; interface ControlPanelProps { state: LayoutState; onStateChange: (state: LayoutState) => void; mode: 'layout' | 'optimize'; onModeChange: (mode: 'layout' | 'optimize') => void; selectedId: string | null; onSelect: (id: string | null) => void; onOptimize: () => void; optimizing: boolean; timeLeft: number; } const CONDITION_KINDS: ConditionKind[] = [ 'walk_to_and_sit', 'around_open_area', 'near_entrance', 'near_object', 'accessible', 'not_blocking_path', 'open_circulation', ]; const CONDITION_LABELS: Record = { walk_to_and_sit: 'Walk to and sit', around_open_area: 'Around open area', near_entrance: 'Near entrance', near_object: 'Near object', accessible: 'Accessible', not_blocking_path: 'Not blocking path', open_circulation: 'Open circulation', }; const SWATCHES = ['#a1887f', '#d7ccc5', '#90caf9', '#a5d6a7', '#ef9a9a', '#ce93d8', '#ffcc80']; export function ControlPanel({ state, onStateChange, mode, onModeChange, selectedId, onSelect, onOptimize, optimizing, timeLeft, }: ControlPanelProps) { const [openId, setOpenId] = useState(null); const objects = state.presets || []; const selectedTypeId = selectedId ? state.furniture.find((f) => f.id === selectedId)?.type ?? (selectedId === '__entrance__' ? '__entrance__' : null) : null; useEffect(() => { if (selectedTypeId) setOpenId(selectedTypeId); }, [selectedTypeId]); const setRoom = (room: Partial) => onStateChange({ ...state, room: { ...state.room, ...room } }); const setEntrance = (entrance: Partial) => { if (!state.entrance) return; onStateChange({ ...state, entrance: { ...state.entrance, ...entrance } }); }; const placeEntrance = () => onStateChange({ ...state, entrance: { x: 20, y: 20, width: 20, height: 20 } }); const updateObject = (id: string, patch: Partial) => { const presets = objects.map((p) => (p.id === id ? { ...p, ...patch } : p)); onStateChange({ ...state, presets }); }; const setAmount = (id: string, amount: number) => updateObject(id, { amount: Math.max(0, amount) }); const removeObject = (id: string) => { onStateChange({ ...state, presets: objects.filter((p) => p.id !== id), furniture: state.furniture.filter((f) => f.type !== id), }); }; const createObject = () => { const id = 'obj_' + Date.now(); const newObject: FurniturePreset = { id, name: 'Object ' + (objects.filter((o) => !o.isPreset).length + 1), color: SWATCHES[objects.length % SWATCHES.length], amount: 1, isPreset: false, shape: { type: 'rectangle', width: 50, height: 50 }, conditions: [ { kind: 'walk_to_and_sit', weight: 1 }, { kind: 'accessible', weight: 1 }, ], }; onStateChange({ ...state, presets: [...objects, newObject] }); onSelect(id); setOpenId(id); }; const toggleObjectCondition = (id: string, k: ConditionKind, enabled: boolean) => { const presets = objects.map((p) => { if (p.id !== id) return p; const has = p.conditions.some((c) => c.kind === k); if (enabled && !has) { const params = k === 'near_object' ? { targetId: '' } : {}; return { ...p, conditions: [...p.conditions, { kind: k, weight: 1, params }] }; } if (!enabled && has) { return { ...p, conditions: p.conditions.filter((c) => c.kind !== k) }; } return p; }); onStateChange({ ...state, presets }); }; const setNearObjectTarget = (id: string, targetId: string) => { const presets = objects.map((p) => { if (p.id !== id) return p; return { ...p, conditions: p.conditions.map((c) => c.kind === 'near_object' ? { ...c, params: { ...c.params, targetId } } : c, ), }; }); onStateChange({ ...state, presets }); }; const toggleOpen = (id: string) => { onSelect(id === '__entrance__' ? '__entrance__' : id); setOpenId((cur) => (cur === id ? null : id)); }; const renderObjectCard = (p: FurniturePreset) => { const open = openId === p.id; return (
toggleOpen(p.id)}> ▶ {p.name} e.stopPropagation()}> setAmount(p.id, v)} />
{open && (
{!p.isPreset && ( )}
Color
{SWATCHES.map((c) => (
Conditions
{CONDITION_KINDS.map((k) => { const active = p.conditions.some((c) => c.kind === k); const targetId = (p.conditions.find((c) => c.kind === k)?.params as { targetId?: string } | undefined) ?.targetId; return (
{k === 'near_object' && active && ( )}
); })}
{!p.isPreset && ( )}
)}
); }; return ( ); }