223 lines
9.5 KiB
HTML
223 lines
9.5 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>{% block title %}RosterHash{% endblock %}</title>
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
|
|
<link rel="icon" type="image/png" href="/favicon.ico">
|
|
<link rel="apple-touch-icon" href="/rosterhash_logo.png">
|
|
<link rel="manifest" href="{{ url_for('static', filename='manifest.json') }}">
|
|
<meta name="theme-color" content="#8b7ff5">
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
|
</head>
|
|
<body>
|
|
<!-- Hamburger Menu Button - Uses CSS-only solution -->
|
|
<input type="checkbox" id="menu-toggle" class="menu-toggle-checkbox">
|
|
<label for="menu-toggle" class="menu-toggle" aria-label="Toggle menu">
|
|
<span class="menu-icon">☰</span>
|
|
</label>
|
|
|
|
<!-- Sidebar Menu -->
|
|
<div class="sidebar" id="sidebar">
|
|
<div class="sidebar-header">
|
|
<h2 class="sidebar-title">Menu</h2>
|
|
<label for="menu-toggle" class="close-btn">✕</label>
|
|
</div>
|
|
|
|
<div class="sidebar-content">
|
|
<!-- About Section (Collapsible, closed by default) -->
|
|
<div class="sidebar-section">
|
|
<details class="sidebar-details">
|
|
<summary>About RosterHash</summary>
|
|
<div class="about-text">
|
|
<p>At-a-glance view of your Sleeper leagues and player schedules.</p>
|
|
<p><strong>Features:</strong></p>
|
|
<ul>
|
|
<li>View all league matchups</li>
|
|
<li>See player schedules by game</li>
|
|
<li>Track favorite NFL teams</li>
|
|
<li>League color-coding</li>
|
|
</ul>
|
|
<p class="cron-note">* * * * 4,7,1</p>
|
|
</div>
|
|
</details>
|
|
</div>
|
|
|
|
<!-- Favorite Teams Section (Collapsible, closed by default) -->
|
|
<div class="sidebar-section">
|
|
<details class="sidebar-details">
|
|
<summary>⭐ Favorite Teams</summary>
|
|
<div class="details-content">
|
|
<div id="favorites-list" class="favorites-list">
|
|
<p class="favorites-empty">Click teams below to add favorites (max 4)</p>
|
|
</div>
|
|
|
|
<!-- Select Teams subsection -->
|
|
<div class="favorites-subsection">
|
|
<h4 class="subsection-title">Select Teams</h4>
|
|
<div class="scrollable-content">
|
|
<div id="games-picker" class="games-picker">
|
|
<!-- Populated by JavaScript -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</details>
|
|
</div>
|
|
|
|
<!-- Actions and Links (No title) -->
|
|
<div class="sidebar-section sidebar-actions">
|
|
<!-- Theme Toggle -->
|
|
<form method="post" action="/toggle_theme">
|
|
<input type="hidden" name="return_url" value="{{ request.url }}">
|
|
<button type="submit" class="sidebar-action-btn">
|
|
{% if current_theme == 'dark' %}
|
|
<span class="btn-icon">🌙</span>
|
|
<span>Change to Light Theme</span>
|
|
{% else %}
|
|
<span class="btn-icon">☀️</span>
|
|
<span>Change to Dark Theme</span>
|
|
{% endif %}
|
|
</button>
|
|
</form>
|
|
|
|
<!-- Sleeper App Link -->
|
|
<a href="https://sleeper.app" target="_blank" class="sidebar-action-btn">
|
|
<span class="btn-icon">🏈</span>
|
|
<span>Sleeper App</span>
|
|
</a>
|
|
|
|
<!-- Source Code Link -->
|
|
<a href="https://codeberg.org/edfig/RosterHash" target="_blank" class="sidebar-action-btn">
|
|
<span class="btn-icon">💻</span>
|
|
<span>Source Code</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Overlay for sidebar -->
|
|
<label for="menu-toggle" class="sidebar-overlay" id="sidebar-overlay"></label>
|
|
|
|
<div class="container">
|
|
{% block content %}{% endblock %}
|
|
</div>
|
|
|
|
<!-- App version footer -->
|
|
<footer class="app-footer">
|
|
<div class="version">RosterHash v{{ app_version }}</div>
|
|
</footer>
|
|
|
|
<!-- Set theme based on server-side session -->
|
|
<script>
|
|
// Apply theme immediately to prevent flash
|
|
document.documentElement.setAttribute('data-theme', '{{ current_theme }}');
|
|
|
|
// For modern browsers with light-dark() support, also set color-scheme
|
|
document.documentElement.style.colorScheme = '{{ current_theme }}';
|
|
|
|
// Detect user's timezone and send to server if not already set
|
|
{% if not session.get('user_timezone') %}
|
|
const userTimezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
if (userTimezone) {
|
|
// Send timezone to server via hidden form submission
|
|
const form = document.createElement('form');
|
|
form.method = 'POST';
|
|
form.action = '/set_timezone';
|
|
form.style.display = 'none';
|
|
|
|
const timezoneInput = document.createElement('input');
|
|
timezoneInput.type = 'hidden';
|
|
timezoneInput.name = 'timezone';
|
|
timezoneInput.value = userTimezone;
|
|
|
|
const returnUrlInput = document.createElement('input');
|
|
returnUrlInput.type = 'hidden';
|
|
returnUrlInput.name = 'return_url';
|
|
returnUrlInput.value = window.location.href;
|
|
|
|
form.appendChild(timezoneInput);
|
|
form.appendChild(returnUrlInput);
|
|
document.body.appendChild(form);
|
|
form.submit();
|
|
}
|
|
{% endif %}
|
|
|
|
// Collapsible functionality
|
|
function toggleDay(dayKey) {
|
|
const dayRow = document.querySelector(`[data-day="${dayKey}"]`);
|
|
const dayGames = document.getElementById(`day-${dayKey}`);
|
|
const indicator = dayRow.querySelector('.collapse-indicator');
|
|
|
|
dayRow.classList.toggle('collapsed');
|
|
|
|
if (dayRow.classList.contains('collapsed')) {
|
|
indicator.textContent = '▶';
|
|
dayGames.style.display = 'none';
|
|
} else {
|
|
indicator.textContent = '▼';
|
|
dayGames.style.display = 'block';
|
|
// Expand all games in this day
|
|
const gameCards = dayGames.querySelectorAll('.game-card');
|
|
gameCards.forEach(card => {
|
|
card.classList.remove('collapsed');
|
|
const gameIndicator = card.querySelector('.game-collapse-indicator');
|
|
const gameContent = card.querySelector('.game-content');
|
|
if (gameIndicator) gameIndicator.textContent = '▼';
|
|
if (gameContent) gameContent.style.display = 'block';
|
|
});
|
|
}
|
|
}
|
|
|
|
function toggleGame(dayKey, gameIndex) {
|
|
const gameCard = document.querySelector(`[data-day="${dayKey}"] [data-game="${gameIndex}"]`);
|
|
const gameContent = document.getElementById(`game-${dayKey}-${gameIndex}`);
|
|
const indicator = gameCard.querySelector('.game-collapse-indicator');
|
|
|
|
gameCard.classList.toggle('collapsed');
|
|
|
|
if (gameCard.classList.contains('collapsed')) {
|
|
indicator.textContent = '▶';
|
|
gameContent.style.display = 'none';
|
|
} else {
|
|
indicator.textContent = '▼';
|
|
gameContent.style.display = 'block';
|
|
}
|
|
}
|
|
|
|
// Initialize collapsed states on page load
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Hide content for collapsed day rows
|
|
document.querySelectorAll('.day-row.collapsed .day-games').forEach(dayGames => {
|
|
dayGames.style.display = 'none';
|
|
});
|
|
|
|
// Hide content for collapsed game cards
|
|
document.querySelectorAll('.game-card.collapsed .game-content').forEach(gameContent => {
|
|
gameContent.style.display = 'none';
|
|
});
|
|
});
|
|
|
|
// Register service worker for PWA functionality
|
|
if ('serviceWorker' in navigator) {
|
|
window.addEventListener('load', function() {
|
|
navigator.serviceWorker.register('/static/sw.js')
|
|
.then(function(registration) {
|
|
console.log('RosterHash SW: Registered successfully');
|
|
})
|
|
.catch(function(error) {
|
|
console.log('RosterHash SW: Registration failed:', error);
|
|
});
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<!-- Favorites Management Script -->
|
|
<script src="{{ url_for('static', filename='favorites.js') }}"></script>
|
|
|
|
<!-- Easter Eggs Script -->
|
|
<script src="{{ url_for('static', filename='easter-eggs.js') }}"></script>
|
|
</body>
|
|
</html>
|