Bump versions; add 404 page; enable TOS modal

This commit is contained in:
2026-01-20 14:51:10 +01:00
parent 87a86c55fc
commit 6f4e5996aa
8 changed files with 316 additions and 217 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "edh-stats-backend",
"version": "1.1.0",
"version": "2.1.2",
"description": "Backend API for EDH/Commander stats tracking application",
"main": "src/server.js",
"type": "module",

View File

@@ -49,7 +49,7 @@ http {
# add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
# Handle static assets with caching
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|txt)$ {
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|webp|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
@@ -74,14 +74,25 @@ http {
proxy_cache_bypass $http_upgrade;
}
# Explicitly handle HTML files - don't fallback to index.html
location ~* \.html$ {
try_files $uri =404;
}
# Handle all routes with SPA fallback
location / {
try_files $uri $uri/ /index.html =404;
try_files $uri $uri/ /index.html;
}
# Error pages
error_page 404 /index.html;
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /404.html {
root /usr/share/nginx/html;
internal;
}
location = /50x.html {
root /usr/share/nginx/html;
internal;

View File

@@ -82,7 +82,7 @@ http {
}
# Regular static files (non-hashed)
location ~* \.(png|jpg|jpeg|gif|ico|svg|txt)$ {
location ~* \.(png|jpg|jpeg|gif|ico|svg|webp|woff|woff2|txt)$ {
limit_req zone=static burst=50 nodelay;
expires 1y;
add_header Cache-Control "public, immutable";
@@ -95,6 +95,12 @@ http {
add_header Cache-Control "public, max-age=3600";
}
# Explicitly handle HTML files - don't fallback to index.html
location ~* \.html$ {
limit_req zone=static burst=10 nodelay;
try_files $uri =404;
}
# Main application routes
location / {
limit_req zone=static burst=10 nodelay;
@@ -109,26 +115,17 @@ http {
}
# Error pages
error_page 404 /index.html;
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /404.html {
root /usr/share/nginx/html;
internal;
}
location = /50x.html {
root /usr/share/nginx/html;
internal;
}
}
# HTTPS server (uncomment when SSL certificates are available)
# server {
# listen 443 ssl http2;
# server_name _;
# root /usr/share/nginx/html;
# index index.html;
# # SSL configuration (add your SSL certificates)
# ssl_certificate /etc/nginx/ssl/cert.pem;
# ssl_certificate_key /etc/nginx/ssl/key.pem;
# ssl_protocols TLSv1.2 TLSv1.3;
# ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
# ssl_prefer_server_ciphers off;
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "edh-stats-frontend",
"version": "1.1.0",
"version": "2.1.2",
"description": "Frontend for EDH/Commander stats tracking application",
"type": "module",
"scripts": {

85
frontend/public/404.html Normal file
View File

@@ -0,0 +1,85 @@
<!doctype html>
<html lang="en" class="h-full bg-gray-50">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Page Not Found - EDH Stats Tracker</title>
<meta
name="description"
content="The page you're looking for doesn't exist. Return to EDH Stats Tracker."
/>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="/css/styles.css" />
</head>
<body class="min-h-full flex flex-col">
<!-- Navigation -->
<nav class="bg-white shadow">
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-4">
<a
href="/dashboard.html"
class="text-2xl font-bold font-mtg text-edh-primary"
>
EDH Stats
</a>
</div>
</nav>
<!-- Main Content -->
<div
class="flex-1 flex items-center justify-center px-4 sm:px-6 lg:px-8 py-12"
>
<div class="max-w-md w-full text-center">
<!-- 404 Icon -->
<div class="mb-8">
<div class="text-6xl font-bold text-edh-primary mb-2">404</div>
<h1 class="text-4xl font-bold font-mtg text-gray-900 mb-4">
Page Not Found
</h1>
<p class="text-lg text-gray-600 mb-8">
Sorry, the page you're looking for doesn't exist. It might have been
moved or deleted.
</p>
</div>
<!-- Icon -->
<div class="mb-8">
<svg
class="w-24 h-24 mx-auto text-gray-400"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="1.5"
d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
></path>
</svg>
</div>
<!-- Actions -->
<div class="space-y-4">
<a
href="/"
class="inline-block px-6 py-3 bg-edh-accent text-white font-medium rounded-lg hover:bg-edh-primary transition-colors"
>
Return to Home
</a>
</div>
<!-- Helpful Info -->
<div class="mt-12 pt-8 border-t border-gray-200">
<p class="text-xs text-gray-500">Error Code: 404 | Page Not Found</p>
</div>
</div>
</div>
<!-- Scripts -->
<script
defer
src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"
></script>
<script src="/js/footer-loader.js"></script>
</body>
</html>

View File

@@ -11,7 +11,7 @@
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="/css/styles.css" />
</head>
<body class="min-h-full flex flex-col py-12 px-4 sm:px-6 lg:px-8">
<body class="min-h-full flex flex-col py-12 px-4 sm:px-6 lg:px-8" x-data="{ showTosModal: false }">
<div class="flex items-center justify-center flex-1">
<div
class="max-w-md w-full space-y-8"
@@ -315,24 +315,28 @@
></p>
</div>
<!-- Terms & Conditions -->
<div class="flex items-center">
<input
id="terms"
name="terms"
type="checkbox"
x-model="formData.terms"
@change="validateTerms()"
:class="errors.terms ? 'border-red-500' : ''"
class="h-4 w-4 text-edh-accent focus:ring-edh-accent border-gray-300 rounded"
/>
<label for="terms" class="ml-2 block text-sm text-gray-900">
I agree to the
<a href="/tos.html" target="_blank" class="text-edh-accent hover:text-edh-primary"
>Terms of Service</a
>
</label>
</div>
<!-- Terms & Conditions -->
<div class="flex items-center">
<input
id="terms"
name="terms"
type="checkbox"
x-model="formData.terms"
@change="validateTerms()"
:class="errors.terms ? 'border-red-500' : ''"
class="h-4 w-4 text-edh-accent focus:ring-edh-accent border-gray-300 rounded"
/>
<label for="terms" class="ml-2 block text-sm text-gray-900">
I agree to the
<button
type="button"
@click="showTosModal = true"
class="text-edh-accent hover:text-edh-primary font-medium"
>
Terms of Service
</button>
</label>
</div>
<p
x-show="errors.terms"
x-text="errors.terms"
@@ -541,17 +545,180 @@
At least one number (0-9)
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Scripts -->
<script
defer
src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"
></script>
<script src="/js/auth.js"></script>
<!-- Terms of Service Modal -->
<template x-if="showTosModal">
<div class="fixed inset-0 bg-black bg-opacity-50 z-40" @click="showTosModal = false"></div>
</template>
<template x-if="showTosModal">
<div class="fixed inset-0 z-50 flex items-center justify-center p-4">
<div class="bg-white rounded-lg shadow-xl w-full h-[90vh] flex flex-col lg:w-1/2 sm:w-11/12">
<!-- Modal Header -->
<div class="flex-shrink-0 bg-white border-b border-gray-200 p-6 flex justify-between items-center">
<h2 class="text-2xl font-bold font-mtg text-edh-primary">
Terms of Service
</h2>
<button
type="button"
@click="showTosModal = false"
class="text-gray-400 hover:text-gray-600 flex-shrink-0"
>
<svg
class="w-6 h-6"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M6 18L18 6M6 6l12 12"
></path>
</svg>
</button>
</div>
<script src="/js/footer-loader.js"></script>
</body>
</html>
<!-- Modal Content - Scrollable -->
<div class="flex-1 overflow-y-auto p-6 text-gray-700">
<p class="text-gray-600 mb-6 text-sm">Last updated: January 2026</p>
<div class="prose prose-sm max-w-none">
<h2 class="text-2xl font-bold text-gray-900 mt-6 mb-4">
Welcome to EDH Stats Tracker
</h2>
<p class="text-gray-700 mb-4">
By creating an account and using EDH Stats Tracker, you agree to these Terms of Service.
We've kept them simple and straightforward—no legal jargon that makes your brain hurt. (You're welcome.)
</p>
<h2 class="text-2xl font-bold text-gray-900 mt-6 mb-4">
1. What This Service Is
</h2>
<p class="text-gray-700 mb-4">
EDH Stats Tracker is a web application designed to help Magic: The Gathering players track,
analyze, and celebrate their EDH/Commander game statistics. We store your game records,
commanders, and associated statistics. Think of us as your personal game journal that actually does math for you.
</p>
<h2 class="text-2xl font-bold text-gray-900 mt-6 mb-4">
2. User Accounts
</h2>
<p class="text-gray-700 mb-4">
You are responsible for maintaining the confidentiality of your password. You agree not to share your account
credentials with anyone else. If someone logs into your account and logs all your games as losses, we'll sympathize,
but that's on you.
</p>
<p class="text-gray-700 mb-4">
You represent that the information you provide during registration is accurate and true.
If you use a fake name, that's between you and Magic's lore team.
</p>
<h2 class="text-2xl font-bold text-gray-900 mt-6 mb-4">
3. Your Content
</h2>
<p class="text-gray-700 mb-4">
All game records, commander lists, notes, and data you enter into EDH Stats Tracker remain your property.
We don't own your stats—we just help you organize them. We won't sell your data, trade it for pack equity, or share it with strangers.
(We're not monsters.)
</p>
<h2 class="text-2xl font-bold text-gray-900 mt-6 mb-4">
4. Acceptable Use
</h2>
<p class="text-gray-700 mb-4">
You agree to use EDH Stats Tracker for its intended purpose: tracking and analyzing your EDH games.
Don't use it to harass, deceive, or cause harm to others. Be cool.
</p>
<p class="text-gray-700 mb-4">
Don't try to break the service through hacking, automated attacks, or other malicious means.
If you find a security vulnerability, please let us know responsibly instead.
</p>
<h2 class="text-2xl font-bold text-gray-900 mt-6 mb-4">
5. Service Availability
</h2>
<p class="text-gray-700 mb-4">
We aim to keep EDH Stats Tracker available and reliable. However, like all software,
it may occasionally go down for maintenance or experience technical issues. We're doing our best here.
</p>
<p class="text-gray-700 mb-4">
We reserve the right to make changes to the service, add features, or modify functionality
as we see fit. We'll try to keep breaking changes to a minimum.
</p>
<h2 class="text-2xl font-bold text-gray-900 mt-6 mb-4">
6. Limitation of Liability
</h2>
<p class="text-gray-700 mb-4">
EDH Stats Tracker is provided "as is." While we work hard to make it great,
we don't guarantee it will be perfect or meet every need. We're not liable for data loss,
lost wins, or your opponent's lucky top-decks.
</p>
<h2 class="text-2xl font-bold text-gray-900 mt-6 mb-4">
7. Changes to Terms
</h2>
<p class="text-gray-700 mb-4">
We may update these Terms of Service from time to time. We'll let you know about significant changes.
Your continued use of the service after changes means you accept the new terms.
</p>
<h2 class="text-2xl font-bold text-gray-900 mt-6 mb-4">
8. Account Termination
</h2>
<p class="text-gray-700 mb-4">
You can delete your account at any time. Your data will be removed from our systems
in accordance with our privacy practices. If you violate these terms, we may disable your account.
</p>
<h2 class="text-2xl font-bold text-gray-900 mt-6 mb-4">
9. Questions?
</h2>
<p class="text-gray-700 mb-4">
If you have questions about these terms, please reach out. We're reasonable people
(at least we think so).
</p>
<div class="mt-8 p-6 bg-blue-50 border border-blue-200 rounded-lg">
<p class="text-blue-900 text-sm">
<strong>TL;DR:</strong> Use the service as intended, keep your password safe, it's your responsibility.
We'll keep your data private and try to keep the service running. Don't be a jerk. That's it.
</p>
</div>
</div>
</div>
<!-- Modal Footer -->
<div class="flex-shrink-0 bg-gray-50 border-t border-gray-200 p-6 flex justify-between items-center">
<button
type="button"
@click="showTosModal = false"
class="px-4 py-2 text-gray-700 bg-gray-200 rounded hover:bg-gray-300"
>
Close
</button>
<button
type="button"
@click="document.getElementById('terms').checked = true; showTosModal = false"
class="px-4 py-2 text-white bg-edh-accent rounded hover:bg-edh-primary"
>
I Agree
</button>
</div>
</div>
</div>
</template>
<!-- Scripts -->
<script
defer
src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"
></script>
<script src="/js/auth.js"></script>
<script src="/js/footer-loader.js"></script>
</body>
</html>

View File

@@ -1,161 +0,0 @@
<!doctype html>
<html lang="en" class="h-full bg-gray-50">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Terms of Service - EDH Stats Tracker</title>
<meta
name="description"
content="Terms of Service for EDH Stats Tracker - Track your Magic: The Gathering EDH/Commander games"
/>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="/css/styles.css" />
</head>
<body class="min-h-full bg-gray-50">
<!-- Navigation -->
<nav class="bg-white shadow">
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-4">
<div class="flex justify-between items-center">
<a href="/" class="text-2xl font-bold font-mtg text-edh-primary">
EDH Stats
</a>
<a href="/register.html" class="text-edh-accent hover:text-edh-primary font-medium">
Back to Register
</a>
</div>
</div>
</nav>
<!-- Main Content -->
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div class="bg-white rounded-lg shadow-md p-8">
<h1 class="text-4xl font-bold font-mtg text-edh-primary mb-2">
Terms of Service
</h1>
<p class="text-gray-600 mb-8">Last updated: January 2026</p>
<!-- Introduction -->
<div class="prose prose-sm max-w-none mb-8">
<h2 class="text-2xl font-bold text-gray-900 mt-8 mb-4">
Welcome to EDH Stats Tracker
</h2>
<p class="text-gray-700 mb-4">
By creating an account and using EDH Stats Tracker, you agree to these Terms of Service.
We've kept them simple and straightforward—no legal jargon that makes your brain hurt. (You're welcome.)
</p>
<h2 class="text-2xl font-bold text-gray-900 mt-8 mb-4">
1. What This Service Is
</h2>
<p class="text-gray-700 mb-4">
EDH Stats Tracker is a web application designed to help Magic: The Gathering players track,
analyze, and celebrate their EDH/Commander game statistics. We store your game records,
commanders, and associated statistics. Think of us as your personal game journal that actually does math for you.
</p>
<h2 class="text-2xl font-bold text-gray-900 mt-8 mb-4">
2. User Accounts
</h2>
<p class="text-gray-700 mb-4">
You are responsible for maintaining the confidentiality of your password. You agree not to share your account
credentials with anyone else. If someone logs into your account and logs all your games as losses, we'll sympathize,
but that's on you.
</p>
<p class="text-gray-700 mb-4">
You represent that the information you provide during registration is accurate and true.
If you use a fake name, that's between you and Magic's lore team.
</p>
<h2 class="text-2xl font-bold text-gray-900 mt-8 mb-4">
3. Your Content
</h2>
<p class="text-gray-700 mb-4">
All game records, commander lists, notes, and data you enter into EDH Stats Tracker remain your property.
We don't own your stats—we just help you organize them. We won't sell your data, trade it for pack equity, or share it with strangers.
(We're not monsters.)
</p>
<h2 class="text-2xl font-bold text-gray-900 mt-8 mb-4">
4. Acceptable Use
</h2>
<p class="text-gray-700 mb-4">
You agree to use EDH Stats Tracker for its intended purpose: tracking and analyzing your EDH games.
Don't use it to harass, deceive, or cause harm to others. Be cool.
</p>
<p class="text-gray-700 mb-4">
Don't try to break the service through hacking, automated attacks, or other malicious means.
If you find a security vulnerability, please let us know responsibly instead.
</p>
<h2 class="text-2xl font-bold text-gray-900 mt-8 mb-4">
5. Service Availability
</h2>
<p class="text-gray-700 mb-4">
We aim to keep EDH Stats Tracker available and reliable. However, like all software,
it may occasionally go down for maintenance or experience technical issues. We're doing our best here.
</p>
<p class="text-gray-700 mb-4">
We reserve the right to make changes to the service, add features, or modify functionality
as we see fit. We'll try to keep breaking changes to a minimum.
</p>
<h2 class="text-2xl font-bold text-gray-900 mt-8 mb-4">
6. Limitation of Liability
</h2>
<p class="text-gray-700 mb-4">
EDH Stats Tracker is provided "as is." While we work hard to make it great,
we don't guarantee it will be perfect or meet every need. We're not liable for data loss,
lost wins, or your opponent's lucky top-decks.
</p>
<h2 class="text-2xl font-bold text-gray-900 mt-8 mb-4">
7. Changes to Terms
</h2>
<p class="text-gray-700 mb-4">
We may update these Terms of Service from time to time. We'll let you know about significant changes.
Your continued use of the service after changes means you accept the new terms.
</p>
<h2 class="text-2xl font-bold text-gray-900 mt-8 mb-4">
8. Account Termination
</h2>
<p class="text-gray-700 mb-4">
You can delete your account at any time. Your data will be removed from our systems
in accordance with our privacy practices. If you violate these terms, we may disable your account.
</p>
<h2 class="text-2xl font-bold text-gray-900 mt-8 mb-4">
9. Questions?
</h2>
<p class="text-gray-700 mb-4">
If you have questions about these terms, please reach out. We're reasonable people
(at least we think so).
</p>
<div class="mt-12 p-6 bg-blue-50 border border-blue-200 rounded-lg">
<p class="text-blue-900 text-sm">
<strong>TL;DR:</strong> Use the service as intended, keep your password safe, it's your responsibility.
We'll keep your data private and try to keep the service running. Don't be a jerk. That's it.
</p>
</div>
</div>
<!-- Footer -->
<div class="mt-12 pt-8 border-t border-gray-200">
<div class="flex justify-between items-center">
<a href="/register.html" class="text-edh-accent hover:text-edh-primary font-medium">
← Back to Register
</a>
<a href="/" class="text-edh-accent hover:text-edh-primary font-medium">
Home
</a>
</div>
</div>
</div>
</div>
<!-- Scripts -->
<script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
<script src="/js/footer-loader.js"></script>
</body>
</html>

View File

@@ -1 +1 @@
2.1.2
2.1.3