304 lines
9.6 KiB
JavaScript
304 lines
9.6 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;
|
|
|
|
if (this.allTeams.size === 0) {
|
|
picker.innerHTML = '<p style="color: var(--text-muted); font-size: 13px; text-align: center; padding: 16px;">No teams available</p>';
|
|
return;
|
|
}
|
|
|
|
picker.innerHTML = '';
|
|
|
|
// Sort teams alphabetically by common name
|
|
const sortedTeams = Array.from(this.allTeams).sort((a, b) => {
|
|
const nameA = this.getTeamName(a);
|
|
const nameB = this.getTeamName(b);
|
|
return nameA.localeCompare(nameB);
|
|
});
|
|
|
|
sortedTeams.forEach(team => {
|
|
const isSelected = this.favorites.includes(team);
|
|
const isDisabled = !isSelected && this.favorites.length >= MAX_FAVORITES;
|
|
const teamName = this.getTeamName(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();
|
|
});
|