1+ import React from 'react' ;
2+ import { Button } from "@/components/ui/button" ;
3+ import { Input } from "@/components/ui/input" ;
4+ import { Label } from "@/components/ui/label" ;
5+ import { Info , ChevronDown , ChevronUp } from "lucide-react" ;
6+
7+ interface SearchParams {
8+ startingUrl : string ;
9+ goal : string ;
10+ iterations : number ;
11+ }
12+
13+ interface ControlPanelProps {
14+ searchParams : SearchParams ;
15+ handleParamChange : ( param : keyof SearchParams , value : string | boolean | number ) => void ;
16+ handleStart : ( ) => void ;
17+ disconnect : ( ) => void ;
18+ isSearching : boolean ;
19+ connected : boolean ;
20+ }
21+
22+ const ControlPanelMCTS : React . FC < ControlPanelProps > = ( {
23+ searchParams,
24+ handleParamChange,
25+ handleStart,
26+ disconnect,
27+ isSearching,
28+ connected,
29+ } ) => {
30+ const [ showParameters , setShowParameters ] = React . useState ( true ) ;
31+
32+ return (
33+ < div className = "bg-white dark:bg-slate-800 shadow-sm border-b sticky top-0 z-10" >
34+ < div className = "py-3 px-4 max-w-full" >
35+ < div className = "flex justify-between items-center" >
36+ < h1 className = "text-2xl font-bold text-sky-950 dark:text-sky-100" > Visual Tree Search: RMCTS</ h1 >
37+
38+ < div className = "flex gap-2" >
39+ < Button
40+ onClick = { handleStart }
41+ disabled = { isSearching }
42+ className = "bg-cyan-600 hover:bg-cyan-700 text-white disabled:bg-cyan-300 dark:disabled:bg-cyan-900"
43+ >
44+ Start
45+ </ Button >
46+ < Button
47+ onClick = { disconnect }
48+ disabled = { ! connected }
49+ variant = "destructive"
50+ className = "bg-rose-600 hover:bg-rose-700 text-white"
51+ >
52+ End
53+ </ Button >
54+ </ div >
55+ </ div >
56+
57+ < div className = "mt-3 bg-sky-50 dark:bg-sky-900/20 border border-sky-200 dark:border-sky-800 rounded-lg overflow-hidden" >
58+ < div
59+ className = "p-3 flex justify-between items-center cursor-pointer hover:bg-sky-100 dark:hover:bg-sky-900/30 transition-colors"
60+ onClick = { ( ) => setShowParameters ( ! showParameters ) }
61+ >
62+ < div className = "flex items-start gap-2" >
63+ < Info className = "h-5 w-5 text-cyan-600 dark:text-cyan-400 flex-shrink-0 mt-0.5" />
64+ < div >
65+ < h3 className = "font-medium text-sky-800 dark:text-sky-300" > How to use this playground</ h3 >
66+ < p className = "text-sm text-sky-700 dark:text-sky-400" >
67+ Configure your search parameters and visualize web browsing automation with tree search algorithms.
68+ </ p >
69+ </ div >
70+ </ div >
71+ { showParameters ? < ChevronUp className = "text-cyan-600" /> : < ChevronDown className = "text-cyan-600" /> }
72+ </ div >
73+
74+ { showParameters && (
75+ < div className = "p-4 border-t border-sky-200 dark:border-sky-800 bg-white/90 dark:bg-slate-800/90" >
76+ { /* Instructions */ }
77+ < div className = "mb-4 ml-1 text-sm text-slate-700 dark:text-slate-300" >
78+ < ol className = "list-decimal list-inside space-y-1" >
79+ < li > Click the "Start" button above to connect and begin the search.</ li >
80+ < li > Configure your search parameters below.</ li >
81+ < li > The tree of possible actions will appear on the right, while the resulting web page will display on the left.</ li >
82+ < li > You can drag the divider to resize the panels as needed.</ li >
83+ </ ol >
84+ </ div >
85+
86+ { /* Parameters Grid */ }
87+ < div className = "grid grid-cols-1 md:grid-cols-4 gap-4 mt-4" >
88+ < div className = "space-y-2" >
89+ < Label htmlFor = "startingUrl" className = "text-slate-700 dark:text-slate-300 font-medium" > Starting URL</ Label >
90+ < Input
91+ id = "startingUrl"
92+ value = { searchParams . startingUrl }
93+ onChange = { ( e ) => handleParamChange ( 'startingUrl' , e . target . value ) }
94+ className = "border-slate-300 dark:border-slate-600 focus:ring-cyan-500 focus:border-cyan-500"
95+ />
96+ </ div >
97+
98+ < div className = "space-y-2" >
99+ < Label htmlFor = "goal" className = "text-slate-700 dark:text-slate-300 font-medium" > Goal</ Label >
100+ < Input
101+ id = "goal"
102+ value = { searchParams . goal }
103+ onChange = { ( e ) => handleParamChange ( 'goal' , e . target . value ) }
104+ className = "border-slate-300 dark:border-slate-600 focus:ring-cyan-500 focus:border-cyan-500"
105+ />
106+ </ div >
107+
108+ < div className = "space-y-2" >
109+ < Label htmlFor = "iterations" className = "text-slate-700 dark:text-slate-300 font-medium" > Iterations</ Label >
110+ < Input
111+ id = "iterations"
112+ type = "number"
113+ min = { 1 }
114+ max = { 10 }
115+ value = { searchParams . iterations }
116+ onChange = { ( e ) => handleParamChange ( 'iterations' , parseInt ( e . target . value ) ) }
117+ className = "border-slate-300 dark:border-slate-600 focus:ring-cyan-500 focus:border-cyan-500"
118+ />
119+ </ div >
120+ </ div >
121+ </ div >
122+ ) }
123+ </ div >
124+ </ div >
125+ </ div >
126+ ) ;
127+ } ;
128+
129+ export default ControlPanelMCTS ;
0 commit comments