11'use client'
2- import { stringify } from 'querystring' ;
32import { useState , useEffect } from 'react' ;
4- import { redirect , useRouter } from 'next/navigation'
5- import { Router } from 'next/router' ;
3+ import { useRouter } from 'next/navigation' ;
64import { handleSpotifyAuth } from '@/src/utils' ;
7- import 'dotenv/config' ;
5+
86const Toast : React . FC < { message : string ; onClose : ( ) => void ; } > = ( { message, onClose } ) => {
97 return (
108 < div className = "toast" >
@@ -13,83 +11,131 @@ const Toast: React.FC<{ message: string; onClose: () => void; }> = ({ message, o
1311 </ div >
1412 ) ;
1513} ;
16-
1714
1815export default function Home ( ) {
19- const [ guestCode , setGuestCode ] = useState ( "" ) ; // Can be set as Next.js cookie and passed into server side session/[id]/page.tsx
20- const [ hostUsername , setHost ] = useState ( "" ) ; // Can be set as Next.js cookie and passed into server side session/[id]/page.tsx
16+ const [ guestCode , setGuestCode ] = useState ( "" ) ;
17+ const [ hostUsername , setHost ] = useState ( "" ) ;
2118 const [ guestUsername , setGuest ] = useState ( "" ) ;
2219 const [ toastMessage , setToastMessage ] = useState ( '' ) ;
2320 const router = useRouter ( ) ;
2421
25-
26-
2722 useEffect ( ( ) => {
28- // This effect will run only on the client side
2923 if ( toastMessage ) {
3024 const timer = setTimeout ( ( ) => setToastMessage ( '' ) , 3500 ) ;
31- return ( ) => clearTimeout ( timer ) ; }
32- // You can place any client-side specific logic here
33- } , [ toastMessage ] ) ; // Empty dependency array ensures the effect runs only once on mount
25+ return ( ) => clearTimeout ( timer ) ;
26+ }
27+ } , [ toastMessage ] ) ;
28+
29+ const handleHostSubmit = ( e ?: React . FormEvent ) => {
30+ if ( e ) e . preventDefault ( ) ; // Prevent form submission behavior
31+
32+ if ( hostUsername === "" ) {
33+ setToastMessage ( "Error: Username is blank." ) ;
34+ setHost ( '' ) ;
35+ } else {
36+ sessionStorage . setItem ( "username" , hostUsername ) ;
37+ sessionStorage . setItem ( "isHost" , "true" ) ;
38+
39+ const client_id : string | undefined = process . env . NEXT_PUBLIC_SPOTIFY_CLIENT_ID ;
40+ const redirect_uri : string = `${ process . env . NEXT_PUBLIC_APP_SERVER } /api/spotify/getToken` ;
41+ const scope : string = 'user-read-currently-playing user-read-playback-state user-modify-playback-state' ;
42+
43+ handleSpotifyAuth ( client_id , redirect_uri , scope ) ;
44+ }
45+ } ;
46+
47+ const handleGuestSubmit = ( e ?: React . FormEvent ) => {
48+ if ( e ) e . preventDefault ( ) ; // Prevent form submission behavior
49+ sessionStorage . setItem ( "username" , guestUsername ) ;
50+ sessionStorage . setItem ( "isHost" , "false" ) ;
51+ connectToSession ( guestCode , guestUsername , router , setToastMessage , setGuestCode , setGuest ) ;
52+ } ;
53+
3454 return (
3555 < main className = "background flex min-h-screen flex-col items-center justify-between p-24" >
36- < img src = "GMJ-emblem-color.svg" alt = "" />
56+ < img src = "GMJ-emblem-color.svg" alt = "" className = "logo" />
3757 < div className = "options" >
58+
59+ { /* Host Section */ }
3860 < div className = "hostoptions" >
39- < h1 > I'm a host:</ h1 >
40- < form data-testid = "host-form" >
41- < input type = "text" placeholder = 'Username' maxLength = { 6 } name = "username" onChange = { ( e ) => setHost ( e . target . value ) } />
42- </ form >
43- < button className = "SubmitButton" onClick = { ( ) => {
44- if ( hostUsername == "" ) {
45- setToastMessage ( 'Error: Username is blank.' ) ;
46- setHost ( '' ) ;
47- } else {
48- sessionStorage . setItem ( "username" , hostUsername ) ; // change this to a nextjs cookie (server-side)
49- sessionStorage . setItem ( "isHost" , "true" ) ; // change this to a nextjs cookie (server-side)
50- const client_id : string | undefined = process . env . NEXT_PUBLIC_SPOTIFY_CLIENT_ID ; // Spotify developer client id for API calls
51- const redirect_uri : string = `${ process . env . NEXT_PUBLIC_APP_SERVER } /api/spotify/getToken`
52- const scope : string = 'user-read-currently-playing user-read-playback-state user-modify-playback-state' ;
53- handleSpotifyAuth ( client_id , redirect_uri , scope ) ; }
54- } } >
55- Host a Jam
56- </ button >
61+ < h1 > I'm a host:</ h1 >
62+ < form data-testid = "host-form" onSubmit = { handleHostSubmit } >
63+ < input
64+ type = "text"
65+ placeholder = "Username"
66+ maxLength = { 6 }
67+ name = "username"
68+ className = "input-field"
69+ onChange = { ( e ) => setHost ( e . target . value ) }
70+ onKeyDown = { ( e ) => {
71+ if ( e . key === 'Enter' ) handleHostSubmit ( ) ;
72+ } }
73+ />
74+ </ form >
75+ < button className = "SubmitButton" onClick = { handleHostSubmit } >
76+ Host a Jam
77+ </ button >
5778 </ div >
79+
5880 < div className = "divideDiv" >
59- < hr className = "divider" > </ hr >
81+ < hr className = "divider" / >
6082 </ div >
6183
84+ { /* Guest Section */ }
6285 < div className = "guestoptions" >
63- < h1 > I'm a guest:</ h1 >
64- < form data-testid = "guest-form" >
65- < input type = "text" placeholder = 'Guest Code' maxLength = { 8 } name = "guestcode" value = { guestCode } onChange = { ( e ) => setGuestCode ( e . target . value . toUpperCase ( ) ) } />
66- < input type = "text" placeholder = 'Username' maxLength = { 25 } name = "username" onChange = { ( e ) => setGuest ( e . target . value ) } />
67- </ form >
68- < button className = "SubmitButton" onClick = { ( ) => {
69- sessionStorage . setItem ( "username" , guestUsername ) ;
70- // console.log(guestUsername);
71- sessionStorage . setItem ( "isHost" , "false" ) ;
72- connectToSession ( guestCode , guestUsername , router , setToastMessage , setGuestCode , setGuest ) } } >
73-
74- Join
75- </ button >
86+ < h1 > I'm a guest:</ h1 >
87+ < form data-testid = "guest-form" onSubmit = { handleGuestSubmit } >
88+ < input
89+ type = "text"
90+ placeholder = "Guest Code"
91+ maxLength = { 8 }
92+ name = "guestcode"
93+ value = { guestCode }
94+ className = "input-field"
95+ onChange = { ( e ) => setGuestCode ( e . target . value . toUpperCase ( ) ) }
96+ onKeyDown = { ( e ) => {
97+ if ( e . key === 'Enter' ) handleGuestSubmit ( ) ;
98+ } }
99+ />
100+ < input
101+ type = "text"
102+ placeholder = "Username"
103+ maxLength = { 25 }
104+ name = "username"
105+ className = "input-field"
106+ onChange = { ( e ) => setGuest ( e . target . value ) }
107+ onKeyDown = { ( e ) => {
108+ if ( e . key === 'Enter' ) handleGuestSubmit ( ) ;
109+ } }
110+ />
111+ </ form >
112+ < button className = "SubmitButton" onClick = { handleGuestSubmit } >
113+ Join
114+ </ button >
76115 </ div >
116+
77117 </ div >
118+
119+ { /* Toast Notification */ }
78120 { toastMessage && (
79121 < Toast message = { toastMessage } onClose = { ( ) => setToastMessage ( '' ) } />
80122 ) }
81123 </ main >
82124 ) ;
83125}
84126
85- async function connectToSession ( guestCode : string , username : string , router : any , setToastMessage : any , setGuestCode : any , // Add this setter function to clear guestCode
86- setGuest : any ) : Promise < void > {
87- // Add this setter function to clear guestCode
88-
89- let stat ;
127+ // Function to connect to a session
128+ async function connectToSession (
129+ guestCode : string ,
130+ username : string ,
131+ router : any ,
132+ setToastMessage : any ,
133+ setGuestCode : any ,
134+ setGuest : any
135+ ) : Promise < void > {
136+ let stat ;
90137 try {
91-
92- await fetch ( `${ process . env . NEXT_PUBLIC_APP_SERVER } /api/sessionDB/connect` , {
138+ const response = await fetch ( `${ process . env . NEXT_PUBLIC_APP_SERVER } /api/sessionDB/connect` , {
93139 method : 'POST' ,
94140 headers : {
95141 'Content-Type' : 'application/json' ,
@@ -98,30 +144,25 @@ async function connectToSession(guestCode : string, username : string, router :
98144 guestCode : guestCode ,
99145 username : username
100146 } ) ,
101- } ) . then ( ( response ) => {
102- if ( ! response . ok ) {
103- stat = response . status ;
104- throw Error ( response . statusText ) ; }
105-
106- return response . json ( ) ;
107- } ) . then ( ( data ) => {
108- const url = data . url ;
109- router . push ( url ) ;
110- } )
111- }
112- catch ( e ) {
113- if ( stat == 401 ) {
114- console . error ( e ) ;
115- setToastMessage ( 'Error: Guest code not found.' ) ;
116- setGuestCode ( '' ) ;
117- } else if ( stat == 409 ) {
118- setToastMessage ( 'Error: Username already in use.' ) ;
119- setGuest ( '' ) ;
120- } else if ( stat == 406 ) {
121- setToastMessage ( 'Error: Username is blank.' ) ;
122- setGuest ( '' ) ;
123- }
124-
147+ } ) ;
148+
149+ if ( ! response . ok ) {
150+ stat = response . status ;
151+ throw new Error ( response . statusText ) ;
152+ }
153+
154+ const data = await response . json ( ) ;
155+ router . push ( `/session/${ guestCode } ` ) ; // Redirect to the correct session
156+ } catch ( e ) {
157+ if ( stat === 401 ) {
158+ setToastMessage ( 'Error: Guest code not found.' ) ;
159+ setGuestCode ( '' ) ;
160+ } else if ( stat === 409 ) {
161+ setToastMessage ( 'Error: Username already in use.' ) ;
162+ setGuest ( '' ) ;
163+ } else if ( stat === 406 ) {
164+ setToastMessage ( 'Error: Username is blank.' ) ;
165+ setGuest ( '' ) ;
166+ }
125167 }
126168}
127-
0 commit comments