@@ -49,6 +49,20 @@ export function Lobby() {
49
49
let stompClient = useContext ( StompContext )
50
50
let navigate = useNavigate ( )
51
51
let auth = useAuthStore ( state => state . auth )
52
+ let newGameRef = useRef ( )
53
+ let onClickOutside = useCallback ( ( event ) => {
54
+ if ( ! isNewGameOpen ) {
55
+ return
56
+ }
57
+ let el = newGameRef . current
58
+ if ( ! el ) {
59
+ return
60
+ }
61
+ let rect = el . getBoundingClientRect ( )
62
+ if ( event . clientX > rect . right || event . clientX < rect . left || event . clientY > rect . bottom || event . clientY < rect . top ) {
63
+ setNewGameOpen ( false )
64
+ }
65
+ } , [ isNewGameOpen ] )
52
66
let onNewGame = useCallback ( ( d ) => doTry ( async ( ) => {
53
67
let response = await tfetch ( "/api/create" , {
54
68
method : "POST" ,
@@ -77,28 +91,31 @@ export function Lobby() {
77
91
navigate ( base + "/game/" + response . id )
78
92
} ) , [ auth , navigate ] )
79
93
return (
80
- < div className = "h-full" >
94
+ < div onClick = { onClickOutside } className = "h-full" >
81
95
< div className = { twJoin (
82
- "mt-2 inline-flex py-2 pr-4 gap-x-1 border-r-2 border-y-2 " ,
83
- isNewGameOpen && "rounded-r-full border-slate-600 " ,
96
+ "mt-2 py-2 pr-4 gap-x-1" ,
97
+ isNewGameOpen && "" ,
84
98
! isNewGameOpen && "border-transparent" ,
85
99
) } >
86
100
{ isNewGameOpen ? (
87
101
< NewGameDialog
102
+ onRef = { ref => newGameRef . current = ref }
88
103
onNewGame = { onNewGame }
89
104
onStartEdit = { onStartEdit }
90
105
setNewGameOpen = { setNewGameOpen } />
91
- ) : (
92
- < button className = { twJoin (
106
+ ) : "" }
107
+ < button disabled = { isNewGameOpen } className = { ! isNewGameOpen ? twJoin (
93
108
"ml-2 border-2 border-transparent px-4 py-2 rounded-lg" ,
94
109
"hover:border-sky-700" ,
110
+ ) : twJoin (
111
+ "ml-2 border-2 bg-gray-400 border-transparent px-4 py-2 rounded-lg" ,
95
112
) }
96
113
onClick = { ( ) => {
97
114
setNewGameOpen ( true )
98
115
} } >
99
116
New Game
100
117
</ button >
101
- ) }
118
+
102
119
</ div >
103
120
< div className = "mt-2 grid gap-x-4 grid-cols-[max-content_auto]" >
104
121
< DetailNavigation detail = { detail } setDetail = { setDetail } />
@@ -114,33 +131,70 @@ export function Lobby() {
114
131
)
115
132
}
116
133
117
- function NewGameDialog ( { onNewGame, onStartEdit, setNewGameOpen} ) {
134
+ function NewGameDialog ( { onNewGame, onStartEdit, setNewGameOpen, onRef } ) {
118
135
let dimRef = useRef ( 9 )
136
+ let timeRef = useRef ( 0 )
119
137
let [ edit , setEdit ] = useState ( false )
120
138
return (
121
139
< form className = "contents" onSubmit = { ( e ) => {
122
140
e . preventDefault ( )
123
- let game = { dim : dimRef . current }
141
+ let game = { dim : dimRef . current , timesetting : timeRef . current }
124
142
if ( edit ) {
125
143
onStartEdit ( game )
126
144
} else {
127
145
onNewGame ( game )
128
146
}
129
147
} } >
130
- < Button type = "submit" className = "ml-2" > OK</ Button >
131
- < input id = "dim-9" type = "radio" name = "dim" value = "9" className = "ml-2" defaultChecked = { true } onClick = { ( ) => dimRef . current = 9 } />
132
- < label htmlFor = "dim-9" className = "pt-[0.625rem] pr-1" > 9x9</ label >
133
- < input id = "dim-13" type = "radio" name = "dim" value = "13" onClick = { ( ) => dimRef . current = 13 } />
134
- < label htmlFor = "dim-13" className = "pt-[0.625rem] pr-1" > 13x13</ label >
135
- < input id = "dim-19" type = "radio" name = "dim" value = "19" onClick = { ( ) => dimRef . current = 19 } />
136
- < label htmlFor = "dim-19" className = "pt-[0.625rem] pr-1" > 19x19</ label >
137
- < input id = "cb-edit" type = "checkbox" name = "edit" checked = { edit } onChange = { ( ) => setEdit ( ! edit ) } />
138
- < label htmlFor = "cb-edit" className = "pt-[0.625rem] ml-1" > Edit</ label >
139
- < button onClick = { ( ) => setNewGameOpen ( false ) } className = "ml-1 text-stone-100 hover:text-stone-300" >
140
- < IconContext . Provider value = { { size : "1.25em" } } >
141
- < CgClose />
142
- </ IconContext . Provider >
143
- </ button >
148
+ < div className = "flex justify-start" >
149
+ < div ref = { onRef } className = "absolute ml-40 bg-slate-800 w-96 border-2 border-slate-600 rounded-lg" >
150
+ < div className = "absolute top-1 right-0 mr-2" >
151
+ < button onClick = { ( ) => setNewGameOpen ( false ) } className = "ml-1 text-stone-100 hover:text-stone-300" >
152
+ < IconContext . Provider value = { { size : "1.25em" } } >
153
+ < CgClose />
154
+ </ IconContext . Provider >
155
+ </ button >
156
+ </ div >
157
+ < div className = "grid grid-cols-3 gap-1" >
158
+ < div className = "col-span-3 pt-3" >
159
+ < label className = "italic text-gray-400 ml-2" > Dimension</ label >
160
+ </ div >
161
+ < div >
162
+ < input id = "dim-9" type = "radio" name = "dim" value = "9" className = "ml-2" defaultChecked = { true } onClick = { ( ) => dimRef . current = 9 } />
163
+ < label htmlFor = "dim-9" className = "pt-[0.625rem] pr-1" > 9x9</ label >
164
+ </ div >
165
+ < div >
166
+ < input id = "dim-13" type = "radio" name = "dim" value = "13" onClick = { ( ) => dimRef . current = 13 } />
167
+ < label htmlFor = "dim-13" className = "pt-[0.625rem] pr-1" > 13x13</ label >
168
+ </ div >
169
+ < div >
170
+ < input id = "dim-19" type = "radio" name = "dim" value = "19" onClick = { ( ) => dimRef . current = 19 } />
171
+ < label htmlFor = "dim-19" className = "pt-[0.625rem] pr-5" > 19x19</ label >
172
+ </ div >
173
+ < div className = "col-span-3" >
174
+ < label className = "italic text-gray-400 ml-2" > Time</ label >
175
+ </ div >
176
+ < div >
177
+ < input id = "time-0" type = "radio" name = "time" value = "0" className = "ml-2" defaultChecked = { true } onClick = { ( ) => timeRef . current = 0 } />
178
+ < label htmlFor = "time-0" className = "pt-[0.625rem] pr-1" > 0s</ label >
179
+ </ div >
180
+ < div >
181
+ < input id = "time-10" type = "radio" name = "time" value = "10" onClick = { ( ) => timeRef . current = 10 } />
182
+ < label htmlFor = "time-10" className = "pt-[0.625rem] pr-1" > 10s</ label >
183
+ </ div >
184
+ < div >
185
+ < input id = "time-30" type = "radio" name = "time" value = "30" onClick = { ( ) => timeRef . current = 30 } />
186
+ < label htmlFor = "time-30" className = "pt-[0.625rem] pr-1" > 30s</ label >
187
+ </ div >
188
+ </ div >
189
+ < div className = "flex flex-row w-full pt-2 pr-2 pb-2" >
190
+ < input className = "ml-2" id = "cb-edit" type = "checkbox" name = "edit" checked = { edit } onChange = { ( ) => setEdit ( ! edit ) } />
191
+ < label htmlFor = "cb-edit" className = "pt-[0.625rem] ml-1" > Edit</ label >
192
+ < div className = "grow" />
193
+ < Button type = "submit" className = "ml-2" > OK</ Button >
194
+ </ div >
195
+ </ div >
196
+ </ div >
197
+
144
198
</ form >
145
199
)
146
200
}
0 commit comments