1- import React from 'react' ;
2- import { BrowserRouter as Router , Routes , Route , useNavigate } from 'react-router-dom' ;
1+ import React , { useEffect , useRef } from 'react' ;
2+ import {
3+ BrowserRouter as Router ,
4+ Routes ,
5+ Route ,
6+ useNavigate ,
7+ useLocation ,
8+ } from 'react-router-dom' ;
39import IntroPage from './components/screens/IntroPage' ;
410import { Login } from './components/screens/Login' ;
511import GameMap from './components/screens/GameMap' ;
@@ -9,14 +15,41 @@ import Signup from './components/screens/Signup';
915import Questions from './components/screens/Questions' ;
1016import './styles/codezilla.css' ;
1117
18+ // 🔊 Persistent background music that plays on interaction
19+ const PersistentBackgroundMusic : React . FC = ( ) => {
20+ const audioRef = useRef < HTMLAudioElement | null > ( null ) ;
21+
22+ useEffect ( ( ) => {
23+ if ( ! audioRef . current ) {
24+ const audio = new Audio ( '/black.sabbath.mp3' ) ;
25+ audio . loop = true ;
26+ audio . volume = 0.03 ;
27+ audioRef . current = audio ;
28+
29+ const play = ( ) => {
30+ audio . play ( ) . catch ( ( err ) =>
31+ console . warn ( 'Autoplay blocked or error playing:' , err )
32+ ) ;
33+ } ;
34+
35+ document . addEventListener ( 'click' , play , { once : true } ) ;
36+ }
37+
38+ return ( ) => {
39+ audioRef . current ?. pause ( ) ;
40+ } ;
41+ } , [ ] ) ;
42+
43+ return null ;
44+ } ;
1245
1346const LogoutButton : React . FC = ( ) => {
1447 const navigate = useNavigate ( ) ;
1548
1649 const handleLogout = ( ) => {
17- localStorage . clear ( ) ;
18- navigate ( '/login' ) ;
19- } ;
50+ localStorage . clear ( ) ;
51+ navigate ( '/login' ) ;
52+ } ;
2053
2154 return (
2255 < button className = "logout-button" onClick = { handleLogout } >
@@ -25,40 +58,45 @@ const LogoutButton: React.FC = () => {
2558 ) ;
2659} ;
2760
61+ const AppContent : React . FC = ( ) => {
62+ const location = useLocation ( ) ;
63+ const isGameActive =
64+ location . pathname . startsWith ( '/map' ) ||
65+ location . pathname . startsWith ( '/question' ) ;
66+
67+ return (
68+ < div className = "app-wrapper" >
69+ { /* Only load persistent music during gameplay */ }
70+ { isGameActive && < PersistentBackgroundMusic /> }
71+
72+ < img
73+ src = "/codezilla_logo.png"
74+ alt = "Codezilla Logo"
75+ className = "logo-background"
76+ />
77+
78+ < LogoutButton />
79+
80+ < Routes >
81+ < Route path = "/" element = { < IntroPage /> } />
82+ < Route path = "/login" element = { < Login /> } />
83+ < Route path = "/map" element = { < GameMap /> } />
84+ < Route path = "/gameover" element = { < GameOver /> } />
85+ < Route path = "/signup" element = { < Signup /> } />
86+ < Route path = "/victory" element = { < Victory /> } />
87+ < Route path = "/question/:id" element = { < Questions /> } />
88+ </ Routes >
89+ </ div >
90+ ) ;
91+ } ;
92+
2893const App : React . FC = ( ) => {
2994 return (
3095 < Router >
31- < div className = "app-wrapper" >
32- { /* Background Image
33- <img
34- src="/background/codezilla_bkgd.png"
35- alt="Dark rainy cityscape"
36- className="background-image"
37- /> */ }
38-
39-
40- < img
41- src = "/codezilla_logo.png"
42- alt = "Codezilla Logo"
43- className = "logo-background"
44- />
45-
46- { /* Logout Button */ }
47- < LogoutButton />
48-
49- { /* Routes */ }
50- < Routes >
51- < Route path = "/" element = { < IntroPage /> } />
52- < Route path = "/login" element = { < Login /> } />
53- < Route path = "/map" element = { < GameMap /> } />
54- < Route path = "/gameover" element = { < GameOver /> } />
55- < Route path = "/signup" element = { < Signup /> } />
56- < Route path = "/victory" element = { < Victory /> } />
57- < Route path = "/question/:id" element = { < Questions /> } />
58- </ Routes >
59- </ div >
96+ < AppContent />
6097 </ Router >
6198 ) ;
6299} ;
63100
64101export default App ;
102+
0 commit comments