1+ import React from 'react' ;
2+ import { Step } from '../types' ;
3+
4+ interface SetupEditorProps {
5+ step : Step ;
6+ onUpdateStep : ( stepId : string , patch : Partial < Step > ) => void ;
7+ }
8+
9+ export const SetupEditor : React . FC < SetupEditorProps > = ( { step, onUpdateStep } ) => {
10+ const setup = step . logic ?. setup || { } ;
11+ const nodeType = setup . nodeType || '' ;
12+
13+ // Check if this is a Performance Center step that can have different setup types
14+ const isPerformanceCenterStep = step . nodeType === 'PerformanceCenterScriptedStep' ;
15+ const isApproachSetup = nodeType === 'PerformanceCenterApproachScriptedSetup' ;
16+ const isTeeShotsSetup = nodeType === 'PerformanceCenterTeeShotsScriptedSetup' ;
17+ const isRangeAnalysisStep = step . nodeType === 'RangeAnalysisScriptedStep' ;
18+
19+ const updateSetup = ( setupPatch : any ) => {
20+ const newLogic = {
21+ ...step . logic ,
22+ setup : {
23+ ...setup ,
24+ ...setupPatch
25+ }
26+ } ;
27+ onUpdateStep ( step . id , { logic : newLogic } ) ;
28+ } ;
29+
30+ const switchSetupType = ( newNodeType : string ) => {
31+ let newSetup : any = { nodeType : newNodeType } ;
32+
33+ if ( newNodeType === 'PerformanceCenterApproachScriptedSetup' ) {
34+ newSetup = {
35+ ...newSetup ,
36+ hole : setup . hole || 1 ,
37+ pin : setup . pin || 1 ,
38+ playerCategory : setup . playerCategory || 'Handicap' ,
39+ hcp : setup . hcp || 0 ,
40+ gender : setup . gender || 'Unspecified' ,
41+ minDistance : setup . minDistance || 0 ,
42+ maxDistance : setup . maxDistance || 100
43+ } ;
44+ } else if ( newNodeType === 'PerformanceCenterTeeShotsScriptedSetup' ) {
45+ newSetup = {
46+ ...newSetup ,
47+ hole : setup . hole || 1 ,
48+ playerCategory : setup . playerCategory || 'Handicap' ,
49+ hcp : setup . hcp || 0 ,
50+ gender : setup . gender || 'Unspecified' ,
51+ courseDistance : setup . courseDistance || 5000
52+ } ;
53+ }
54+
55+ const newLogic = {
56+ ...step . logic ,
57+ setup : newSetup
58+ } ;
59+ onUpdateStep ( step . id , { logic : newLogic } ) ;
60+ } ;
61+
62+ if ( isRangeAnalysisStep ) {
63+ return (
64+ < div className = "setup-editor" >
65+ < h4 > Range Analysis Setup</ h4 >
66+ < div className = "edit-field" >
67+ < label >
68+ Club
69+ < select
70+ className = "cond-input"
71+ value = { setup . club || 'None' }
72+ onChange = { e => updateSetup ( { club : e . target . value } ) }
73+ >
74+ < option value = "None" > None</ option >
75+ < option value = "Drv" > Driver</ option >
76+ < option value = "_2W" > 2 Wood</ option >
77+ < option value = "_3W" > 3 Wood</ option >
78+ < option value = "_4W" > 4 Wood</ option >
79+ < option value = "_5W" > 5 Wood</ option >
80+ < option value = "_6W" > 6 Wood</ option >
81+ < option value = "_7W" > 7 Wood</ option >
82+ < option value = "_8W" > 8 Wood</ option >
83+ < option value = "_9W" > 9 Wood</ option >
84+ < option value = "_1H" > 1 Hybrid</ option >
85+ < option value = "_2H" > 2 Hybrid</ option >
86+ < option value = "_3H" > 3 Hybrid</ option >
87+ < option value = "_4H" > 4 Hybrid</ option >
88+ < option value = "_5H" > 5 Hybrid</ option >
89+ < option value = "_6H" > 6 Hybrid</ option >
90+ < option value = "_7H" > 7 Hybrid</ option >
91+ < option value = "_8H" > 8 Hybrid</ option >
92+ < option value = "_9H" > 9 Hybrid</ option >
93+ < option value = "_1I" > 1 Iron</ option >
94+ < option value = "_2I" > 2 Iron</ option >
95+ < option value = "_3I" > 3 Iron</ option >
96+ < option value = "_4I" > 4 Iron</ option >
97+ < option value = "_5I" > 5 Iron</ option >
98+ < option value = "_6I" > 6 Iron</ option >
99+ < option value = "_7I" > 7 Iron</ option >
100+ < option value = "_8I" > 8 Iron</ option >
101+ < option value = "_9I" > 9 Iron</ option >
102+ < option value = "_PW" > Pitching Wedge</ option >
103+ < option value = "_SW" > Sand Wedge</ option >
104+ < option value = "_LW" > Lob Wedge</ option >
105+ < option value = "_50W" > 50° Wedge</ option >
106+ < option value = "_52W" > 52° Wedge</ option >
107+ < option value = "_54W" > 54° Wedge</ option >
108+ < option value = "_56W" > 56° Wedge</ option >
109+ < option value = "_58W" > 58° Wedge</ option >
110+ < option value = "_60W" > 60° Wedge</ option >
111+ < option value = "Putt" > Putter</ option >
112+ </ select >
113+ </ label >
114+ </ div >
115+ < div className = "edit-field" >
116+ < label >
117+ Distance (meters)
118+ < input
119+ type = "number"
120+ min = "0"
121+ step = "0.1"
122+ value = { setup . distance || 0 }
123+ onChange = { e => updateSetup ( { distance : parseFloat ( e . target . value ) || 0 } ) }
124+ />
125+ </ label >
126+ </ div >
127+ </ div >
128+ ) ;
129+ }
130+
131+ if ( isPerformanceCenterStep ) {
132+ return (
133+ < div className = "setup-editor" >
134+ < h4 > Performance Center Setup</ h4 >
135+
136+ { /* Setup Type Switch */ }
137+ < div className = "edit-field" >
138+ < label > Setup Type</ label >
139+ < div className = "setup-type-switch" >
140+ < button
141+ className = { `setup-type-btn ${ isApproachSetup ? 'active' : '' } ` }
142+ onClick = { ( ) => switchSetupType ( 'PerformanceCenterApproachScriptedSetup' ) }
143+ >
144+ Approach Shots
145+ </ button >
146+ < button
147+ className = { `setup-type-btn ${ isTeeShotsSetup ? 'active' : '' } ` }
148+ onClick = { ( ) => switchSetupType ( 'PerformanceCenterTeeShotsScriptedSetup' ) }
149+ >
150+ Tee Shots
151+ </ button >
152+ </ div >
153+ </ div >
154+
155+ { /* Common Fields */ }
156+ < div className = "edit-field" >
157+ < label >
158+ Hole
159+ < input
160+ type = "number"
161+ min = "1"
162+ value = { setup . hole || 1 }
163+ onChange = { e => updateSetup ( { hole : parseInt ( e . target . value ) || 1 } ) }
164+ />
165+ </ label >
166+ </ div >
167+
168+ < div className = "edit-field" >
169+ < label >
170+ Player Category
171+ < select
172+ className = "cond-input"
173+ value = { setup . playerCategory || 'Handicap' }
174+ onChange = { e => updateSetup ( { playerCategory : e . target . value } ) }
175+ >
176+ < option value = "Handicap" > Handicap</ option >
177+ < option value = "PGA" > PGA</ option >
178+ < option value = "LPGA" > LPGA</ option >
179+ </ select >
180+ </ label >
181+ </ div >
182+
183+ { /* Handicap - only show for Handicap player category */ }
184+ { setup . playerCategory === 'Handicap' && (
185+ < div className = "edit-field" >
186+ < label >
187+ Handicap
188+ { isTeeShotsSetup ? (
189+ < select
190+ className = "cond-input"
191+ value = { setup . hcp || 0 }
192+ onChange = { e => updateSetup ( { hcp : parseInt ( e . target . value ) || 0 } ) }
193+ >
194+ { Array . from ( { length : 16 } , ( _ , i ) => (
195+ < option key = { i } value = { i } > { i } </ option >
196+ ) ) }
197+ </ select >
198+ ) : (
199+ < input
200+ type = "number"
201+ min = "-10"
202+ max = "54"
203+ value = { setup . hcp || 0 }
204+ onChange = { e => updateSetup ( { hcp : parseInt ( e . target . value ) || 0 } ) }
205+ />
206+ ) }
207+ </ label >
208+ </ div >
209+ ) }
210+
211+ < div className = "edit-field" >
212+ < label >
213+ Gender
214+ < select
215+ className = "cond-input"
216+ value = { setup . gender || 'Unspecified' }
217+ onChange = { e => updateSetup ( { gender : e . target . value } ) }
218+ >
219+ < option value = "Male" > Male</ option >
220+ < option value = "Female" > Female</ option >
221+ < option value = "Unspecified" > Unspecified</ option >
222+ </ select >
223+ </ label >
224+ </ div >
225+
226+ { /* Approach-specific fields */ }
227+ { isApproachSetup && (
228+ < >
229+ < div className = "edit-field" >
230+ < label >
231+ Pin
232+ < input
233+ type = "number"
234+ min = "1"
235+ value = { setup . pin || 1 }
236+ onChange = { e => updateSetup ( { pin : parseInt ( e . target . value ) || 1 } ) }
237+ />
238+ </ label >
239+ </ div >
240+ < div className = "edit-field" >
241+ < label >
242+ Min Distance (meters)
243+ < input
244+ type = "number"
245+ min = "0"
246+ step = "0.1"
247+ value = { setup . minDistance || 0 }
248+ onChange = { e => updateSetup ( { minDistance : parseFloat ( e . target . value ) || 0 } ) }
249+ />
250+ </ label >
251+ </ div >
252+ < div className = "edit-field" >
253+ < label >
254+ Max Distance (meters)
255+ < input
256+ type = "number"
257+ min = "0"
258+ step = "0.1"
259+ value = { setup . maxDistance || 100 }
260+ onChange = { e => updateSetup ( { maxDistance : parseFloat ( e . target . value ) || 100 } ) }
261+ />
262+ </ label >
263+ </ div >
264+ </ >
265+ ) }
266+
267+ { /* Tee shots specific fields */ }
268+ { isTeeShotsSetup && (
269+ < div className = "edit-field" >
270+ < label >
271+ Course Distance (meters)
272+ < input
273+ type = "number"
274+ min = "1000"
275+ max = "9000"
276+ value = { setup . courseDistance || 5000 }
277+ onChange = { e => updateSetup ( { courseDistance : parseInt ( e . target . value ) || 5000 } ) }
278+ />
279+ </ label >
280+ </ div >
281+ ) }
282+ </ div >
283+ ) ;
284+ }
285+
286+ return null ;
287+ } ;
0 commit comments