@@ -48,6 +48,23 @@ <h1 class="text-4xl md:text-5xl font-extrabold bg-gradient-to-r from-rose-400 vi
4848 Verbal Assassins
4949 </ h1 >
5050 < p class ="text-slate-400 "> A real-time multiplayer assassination game for our group.</ p >
51+
52+ <!-- Bracket Selector -->
53+ < div class ="mt-6 mb-4 ">
54+ < div class ="inline-flex rounded-lg bg-slate-800 p-1 ">
55+ < button id ="main-bracket-btn " class ="px-6 py-2 rounded-md font-semibold transition-all duration-200 bg-indigo-600 text-white ">
56+ 🏆 Main Bracket
57+ </ button >
58+ < button id ="losers-bracket-btn " class ="px-6 py-2 rounded-md font-semibold transition-all duration-200 text-slate-400 hover:text-white ">
59+ 💀 Losers Bracket
60+ </ button >
61+ </ div >
62+ </ div >
63+
64+ < div id ="bracket-indicator " class ="text-lg font-bold mb-2 ">
65+ < span class ="text-indigo-400 "> Currently viewing: Main Bracket</ span >
66+ </ div >
67+
5168 < div id ="user-info " class ="mt-4 text-xs text-slate-500 bg-slate-800 rounded-md p-2 inline-block ">
5269 Connecting...
5370 </ div >
@@ -114,6 +131,7 @@ <h2 class="text-2xl font-bold mb-4 text-rose-400">Kill History</h2>
114131
115132 // --- GLOBAL VARIABLES & CONFIG ---
116133 const appId = 'default-verbal-assassins' ;
134+ let currentBracket = 'main' ; // track which bracket we're viewing
117135
118136 // Your web app's Firebase configuration
119137 const firebaseConfig = {
@@ -137,6 +155,42 @@ <h2 class="text-2xl font-bold mb-4 text-rose-400">Kill History</h2>
137155 const modalContainer = document . getElementById ( 'modal-container' ) ;
138156 const modalContent = document . getElementById ( 'modal-content' ) ;
139157 const lastSaveInfo = document . getElementById ( 'last-save-info' ) ;
158+ const bracketIndicator = document . getElementById ( 'bracket-indicator' ) ;
159+
160+ // bracket switching
161+ const mainBracketBtn = document . getElementById ( 'main-bracket-btn' ) ;
162+ const losersBracketBtn = document . getElementById ( 'losers-bracket-btn' ) ;
163+
164+ // --- BRACKET SWITCHING ---
165+
166+ mainBracketBtn . addEventListener ( 'click' , ( ) => {
167+ if ( currentBracket !== 'main' ) {
168+ currentBracket = 'main' ;
169+ updateBracketUI ( ) ;
170+ if ( userId ) connectToGame ( ) ;
171+ }
172+ } ) ;
173+
174+ losersBracketBtn . addEventListener ( 'click' , ( ) => {
175+ if ( currentBracket !== 'losers' ) {
176+ currentBracket = 'losers' ;
177+ updateBracketUI ( ) ;
178+ if ( userId ) connectToGame ( ) ;
179+ }
180+ } ) ;
181+
182+ function updateBracketUI ( ) {
183+ // update button styles
184+ if ( currentBracket === 'main' ) {
185+ mainBracketBtn . className = "px-6 py-2 rounded-md font-semibold transition-all duration-200 bg-indigo-600 text-white" ;
186+ losersBracketBtn . className = "px-6 py-2 rounded-md font-semibold transition-all duration-200 text-slate-400 hover:text-white" ;
187+ bracketIndicator . innerHTML = '<span class="text-indigo-400">Currently viewing: Main Bracket</span>' ;
188+ } else {
189+ mainBracketBtn . className = "px-6 py-2 rounded-md font-semibold transition-all duration-200 text-slate-400 hover:text-white" ;
190+ losersBracketBtn . className = "px-6 py-2 rounded-md font-semibold transition-all duration-200 bg-rose-600 text-white" ;
191+ bracketIndicator . innerHTML = '<span class="text-rose-400">Currently viewing: Losers Bracket</span>' ;
192+ }
193+ }
140194
141195 // --- INITIALIZATION ---
142196
@@ -170,18 +224,30 @@ <h2 class="text-2xl font-bold mb-4 text-rose-400">Kill History</h2>
170224 // --- FIRESTORE REAL-TIME CONNECTION ---
171225
172226 async function connectToGame ( ) {
173- const gameDocRef = doc ( db , `artifacts/${ appId } /public/data/games` , "verbal-assassins-game-specific" ) ;
227+ // unsubscribe from previous game if switching brackets
228+ if ( gameUnsubscribe ) {
229+ gameUnsubscribe ( ) ;
230+ gameUnsubscribe = null ;
231+ }
232+
233+ // use different document IDs for main and losers brackets
234+ const gameDocId = currentBracket === 'main'
235+ ? "verbal-assassins-game-specific"
236+ : "verbal-assassins-losers-bracket" ;
237+
238+ const gameDocRef = doc ( db , `artifacts/${ appId } /public/data/games` , gameDocId ) ;
174239
175240 try {
176241 // first, check if document exists to avoid accidental resets
177242 const docSnap = await getDoc ( gameDocRef ) ;
178243
179244 if ( ! docSnap . exists ( ) ) {
180245 // instead of auto-creating, ask the user
246+ const bracketName = currentBracket === 'main' ? 'Main Bracket' : 'Losers Bracket' ;
181247 loadingEl . innerHTML = `
182- <p class="text-lg text-amber-400 mb-4">No game found!</p>
183- <p class="text-slate-400 mb-4">Would you like to start a new game?</p>
184- <button id="create-new-game" class="bg-green-600 hover:bg-green-500 text-white font-semibold py-2 px-5 rounded-lg">Create New Game</button>
248+ <p class="text-lg text-amber-400 mb-4">No ${ bracketName } game found!</p>
249+ <p class="text-slate-400 mb-4">Would you like to start a new ${ bracketName } game?</p>
250+ <button id="create-new-game" class="bg-green-600 hover:bg-green-500 text-white font-semibold py-2 px-5 rounded-lg">Create New ${ bracketName } Game</button>
185251 ` ;
186252
187253 document . getElementById ( 'create-new-game' ) . addEventListener ( 'click' , async ( ) => {
@@ -277,7 +343,11 @@ <h2 class="text-2xl font-bold mb-4 text-rose-400">Kill History</h2>
277343 // --- GAME ACTIONS (WRITING TO FIRESTORE) ---
278344
279345 async function updateFirestoreState ( newState ) {
280- const gameDocRef = doc ( db , `artifacts/${ appId } /public/data/games` , "verbal-assassins-game-specific" ) ;
346+ const gameDocId = currentBracket === 'main'
347+ ? "verbal-assassins-game-specific"
348+ : "verbal-assassins-losers-bracket" ;
349+ const gameDocRef = doc ( db , `artifacts/${ appId } /public/data/games` , gameDocId ) ;
350+
281351 try {
282352 // add timestamp to track when changes happen
283353 newState . lastUpdated = serverTimestamp ( ) ;
@@ -290,40 +360,43 @@ <h2 class="text-2xl font-bold mb-4 text-rose-400">Kill History</h2>
290360 }
291361 }
292362
293- // backup functionality
363+ // backup functionality - now includes bracket info
294364 async function saveBackup ( ) {
295365 const backupData = {
296366 ...gameState ,
297367 backupDate : new Date ( ) . toISOString ( ) ,
298- backupBy : userId
368+ backupBy : userId ,
369+ bracket : currentBracket // remember which bracket this backup is from
299370 } ;
300371
301- // store in browser's local storage with timestamp
302- const backupKey = `verbal-assassins-backup-${ new Date ( ) . getTime ( ) } ` ;
372+ // store in browser's local storage with timestamp and bracket
373+ const backupKey = `verbal-assassins-backup-${ currentBracket } - ${ new Date ( ) . getTime ( ) } ` ;
303374 localStorage . setItem ( backupKey , JSON . stringify ( backupData ) ) ;
304375
305- // also store reference to latest backup
306- localStorage . setItem ( ' verbal-assassins-latest-backup' , backupKey ) ;
376+ // also store reference to latest backup for this bracket
377+ localStorage . setItem ( ` verbal-assassins-latest-backup- ${ currentBracket } ` , backupKey ) ;
307378
308- // keep only last 5 backups to save space
309- const allKeys = Object . keys ( localStorage ) . filter ( k => k . startsWith ( ' verbal-assassins-backup-' ) ) ;
379+ // keep only last 5 backups per bracket to save space
380+ const allKeys = Object . keys ( localStorage ) . filter ( k => k . startsWith ( ` verbal-assassins-backup-${ currentBracket } -` ) ) ;
310381 if ( allKeys . length > 5 ) {
311382 allKeys . sort ( ) ;
312383 const toRemove = allKeys . slice ( 0 , allKeys . length - 5 ) ;
313384 toRemove . forEach ( key => localStorage . removeItem ( key ) ) ;
314385 }
315386
316- alert ( `Backup saved! (${ new Date ( ) . toLocaleTimeString ( ) } )` ) ;
387+ const bracketName = currentBracket === 'main' ? 'Main Bracket' : 'Losers Bracket' ;
388+ alert ( `${ bracketName } backup saved! (${ new Date ( ) . toLocaleTimeString ( ) } )` ) ;
317389 }
318390
319391 async function showRestoreOptions ( ) {
320392 const allBackups = Object . keys ( localStorage )
321- . filter ( k => k . startsWith ( ' verbal-assassins-backup-' ) )
393+ . filter ( k => k . startsWith ( ` verbal-assassins-backup-${ currentBracket } -` ) )
322394 . sort ( )
323395 . reverse ( ) ;
324396
325397 if ( allBackups . length === 0 ) {
326- alert ( "No backups found in your browser." ) ;
398+ const bracketName = currentBracket === 'main' ? 'Main Bracket' : 'Losers Bracket' ;
399+ alert ( `No backups found for ${ bracketName } in your browser.` ) ;
327400 return ;
328401 }
329402
@@ -335,11 +408,12 @@ <h2 class="text-2xl font-bold mb-4 text-rose-400">Kill History</h2>
335408 return `<option value="${ key } ">${ date . toLocaleString ( ) } - ${ aliveCount } alive, ${ killCount } kills</option>` ;
336409 } ) . join ( '' ) ;
337410
411+ const bracketName = currentBracket === 'main' ? 'Main Bracket' : 'Losers Bracket' ;
338412 showModal (
339- ' Restore from Backup' ,
413+ ` Restore ${ bracketName } from Backup` ,
340414 `<label for="backup-select" class="block mb-2 text-slate-400">Select a backup to restore:</label>
341415 <select id="backup-select" class="w-full bg-slate-700 border border-slate-600 rounded-lg p-2 mb-4">${ options } </select>
342- <p class="text-amber-400 text-sm">⚠️ This will overwrite the current game state!</p>` ,
416+ <p class="text-amber-400 text-sm">⚠️ This will overwrite the current ${ bracketName } game state!</p>` ,
343417 [
344418 `<button id="cancel-btn" class="bg-slate-600 hover:bg-slate-500 font-semibold py-2 px-4 rounded-lg">Cancel</button>` ,
345419 `<button id="confirm-restore-btn" class="bg-teal-600 hover:bg-teal-500 font-semibold py-2 px-4 rounded-lg">Restore</button>`
@@ -354,6 +428,7 @@ <h2 class="text-2xl font-bold mb-4 text-rose-400">Kill History</h2>
354428 // remove backup metadata before restoring
355429 delete backupData . backupDate ;
356430 delete backupData . backupBy ;
431+ delete backupData . bracket ;
357432
358433 await updateFirestoreState ( backupData ) ;
359434 closeModal ( ) ;
@@ -394,9 +469,10 @@ <h2 class="text-2xl font-bold mb-4 text-rose-400">Kill History</h2>
394469 } ) ;
395470
396471 document . getElementById ( 'reset-btn' ) . addEventListener ( 'click' , ( ) => {
472+ const bracketName = currentBracket === 'main' ? 'Main Bracket' : 'Losers Bracket' ;
397473 showModal (
398- ' Confirm Reset' ,
399- ' <p>Are you sure you want to reset the game? This will restore the original player list and clear all kills and targets.</p><p class="text-amber-400 text-sm mt-2">💡 Tip: Save a backup first!</p>' ,
474+ ` Confirm Reset ${ bracketName } ` ,
475+ ` <p>Are you sure you want to reset the ${ bracketName } game? This will restore the original player list and clear all kills and targets.</p><p class="text-amber-400 text-sm mt-2">💡 Tip: Save a backup first!</p>` ,
400476 [
401477 `<button id="cancel-btn" class="bg-slate-600 hover:bg-slate-500 font-semibold py-2 px-4 rounded-lg">Cancel</button>` ,
402478 `<button id="confirm-reset-btn" class="bg-rose-600 hover:bg-rose-500 font-semibold py-2 px-4 rounded-lg">Confirm Reset</button>`
@@ -667,6 +743,7 @@ <h3 class="text-xl font-bold mb-4 text-sky-300">${title}</h3>
667743 killHistory : [ ] ,
668744 gameStarted : false ,
669745 version : 2 , // add version to track schema changes
746+ bracket : currentBracket // track which bracket this is
670747 } ;
671748 }
672749
0 commit comments