@@ -14,6 +14,8 @@ export const Home = () => {
1414 const [ storedSession , setStoredSession ] = useState < string | null > ( null ) ;
1515 const [ showRejoinPrompt , setShowRejoinPrompt ] = useState ( false ) ;
1616 const [ notification , setNotification ] = useState < string | null > ( null ) ;
17+ const [ showCustomSessionModal , setShowCustomSessionModal ] = useState ( false ) ;
18+ const [ customSessionId , setCustomSessionId ] = useState ( '' ) ;
1719 const [ darkMode , setDarkMode ] = useState < boolean > ( ( ) => {
1820 const stored = localStorage . getItem ( STORAGE_KEY_DARK_MODE ) ;
1921 return stored === 'true' ;
@@ -50,17 +52,33 @@ export const Home = () => {
5052 setStoredSession ( null ) ;
5153 } ;
5254
53- const createSession = async ( ) => {
55+ const createSession = ( ) => {
5456 if ( ! userName . trim ( ) ) {
5557 setNotification ( 'Please enter your name' ) ;
5658 return ;
5759 }
60+ setShowCustomSessionModal ( true ) ;
61+ } ;
5862
63+ const confirmCreateSession = async ( ) => {
5964 setLoading ( true ) ;
65+ setShowCustomSessionModal ( false ) ;
66+
6067 try {
68+ const body = customSessionId . trim ( ) ? { sessionId : customSessionId . trim ( ) } : undefined ;
6169 const response = await fetch ( '/api/session' , {
6270 method : 'POST' ,
71+ headers : body ? { 'Content-Type' : 'application/json' } : { } ,
72+ body : body ? JSON . stringify ( body ) : undefined ,
6373 } ) ;
74+
75+ if ( ! response . ok ) {
76+ const error = await response . json ( ) ;
77+ setNotification ( error . error || 'Failed to create session' ) ;
78+ setLoading ( false ) ;
79+ return ;
80+ }
81+
6482 const data = await response . json ( ) ;
6583
6684 localStorage . setItem ( STORAGE_KEY_USERNAME , userName ) ;
@@ -72,6 +90,7 @@ export const Home = () => {
7290 setNotification ( 'Failed to create session' ) ;
7391 } finally {
7492 setLoading ( false ) ;
93+ setCustomSessionId ( '' ) ;
7594 }
7695 } ;
7796
@@ -142,6 +161,42 @@ export const Home = () => {
142161 { notification && (
143162 < Notification message = { notification } onClose = { ( ) => setNotification ( null ) } />
144163 ) }
164+ { showCustomSessionModal && (
165+ < div style = { styles . modalOverlay } onClick = { ( ) => setShowCustomSessionModal ( false ) } >
166+ < div style = { styles . modalContent } onClick = { ( e ) => e . stopPropagation ( ) } >
167+ < h2 style = { styles . modalTitle } > Create New Session</ h2 >
168+ < p style = { styles . modalDescription } >
169+ Enter a custom session name (optional) or leave blank to auto-generate
170+ </ p >
171+ < input
172+ type = "text"
173+ value = { customSessionId }
174+ onChange = { ( e ) => setCustomSessionId ( e . target . value ) }
175+ placeholder = "Custom session name (optional)"
176+ style = { styles . modalInput }
177+ autoFocus
178+ />
179+ < div style = { styles . modalButtons } >
180+ < button
181+ onClick = { ( ) => {
182+ setShowCustomSessionModal ( false ) ;
183+ setCustomSessionId ( '' ) ;
184+ } }
185+ style = { styles . cancelButton }
186+ >
187+ Cancel
188+ </ button >
189+ < button
190+ onClick = { confirmCreateSession }
191+ style = { styles . confirmButton }
192+ disabled = { loading }
193+ >
194+ { loading ? 'Creating...' : 'Create Session' }
195+ </ button >
196+ </ div >
197+ </ div >
198+ </ div >
199+ ) }
145200 </ div >
146201 ) ;
147202} ;
@@ -168,4 +223,71 @@ const getStyles = (colors: any): { [key: string]: React.CSSProperties } => ({
168223 borderRadius : '4px' ,
169224 cursor : 'pointer' ,
170225 } ,
226+ modalOverlay : {
227+ position : 'fixed' ,
228+ top : 0 ,
229+ left : 0 ,
230+ right : 0 ,
231+ bottom : 0 ,
232+ backgroundColor : 'rgba(0, 0, 0, 0.5)' ,
233+ display : 'flex' ,
234+ alignItems : 'center' ,
235+ justifyContent : 'center' ,
236+ zIndex : 1000 ,
237+ } ,
238+ modalContent : {
239+ backgroundColor : colors . surface ,
240+ borderRadius : '8px' ,
241+ padding : '24px' ,
242+ maxWidth : '500px' ,
243+ width : '100%' ,
244+ margin : '20px' ,
245+ } ,
246+ modalTitle : {
247+ fontSize : '24px' ,
248+ fontWeight : 'bold' ,
249+ marginBottom : '12px' ,
250+ color : colors . text ,
251+ } ,
252+ modalDescription : {
253+ fontSize : '14px' ,
254+ color : colors . textSecondary ,
255+ marginBottom : '20px' ,
256+ } ,
257+ modalInput : {
258+ width : '100%' ,
259+ padding : '12px' ,
260+ fontSize : '16px' ,
261+ border : `2px solid ${ colors . border } ` ,
262+ borderRadius : '4px' ,
263+ marginBottom : '20px' ,
264+ backgroundColor : colors . surface ,
265+ color : colors . text ,
266+ boxSizing : 'border-box' ,
267+ } ,
268+ modalButtons : {
269+ display : 'flex' ,
270+ gap : '12px' ,
271+ justifyContent : 'flex-end' ,
272+ } ,
273+ cancelButton : {
274+ padding : '10px 20px' ,
275+ fontSize : '14px' ,
276+ fontWeight : '600' ,
277+ backgroundColor : colors . surface ,
278+ color : colors . text ,
279+ border : `2px solid ${ colors . border } ` ,
280+ borderRadius : '4px' ,
281+ cursor : 'pointer' ,
282+ } ,
283+ confirmButton : {
284+ padding : '10px 20px' ,
285+ fontSize : '14px' ,
286+ fontWeight : '600' ,
287+ backgroundColor : colors . primary ,
288+ color : 'white' ,
289+ border : 'none' ,
290+ borderRadius : '4px' ,
291+ cursor : 'pointer' ,
292+ } ,
171293} ) ;
0 commit comments