RosterHash/static/favorites.js
2025-10-31 11:52:23 -07:00

302 lines
9.5 KiB
JavaScript

// Favorites Management for RosterHash
// Manages up to 4 favorite NFL teams with localStorage persistence (persists across weeks)
const MAX_FAVORITES = 4;
// Team abbreviation to common name mapping
const TEAM_NAMES = {
'ARI': 'Cardinals',
'ATL': 'Falcons',
'BAL': 'Ravens',
'BUF': 'Bills',
'CAR': 'Panthers',
'CHI': 'Bears',
'CIN': 'Bengals',
'CLE': 'Browns',
'DAL': 'Cowboys',
'DEN': 'Broncos',
'DET': 'Lions',
'GB': 'Packers',
'HOU': 'Texans',
'IND': 'Colts',
'JAX': 'Jaguars',
'KC': 'Chiefs',
'LV': 'Raiders',
'LAC': 'Chargers',
'LAR': 'Rams',
'MIA': 'Dolphins',
'MIN': 'Vikings',
'NE': 'Patriots',
'NO': 'Saints',
'NYG': 'Giants',
'NYJ': 'Jets',
'PHI': 'Eagles',
'PIT': 'Steelers',
'SF': '49ers',
'SEA': 'Seahawks',
'TB': 'Buccaneers',
'TEN': 'Titans',
'WAS': 'Commanders'
};
class FavoritesManager {
constructor() {
this.favorites = this.loadFavorites();
this.games = [];
this.allTeams = new Set();
this.init();
}
// Get team common name
getTeamName(abbrev) {
return TEAM_NAMES[abbrev] || abbrev;
}
// Get storage key (no week suffix - persists across weeks)
getStorageKey() {
return `rosterhash_favorite_teams`;
}
// Load favorites from localStorage
loadFavorites() {
try {
const stored = localStorage.getItem(this.getStorageKey());
return stored ? JSON.parse(stored) : [];
} catch (e) {
console.error('Failed to load favorites:', e);
return [];
}
}
// Save favorites to localStorage
saveFavorites() {
try {
localStorage.setItem(this.getStorageKey(), JSON.stringify(this.favorites));
} catch (e) {
console.error('Failed to save favorites:', e);
}
}
// Initialize favorites system
init() {
// Wait for DOM to be ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => this.setup());
} else {
this.setup();
}
}
// Setup favorites after DOM is loaded
setup() {
this.extractGamesFromPage();
this.extractAllTeams();
this.populateTeamsPicker();
this.renderFavoritesList();
this.renderFavoritesDisplay();
}
// Extract all games from the schedule on the page
extractGamesFromPage() {
this.games = [];
this.allTeams = new Set();
// Find all game cards in the schedule
const gameCards = document.querySelectorAll('.game-card');
gameCards.forEach((card, index) => {
const timeElement = card.querySelector('.game-time');
const awayTeamElement = card.querySelector('.away-team');
const homeTeamElement = card.querySelector('.home-team');
const awayScoreElement = card.querySelectorAll('.nfl-score')[0];
const homeScoreElement = card.querySelectorAll('.nfl-score')[1];
const liveIndicator = card.querySelector('.live-indicator');
if (awayTeamElement && homeTeamElement) {
const awayTeam = awayTeamElement.textContent.trim();
const homeTeam = homeTeamElement.textContent.trim();
// Add teams to the set
this.allTeams.add(awayTeam);
this.allTeams.add(homeTeam);
const game = {
awayTeam: awayTeam,
homeTeam: homeTeam,
awayScore: awayScoreElement ? awayScoreElement.textContent.trim() : null,
homeScore: homeScoreElement ? homeScoreElement.textContent.trim() : null,
time: timeElement ? timeElement.textContent.trim() : 'TBD',
isLive: !!liveIndicator,
matchup: `${awayTeam} @ ${homeTeam}`
};
this.games.push(game);
}
});
}
// Extract all unique teams
extractAllTeams() {
// Already done in extractGamesFromPage
}
// Populate the teams picker in the sidebar
populateTeamsPicker() {
const picker = document.getElementById('games-picker');
if (!picker) return;
picker.innerHTML = '';
// Use all teams from TEAM_NAMES instead of only teams with games this week
const allTeamAbbrevs = Object.keys(TEAM_NAMES);
// Sort teams alphabetically by common name
const sortedTeams = allTeamAbbrevs.sort((a, b) => {
const nameA = TEAM_NAMES[a];
const nameB = TEAM_NAMES[b];
return nameA.localeCompare(nameB);
});
sortedTeams.forEach(team => {
const isSelected = this.favorites.includes(team);
const isDisabled = !isSelected && this.favorites.length >= MAX_FAVORITES;
const teamName = TEAM_NAMES[team];
const item = document.createElement('div');
item.className = 'game-picker-item';
if (isSelected) item.classList.add('selected');
if (isDisabled) item.classList.add('disabled');
item.innerHTML = `
<div class="game-picker-matchup">${teamName}</div>
`;
if (!isDisabled || isSelected) {
item.addEventListener('click', () => this.toggleFavorite(team));
}
picker.appendChild(item);
});
}
// Toggle a team as favorite
toggleFavorite(team) {
const index = this.favorites.indexOf(team);
if (index > -1) {
// Remove from favorites
this.favorites.splice(index, 1);
} else {
// Add to favorites if under limit
if (this.favorites.length < MAX_FAVORITES) {
this.favorites.push(team);
}
}
this.saveFavorites();
this.populateTeamsPicker();
this.renderFavoritesList();
this.renderFavoritesDisplay();
}
// Render favorites list in sidebar
renderFavoritesList() {
const list = document.getElementById('favorites-list');
if (!list) return;
if (this.favorites.length === 0) {
list.innerHTML = '<p class="favorites-empty">Click teams below to add favorites (max 4)</p>';
return;
}
list.innerHTML = '';
this.favorites.forEach(team => {
const teamName = this.getTeamName(team);
const card = document.createElement('div');
card.className = 'favorite-game-card';
card.innerHTML = `
<div class="favorite-game-header">
<div class="favorite-matchup">${teamName}</div>
<button class="favorite-remove" onclick="favoritesManager.toggleFavorite('${team}')">✕</button>
</div>
`;
list.appendChild(card);
});
}
// Render favorites display on main dashboard (stacked rows like fantasy scores)
renderFavoritesDisplay() {
const section = document.getElementById('favorites-section-main');
const display = document.getElementById('favorites-display');
if (!section || !display) return;
if (this.favorites.length === 0) {
section.classList.remove('has-favorites');
display.innerHTML = '';
return;
}
section.classList.add('has-favorites');
display.innerHTML = '';
this.favorites.forEach(team => {
// Find the game(s) for this team
const teamGames = this.games.filter(g => g.awayTeam === team || g.homeTeam === team);
teamGames.forEach(game => {
const row = document.createElement('div');
row.className = 'favorite-team-row';
const isHome = game.homeTeam === team;
const opponent = isHome ? game.awayTeam : game.homeTeam;
const teamScore = isHome ? game.homeScore : game.awayScore;
const oppScore = isHome ? game.awayScore : game.homeScore;
const teamName = this.getTeamName(team);
const opponentName = this.getTeamName(opponent);
const scoreDisplay = (teamScore && oppScore)
? `<span class="favorite-team-score">${teamScore} - ${oppScore}</span>`
: '';
const liveBadge = game.isLive
? '<span class="favorite-live-indicator">LIVE</span>'
: '';
const matchupDisplay = isHome ? `vs ${opponentName}` : `@ ${opponentName}`;
row.innerHTML = `
<div class="favorite-team-info">
<span class="favorite-team-name">${teamName}</span>
<span class="favorite-opponent">${matchupDisplay}</span>
</div>
<div class="favorite-team-details">
<span class="favorite-game-time">${game.time}</span>
${liveBadge}
${scoreDisplay}
</div>
`;
display.appendChild(row);
});
});
}
// Refresh scores for favorite games (called by page refresh)
refreshScores() {
this.extractGamesFromPage();
this.renderFavoritesList();
this.renderFavoritesDisplay();
}
}
// Initialize favorites manager globally
let favoritesManager;
document.addEventListener('DOMContentLoaded', function() {
favoritesManager = new FavoritesManager();
});