Add ids to tags; use pygments to color JSON

This commit is contained in:
Joakim Hellsén 2025-09-07 22:31:31 +02:00
commit 8f438aca2d
18 changed files with 365 additions and 211 deletions

View file

@ -3,15 +3,15 @@
Login
{% endblock title %}
{% block content %}
<h4>Login</h4>
<h4 id="page-title">Login</h4>
{% if form.errors %}
<ul>
<ul id="error-list">
{% for field, errors in form.errors.items %}
{% for error in errors %}<li>{{ error }}</li>{% endfor %}
{% endfor %}
</ul>
{% endif %}
<form method="post">
<form id="login-form" method="post">
{% csrf_token %}
<label for="{{ form.username.id_for_label }}">Username</label>
<input type="text"
@ -24,10 +24,10 @@
name="password"
id="{{ form.password.id_for_label }}"
required>
<button type="submit">Login</button>
<button id="login-button" type="submit">Login</button>
</form>
<p>
Don't have an account? <a href="{% url 'accounts:signup' %}">Sign up here</a>
Don't have an account? <a id="signup-link" href="{% url 'accounts:signup' %}">Sign up here</a>
</p>
<style>
.form-control {

View file

@ -3,9 +3,11 @@
{{ user.username }}
{% endblock title %}
{% block content %}
<h2>{{ user.username }}</h2>
<p>Joined {{ user.date_joined|date:"F d, Y" }}</p>
<table>
<h2 id="username">{{ user.username }}</h2>
<p>
Joined <time id="date-joined">{{ user.date_joined|date:"F d, Y" }}</time>
</p>
<table id="user-info-table">
<tr>
<td>
<strong>Date Joined:</strong>
@ -25,12 +27,12 @@
<td>{{ user.email|default:"Not provided" }}</td>
</tr>
</table>
<a href="{% url 'accounts:logout' %}">Logout</a>
<a id="logout-link" href="{% url 'accounts:logout' %}">Logout</a>
<h2>Will get notifications for these subscriptions:</h2>
<h3>Games</h3>
<ul>
<h3 id="games-subscriptions-header">Games</h3>
<ul id="games-subscriptions-list">
{% for item in games_with_inheritance %}
<li>
<li id="game-subscription-{{ item.game.id }}">
<a href="{% url 'twitch:game_detail' item.game.id %}">{{ item.game.display_name }}</a>
{% if item.is_inherited %}
<span style="font-size: 0.85em; color: #666; font-style: italic;">(inherited from {{ item.inherited_from }})</span>
@ -40,10 +42,10 @@
<li>You have no game subscriptions yet.</li>
{% endfor %}
</ul>
<h3>Organizations</h3>
<ul>
<h3 id="org-subscriptions-header">Organizations</h3>
<ul id="org-subscriptions-list">
{% for subscription in org_subscriptions %}
<li>
<li id="org-subscription-{{ subscription.organization_id }}">
<a href="{% url 'twitch:organization_detail' subscription.organization_id %}">{{ subscription.organization.name }}</a>
</li>
{% empty %}

View file

@ -3,15 +3,15 @@
Sign Up
{% endblock title %}
{% block content %}
<h4>Sign Up</h4>
<h4 id="page-title">Sign Up</h4>
{% if form.errors %}
<ul>
<ul id="error-list">
{% for field, errors in form.errors.items %}
{% for error in errors %}<li>{{ error }}</li>{% endfor %}
{% endfor %}
</ul>
{% endif %}
<form method="post">
<form id="signup-form" method="post">
{% csrf_token %}
<label for="{{ form.username.id_for_label }}">Username</label>
<input type="text"
@ -19,22 +19,22 @@
id="{{ form.username.id_for_label }}"
value="{{ form.username.value|default:'' }}"
required>
{% if form.username.help_text %}{{ form.username.help_text }}{% endif %}
{% if form.username.help_text %}<small id="username-help">{{ form.username.help_text }}</small>{% endif %}
<label for="{{ form.password1.id_for_label }}">Password</label>
<input type="password"
name="password1"
id="{{ form.password1.id_for_label }}"
required>
{% if form.password1.help_text %}{{ form.password1.help_text }}{% endif %}
{% if form.password1.help_text %}<small id="password1-help">{{ form.password1.help_text }}</small>{% endif %}
<label for="{{ form.password2.id_for_label }}">Confirm Password</label>
<input type="password"
name="password2"
id="{{ form.password2.id_for_label }}"
required>
{% if form.password2.help_text %}{{ form.password2.help_text }}{% endif %}
<button type="submit">Sign Up</button>
{% if form.password2.help_text %}<small id="password2-help">{{ form.password2.help_text }}</small>{% endif %}
<button id="signup-button" type="submit">Sign Up</button>
</form>
<p>
Already have an account? <a href="{% url 'accounts:login' %}">Login here</a>
Already have an account? <a id="login-link" href="{% url 'accounts:login' %}">Login here</a>
</p>
{% endblock content %}

View file

@ -39,7 +39,33 @@
</title>
<style>
html { color-scheme: light dark; }
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 1.4; padding: 0 15px; font-size: 115%;}
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; line-height: 1.4; padding: 0; font-size: 115%; max-width: 75%; margin: 0 auto;}
@media (max-width: 900px) { body { max-width: 95%; } }
table { width: 100%; }
th, td { padding: 8px; text-align: left; vertical-align: middle; }
th {background-color: Canvas; color: CanvasText; font-weight: bold; }
tr:nth-child(even) { background-color: color-mix(in srgb, Canvas 95%, CanvasText 5%); }
td img { display: block; height: 160px; width: 160px; object-fit: cover; border-radius: 4px; }
@media (prefers-color-scheme: dark) {
.highlight { background: #0d1117; color: #E6EDF3; }
.highlight .p { color: #E6EDF3; }
.highlight .nt { color: #7EE787; }
.highlight .s2, .highlight .mi { color: #A5D6FF; }
.highlight .kc { color: #79C0FF; }
.highlight .w { color: #6E7681; }
}
@media (prefers-color-scheme: light) {
.highlight { background: #f6f8fa; color: #24292e; }
.highlight .p { color: #24292e; }
.highlight .nt { color: #005cc5; }
.highlight .s2, .highlight .mi { color: #032f62; }
.highlight .kc { color: #d73a49; }
.highlight .w { color: #6a737d; }
}
</style>
</head>
<body>
@ -47,17 +73,7 @@
<a href="{% url 'twitch:campaign_list' %}">Campaigns</a> |
<a href="{% url 'twitch:game_list' %}">Games</a> |
<a href="{% url 'twitch:org_list' %}">Organizations</a> |
<a href="{% url 'twitch:docs_rss' %}">RSS Docs</a> |
<form action="{% url 'twitch:search' %}"
method="get"
style="display: inline">
<input type="search"
name="q"
placeholder="Search..."
value="{{ request.GET.q }}">
<button type="submit">Search</button>
</form>
|
<a href="{% url 'twitch:docs_rss' %}">RSS</a> |
{% if user.is_authenticated %}
<a href="{% url 'twitch:debug' %}">Debug</a> |
{% if user.is_staff %}
@ -68,6 +84,16 @@
<a href="{% url 'accounts:login' %}">Login</a> |
<a href="{% url 'accounts:signup' %}">Sign Up</a>
{% endif %}
|
<form action="{% url 'twitch:search' %}"
method="get"
style="display: inline">
<input type="search"
name="q"
placeholder="Search..."
value="{{ request.GET.q }}">
<button type="submit">Search</button>
</form>
{% if messages %}
<ul>
{% for message in messages %}

View file

@ -4,96 +4,136 @@
{{ campaign.clean_name }}
{% endblock title %}
{% block content %}
<h1>
<a href="{% url 'twitch:game_detail' campaign.game.id %}">{{ campaign.game.display_name }}</a> - {{ campaign.clean_name }}
</h1>
{% if campaign.owner %}
<p>
<a href="{% url 'twitch:organization_detail' campaign.owner.id %}">{{ campaign.owner.name }}</a>
</p>
<!-- Campaign Title -->
{% if campaign.game %}
<h1 id="campaign-title">
<a href="{% url 'twitch:game_detail' campaign.game.id %}">{{ campaign.game.name }}</a> - {{ campaign.clean_name }}
</h1>
{% else %}
<p>Organization Unknown</p>
<h1 id="campaign-title">{{ campaign.clean_name }}</h1>
{% endif %}
{% if owner %}
<p id="campaign-owner">
<a href="{% url 'twitch:organization_detail' owner.id %}">{{ owner.name }}</a>
</p>
{% endif %}
<!-- Campaign image -->
{% if campaign.image_url %}
<img height="70"
width="70"
<img id="campaign-image"
height="160"
width="160"
src="{{ campaign.image_url }}"
alt="{{ campaign.name }}">
{% endif %}
<p>{{ campaign.description|linebreaksbr }}</p>
<p>
Start:
{{ campaign.start_at }}
</p>
<p>
End:
{{ campaign.end_at }}
</p>
<!-- Campaign description -->
<p id="campaign-description">{{ campaign.description|linebreaksbr }}</p>
<!-- Campaign end times -->
<div>
<time id="campaign-end-time"
datetime="{{ campaign.end_at|date:'c' }}"
title="{{ campaign.end_at|date:'DATETIME_FORMAT' }}">
<strong>Ends in</strong> {{ campaign.end_at|timeuntil }}
</time>
</div>
<!-- Campaign start times -->
<div>
<time id="campaign-start-time"
datetime="{{ campaign.start_at|date:'c' }}"
title="{{ campaign.start_at|date:'DATETIME_FORMAT' }}">
<strong>Started</strong> {{ campaign.start_at|timesince }} ago
</time>
</div>
<!-- Campaign added times -->
<div>
<time id="campaign-added-time"
datetime="{{ campaign.added_at|date:'c' }}"
title="{{ campaign.added_at|date:'DATETIME_FORMAT' }}">
<strong>Scraped</strong> {{ campaign.added_at|timesince }} ago
</time>
</div>
<!-- Campaign duration -->
<div>
<time id="campaign-duration"
datetime="{{ campaign.start_at|date:'c' }} to {{ campaign.end_at|date:'c' }}"
title="{{ campaign.start_at|date:'DATETIME_FORMAT' }} to {{ campaign.end_at|date:'DATETIME_FORMAT' }}">
<strong>Duration</strong> {{ campaign.start_at|timesince:campaign.end_at }} ago
</time>
</div>
<!-- Campaign Detail URL -->
{% if campaign.details_url %}
{# TODO: Archive this URL automatically #}
<p>
<a href="{{ campaign.details_url }}" target="_blank">Official Details</a>
<a id="campaign-details-url"
href="{{ campaign.details_url }}"
target="_blank">Official Details</a>
</p>
{% endif %}
<!-- Campaign Account Link URL -->
{% if campaign.account_link_url %}
{# TODO: Archive this URL automatically #}
<p>
<a href="{{ campaign.account_link_url }}" target="_blank">Connect Account</a>
<a id="campaign-account-link-url"
href="{{ campaign.account_link_url }}"
target="_blank">Connect Account</a>
</p>
{% endif %}
<h5>Campaign Info</h5>
{% if user.is_staff %}
<p>
{% if campaign.is_account_connected %}
Connected
{% else %}
Not Connected
{% endif %}
</p>
{% endif %}
{% if drops %}
<table>
<tr>
<th>Image</th>
<th>Name</th>
<th>Requirements</th>
<th>Availability</th>
</tr>
{% for drop in drops %}
<table id="drops-table" style="border-collapse: collapse; width: 100%;">
<thead>
<tr>
<td>
{% for benefit in drop.benefits.all %}
{% if benefit.image_asset_url %}
<img height="120"
width="120"
style="object-fit: cover"
src="{{ benefit.image_asset_url }}"
alt="{{ benefit.name }}">
{% else %}
<img height="120"
width="120"
style="object-fit: cover"
src="{% static 'images/placeholder.png' %}"
alt="No Image Available">
<th>Benefits</th>
<th>Drop Name</th>
<th>Requirements</th>
<th>Period</th>
</tr>
</thead>
<tbody>
{% for drop in drops %}
<tr id="drop-{{ drop.drop.id }}">
<td>
{% for benefit in drop.drop.benefits.all %}
{% if benefit.image_asset_url %}
<img height="160"
width="160"
style="object-fit: cover;
margin-right: 3px"
src="{{ benefit.image_asset_url }}"
alt="{{ benefit.name }}">
{% else %}
<img height="160"
width="160"
style="object-fit: cover;
margin-right: 3px"
src="{% static 'images/placeholder.png' %}"
alt="No Image Available">
{% endif %}
{% endfor %}
</td>
<td>{{ drop.drop.name }}</td>
<td>
{% if drop.drop.required_minutes_watched %}{{ drop.drop.required_minutes_watched }} minutes watched{% endif %}
{% if drop.drop.required_subs > 0 %}
{% if drop.drop.required_minutes_watched %}and{% endif %}
{{ drop.drop.required_subs }} subscriptions required
{% endif %}
{% endfor %}
</td>
<td>{{ drop.name }}</td>
<td>
{{ drop.required_minutes_watched }} minutes watched
{% if drop.required_subs > 0 %}and {{ drop.required_subs }} subscriptions required{% endif %}
</td>
<td>{{ drop.start_at }} - {{ drop.end_at }}</td>
</tr>
{% endfor %}
{% if not drops %}
<tr>
<td colspan="6">No drops found for this campaign.</td>
</tr>
{% endif %}
</td>
<td>
<div>
{% if drop.local_start %}{{ drop.local_start|date:"M j, Y H:i" }}{% endif %}
{% if drop.local_start and drop.local_end %}-{% endif %}
{% if drop.local_end %}{{ drop.local_end|date:"M j, Y H:i" }}{% endif %}
<small style="color: #666;">{{ drop.timezone_name }}</small>
</div>
<div style="font-size: 0.8em; color: #666;">{{ drop.countdown_text }}</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No drops available for this campaign.</p>
{% endif %}
<pre><code>{{ campaign_data }}</code></pre>
<!-- Campaign JSON -->
{{ campaign_data|safe }}
{% endblock content %}

View file

@ -6,10 +6,11 @@
{% block content %}
<main>
<header>
<h1>Drop Campaigns</h1>
<h1 id="page-title">Drop Campaigns</h1>
<p>Browse all available drop campaigns</p>
</header>
<form method="get"
<form id="filter-form"
method="get"
action="{% url 'twitch:campaign_list' %}"
style="margin-bottom: 2rem;
padding: 1rem;
@ -42,13 +43,14 @@
{% endfor %}
</select>
</div>
<button type="submit">Apply Filters</button>
<button id="apply-filters-button" type="submit">Apply Filters</button>
</div>
</form>
{% if campaigns %}
{% regroup campaigns by game as campaigns_by_game %}
{% for game_group in campaigns_by_game %}
<section style="margin-bottom: 3rem;">
<section id="game-group-{{ game_group.grouper.id }}"
style="margin-bottom: 3rem">
<div style="display: flex; gap: 1rem;">
<div style="flex-shrink: 0;">
{% if game_group.grouper.box_art_base_url %}
@ -76,13 +78,15 @@
{% comment %} Find this header section in your template {% endcomment %}
<header style="margin-bottom: 1rem;">
<h2 style="margin: 0 0 0.5rem 0;">
<a href="{% url 'twitch:game_detail' game_group.grouper.id %}"
<a id="game-link-{{ game_group.grouper.id }}"
href="{% url 'twitch:game_detail' game_group.grouper.id %}"
style="text-decoration: none">{{ game_group.grouper.display_name|default:game_group.grouper.name|default:game_group.grouper.slug|default:game_group.grouper.id }}</a>
</h2>
{% comment %} MODIFICATION: Check if the owner exists before creating the link {% endcomment %}
{% if game_group.grouper.owner %}
<p style="margin: 0;">
<a href="{% url 'twitch:organization_detail' game_group.grouper.owner.id %}"
<a id="org-link-{{ game_group.grouper.owner.id }}"
href="{% url 'twitch:organization_detail' game_group.grouper.owner.id %}"
style="text-decoration: none">{{ game_group.grouper.owner.name }}</a>
</p>
{% endif %}
@ -90,16 +94,19 @@
<div style="overflow-x: auto;">
<div style="display: flex; gap: 1rem; min-width: max-content;">
{% for campaign in game_group.list %}
<article style="display: flex;
<article id="campaign-{{ campaign.id }}"
style="display: flex;
flex-direction: column;
align-items: flex-start;
padding: 0.5rem;
flex-shrink: 0">
<div>
<a href="{% url 'twitch:campaign_detail' campaign.id %}"
<a id="campaign-link-{{ campaign.id }}"
href="{% url 'twitch:campaign_detail' campaign.id %}"
style="text-decoration: none">
{% if campaign.image_url %}
<img src="{{ campaign.image_url }}"
<img id="campaign-image-{{ campaign.id }}"
src="{{ campaign.image_url }}"
alt="Campaign artwork for {{ campaign.name }}"
width="120"
height="120"
@ -118,7 +125,9 @@
No Image
</div>
{% endif %}
<h4 style="margin: 0.5rem 0; text-align: left;">{{ campaign.clean_name }}</h4>
<h4 id="campaign-name-{{ campaign.id }}"
style="margin: 0.5rem 0;
text-align: left">{{ campaign.clean_name }}</h4>
</a>
<div style="font-size: 0.9rem;">
<time datetime="{{ campaign.start_at|date:'c' }}"
@ -133,11 +142,15 @@
</div>
<div style="margin-top: 0.5rem;">
{% if campaign.start_at <= now and campaign.end_at >= now %}
<span style="font-weight: 600; color: #28a745;">Active</span>
<span id="campaign-status-{{ campaign.id }}"
style="font-weight: 600;
color: #28a745">Active</span>
{% elif campaign.start_at > now %}
<span style="font-weight: 600;">Upcoming</span>
<span id="campaign-status-{{ campaign.id }}" style="font-weight: 600;">Upcoming</span>
{% else %}
<span style="font-weight: 600; color: #dc3545;">Expired</span>
<span id="campaign-status-{{ campaign.id }}"
style="font-weight: 600;
color: #dc3545">Expired</span>
{% endif %}
</div>
</div>
@ -162,7 +175,7 @@
{% endif %}
<!-- Pagination -->
{% if is_paginated %}
<nav style="margin-top: 3rem; text-align: center;">
<nav id="pagination" style="margin-top: 3rem; text-align: center;">
<div style="display: flex;
justify-content: center;
align-items: center;

View file

@ -5,14 +5,14 @@
{% endblock title %}
{% block content %}
<main>
<h1>Twitch Drops</h1>
<h1 id="page-title">Twitch Drops</h1>
<pre>
Drops are sorted alphabetically by organization and game. Click on a campaign or game title to see more details.
Hover over the end time to see the exact date and time.
</pre>
{% if campaigns_by_org_game %}
{% for org_id, org_data in campaigns_by_org_game.items %}
<section>
<section id="org-section-{{ org_id }}">
<h2>
{% if org_data.name %}
{{ org_data.name }}
@ -21,7 +21,7 @@ Hover over the end time to see the exact date and time.
{% endif %}
</h2>
{% for game_id, game_data in org_data.games.items %}
<article>
<article id="game-article-{{ game_id }}">
<header style="margin-bottom: 1rem;">
<h3 style="margin: 0 0 0.5rem 0;">
<a href="{% url 'twitch:game_detail' game_id %}">{{ game_data.name }}</a>
@ -38,7 +38,8 @@ Hover over the end time to see the exact date and time.
<div style="flex: 1; overflow-x: auto;">
<div style="display: flex; gap: 1rem; min-width: max-content;">
{% for campaign in game_data.campaigns %}
<article style="display: flex;
<article id="campaign-article-{{ campaign.id }}"
style="display: flex;
flex-direction: column;
align-items: center;
padding: 0.5rem;
@ -68,13 +69,13 @@ Hover over the end time to see the exact date and time.
text-align: left">
Started {{ campaign.start_at|timesince }} ago
</time>
<time datetime="{{ campaign.created_at|date:'c' }}"
title="{{ campaign.created_at|date:'DATETIME_FORMAT' }}"
<time datetime="{{ campaign.added_at|date:'c' }}"
title="{{ campaign.added_at|date:'DATETIME_FORMAT' }}"
style="font-size: 0.9rem;
color: #666;
display: block;
text-align: left">
Scraped {{ campaign.created_at|timesince }} ago
Scraped {{ campaign.added_at|timesince }} ago
</time>
<time datetime="{{ campaign.start_at|date:'c' }} to {{ campaign.end_at|date:'c' }}"
title="{{ campaign.start_at|date:'DATETIME_FORMAT' }} to {{ campaign.end_at|date:'DATETIME_FORMAT' }}"

View file

@ -3,14 +3,16 @@
Debug
{% endblock title %}
{% block content %}
<h1>Debug Data Integrity Report</h1>
<p>Generated at: {{ now }}</p>
<h1 id="page-title">Debug Data Integrity Report</h1>
<p>
Generated at: <time id="generation-time">{{ now }}</time>
</p>
<section>
<h2>Games Without an Assigned Owner ({{ games_without_owner|length }})</h2>
<h2 id="games-without-owner-header">Games Without an Assigned Owner ({{ games_without_owner|length }})</h2>
{% if games_without_owner %}
<ul>
<ul id="games-without-owner-list">
{% for game in games_without_owner %}
<li>
<li id="game-{{ game.id }}">
<a href="{% url 'twitch:game_detail' game.id %}">{{ game.display_name }}</a> (ID: {{ game.id }})
</li>
{% endfor %}
@ -20,11 +22,11 @@
{% endif %}
</section>
<section>
<h2>Campaigns With Broken Image URLs ({{ broken_image_campaigns|length }})</h2>
<h2 id="broken-image-campaigns-header">Campaigns With Broken Image URLs ({{ broken_image_campaigns|length }})</h2>
{% if broken_image_campaigns %}
<ul>
<ul id="broken-image-campaigns-list">
{% for c in broken_image_campaigns %}
<li>
<li id="campaign-{{ c.id }}">
<a href="{% url 'twitch:campaign_detail' c.id %}">{{ c.name }}</a>
(Game: <a href="{% url 'twitch:game_detail' c.game.id %}">{{ c.game.display_name }}</a>)
- URL: {{ c.image_url|default:'(empty)' }}
@ -36,14 +38,14 @@
{% endif %}
</section>
<section>
<h2>Benefits With Broken Image URLs ({{ broken_benefit_images|length }})</h2>
<h2 id="broken-benefit-images-header">Benefits With Broken Image URLs ({{ broken_benefit_images|length }})</h2>
{% if broken_benefit_images %}
<ul>
<ul id="broken-benefit-images-list">
{% for b in broken_benefit_images %}
{# A benefit is linked to a game via a drop and a campaign. #}
{# We use the 'with' tag to get the first drop for cleaner access. #}
{% with first_drop=b.drops.all.0 %}
<li>
<li id="benefit-{{ b.id }}">
{{ b.name }}
{# Check if the relationship path to the game exists #}
{% if first_drop and first_drop.campaign and first_drop.campaign.game %}
@ -61,11 +63,11 @@
{% endif %}
</section>
<section>
<h2>Active Campaigns Missing Image ({{ active_missing_image|length }})</h2>
<h2 id="active-missing-image-header">Active Campaigns Missing Image ({{ active_missing_image|length }})</h2>
{% if active_missing_image %}
<ul>
<ul id="active-missing-image-list">
{% for c in active_missing_image %}
<li>
<li id="campaign-{{ c.id }}">
<a href="{% url 'twitch:campaign_detail' c.id %}">{{ c.name }}</a>
(Game: <a href="{% url 'twitch:game_detail' c.game.id %}">{{ c.game.display_name }}</a>)
</li>
@ -76,11 +78,11 @@
{% endif %}
</section>
<section>
<h2>Time-Based Drops Without Benefits ({{ drops_without_benefits|length }})</h2>
<h2 id="drops-without-benefits-header">Time-Based Drops Without Benefits ({{ drops_without_benefits|length }})</h2>
{% if drops_without_benefits %}
<ul>
<ul id="drops-without-benefits-list">
{% for d in drops_without_benefits %}
<li>
<li id="drop-{{ d.id }}">
{{ d.name }}
(Campaign: <a href="{% url 'twitch:campaign_detail' d.campaign.id %}">{{ d.campaign.name }}</a>
in Game: <a href="{% url 'twitch:game_detail' d.campaign.game.id %}">{{ d.campaign.game.display_name }}</a>)
@ -92,11 +94,11 @@
{% endif %}
</section>
<section>
<h2>Campaigns With Invalid Dates ({{ invalid_date_campaigns|length }})</h2>
<h2 id="invalid-date-campaigns-header">Campaigns With Invalid Dates ({{ invalid_date_campaigns|length }})</h2>
{% if invalid_date_campaigns %}
<ul>
<ul id="invalid-date-campaigns-list">
{% for c in invalid_date_campaigns %}
<li>
<li id="campaign-{{ c.id }}">
<a href="{% url 'twitch:campaign_detail' c.id %}">{{ c.name }}</a>
(Game: <a href="{% url 'twitch:game_detail' c.game.id %}">{{ c.game.display_name }}</a>)
- Start: {{ c.start_at|default:'(none)' }} / End: {{ c.end_at|default:'(none)' }}
@ -108,9 +110,9 @@
{% endif %}
</section>
<section>
<h2>Duplicate Campaign Names Per Game ({{ duplicate_name_campaigns|length }})</h2>
<h2 id="duplicate-name-campaigns-header">Duplicate Campaign Names Per Game ({{ duplicate_name_campaigns|length }})</h2>
{% if duplicate_name_campaigns %}
<table>
<table id="duplicate-name-campaigns-table">
<thead>
<tr>
<th>Game</th>

View file

@ -5,13 +5,13 @@
{% endblock title %}
{% block content %}
<main>
<h1>RSS Feeds Documentation</h1>
<h1 id="page-title">RSS Feeds Documentation</h1>
<p>This page lists all available RSS feeds for TTVDrops.</p>
<section>
<h2>Available RSS Feeds</h2>
<ul>
<h2 id="available-feeds-header">Available RSS Feeds</h2>
<ul id="feeds-list">
{% for feed in feeds %}
<li>
<li id="feed-{{ forloop.counter }}">
<h3>{{ feed.title }}</h3>
<p>{{ feed.description }}</p>
<p>

View file

@ -3,12 +3,27 @@
{{ game.display_name }}
{% endblock title %}
{% block content %}
<h1>{{ game.display_name }}</h1>
<!-- Game Title -->
<h1 id="game-name">
{{ game.display_name }}
{% if game.display_name != game.name and game.name %}<small>({{ game.name }})</small>{% endif %}
</h1>
<!-- Game image -->
{% if game.box_art_url %}
<img id="game-image"
height="160"
width="160"
src="{{ game.box_art_url }}"
alt="{{ game.name }}">
{% endif %}
<!-- Game owner -->
{% if owner %}
<small><a href="{% url 'twitch:organization_detail' owner.id %}">{{ owner.name }}</a></small>
<small><a id="owner-link"
href="{% url 'twitch:organization_detail' owner.id %}">{{ owner.name }}</a></small>
{% endif %}
{% if user.is_authenticated %}
<form method="post"
<form id="notification-form"
method="post"
action="{% url 'twitch:subscribe_notifications' game_id=game.id %}">
{% csrf_token %}
<div>
@ -25,17 +40,17 @@
{% if subscription and subscription.notify_live %}checked{% endif %} />
<label for="live">🎮 Get notified when the drop is live and ready to be farmed.</label>
</div>
<button type="submit">Save notification preferences</button>
<button id="save-notifications-button" type="submit">Save notification preferences</button>
</form>
{% else %}
Login to subscribe!
<p id="login-prompt">Login to subscribe!</p>
{% endif %}
{% if active_campaigns %}
<h5>Active Campaigns</h5>
<table>
<h5 id="active-campaigns-header">Active Campaigns</h5>
<table id="active-campaigns-table">
<tbody>
{% for campaign in active_campaigns %}
<tr>
<tr id="campaign-row-{{ campaign.id }}">
<td>
<a href="{% url 'twitch:campaign_detail' campaign.id %}">{{ campaign.clean_name }}</a>
</td>
@ -48,11 +63,11 @@
</table>
{% endif %}
{% if upcoming_campaigns %}
<h5>Upcoming Campaigns</h5>
<table>
<h5 id="upcoming-campaigns-header">Upcoming Campaigns</h5>
<table id="upcoming-campaigns-table">
<tbody>
{% for campaign in upcoming_campaigns %}
<tr>
<tr id="campaign-row-{{ campaign.id }}">
<td>
<a href="{% url 'twitch:campaign_detail' campaign.id %}">{{ campaign.clean_name }}</a>
</td>
@ -65,11 +80,11 @@
</table>
{% endif %}
{% if expired_campaigns %}
<h5>Past Campaigns</h5>
<table>
<h5 id="expired-campaigns-header">Past Campaigns</h5>
<table id="expired-campaigns-table">
<tbody>
{% for campaign in expired_campaigns %}
<tr>
<tr id="campaign-row-{{ campaign.id }}">
<td>
<a href="{% url 'twitch:campaign_detail' campaign.id %}">{{ campaign.clean_name }}</a>
</td>
@ -82,7 +97,7 @@
</table>
{% endif %}
{% if not active_campaigns and not upcoming_campaigns and not expired_campaigns %}
No campaigns found for this game.
<p id="no-campaigns-message">No campaigns found for this game.</p>
{% endif %}
<pre><code>{{ game_data }}</code></pre>
{{ game_data|safe }}
{% endblock content %}

View file

@ -5,7 +5,7 @@
{% block content %}
<main>
<header>
<h1>All Games</h1>
<h1 id="page-title">All Games</h1>
<p>Browse all available games</p>
<p>
<a href="{% url 'twitch:game_list_simple' %}">List View</a>
@ -16,7 +16,8 @@
<div style="display: flex; flex-wrap: wrap; gap: 0.25rem;">
{% for organization, games in games_by_org.items %}
{% for item in games %}
<article style="padding: 0.25rem;
<article id="game-{{ item.game.id }}"
style="padding: 0.25rem;
border-radius: 8px;
flex: 1 1 160px;
text-align: center">

View file

@ -4,16 +4,16 @@
{% endblock title %}
{% block content %}
<main>
<h1>Games List</h1>
<h1 id="page-title">Games List</h1>
<p>
<a href="{% url 'twitch:game_list' %}">Grid View</a>
</p>
{% if games_by_org %}
{% for organization, games in games_by_org.items %}
<h2>{{ organization.name }}</h2>
<h2 id="org-{{ organization.id }}">{{ organization.name }}</h2>
<ul style="list-style: none; padding: 0; margin: 0;">
{% for item in games %}
<li>
<li id="game-{{ item.game.id }}">
<a href="{% url 'twitch:game_detail' item.game.id %}">{{ item.game.display_name }}</a>
</li>
{% endfor %}

View file

@ -3,16 +3,16 @@
Games
{% endblock title %}
{% block content %}
<h1>Organizations</h1>
<h1 id="page-title">Organizations</h1>
{% if orgs %}
<ul>
<ul id="org-list">
{% for organization in orgs %}
<li>
<li id="org-{{ organization.id }}">
<a href="{% url 'twitch:organization_detail' organization.id %}">{{ organization.name }}</a>
</li>
{% endfor %}
</ul>
{% else %}
No games found.
<p>No games found.</p>
{% endif %}
{% endblock content %}

View file

@ -3,9 +3,10 @@
{{ organization.name }}
{% endblock title %}
{% block content %}
<h1>{{ organization.name }}</h1>
<h1 id="org-name">{{ organization.name }}</h1>
{% if user.is_authenticated %}
<form method="post"
<form id="notification-form"
method="post"
action="{% url 'twitch:subscribe_org_notifications' org_id=organization.id %}">
{% csrf_token %}
<div>
@ -22,17 +23,17 @@
{% if subscription and subscription.notify_live %}checked{% endif %} />
<label for="live">🎮 Get notified when the drop is live and ready to be farmed.</label>
</div>
<button type="submit">Save preferences</button>
<button id="save-preferences-button" type="submit">Save preferences</button>
</form>
{% else %}
Login to subscribe!
<p id="login-prompt">Login to subscribe!</p>
{% endif %}
<ul>
<ul id="games-list">
{% for game in games %}
<li>
<li id="game-{{ game.id }}">
<a href="{% url 'twitch:game_detail' pk=game.id %}">{{ game }}</a>
</li>
{% endfor %}
</ul>
<pre><code>{{ org_data }}</code></pre>
<pre><code id="org-data">{{ org_data }}</code></pre>
{% endblock content %}

View file

@ -3,55 +3,55 @@
Search Results for "{{ query }}"
{% endblock title %}
{% block content %}
<div class="container">
<h1>Search Results for "{{ query }}"</h1>
<div class="container" id="search-results-container">
<h1 id="page-title">Search Results for "{{ query }}"</h1>
{% if not results.organizations and not results.games and not results.campaigns and not results.drops and not results.benefits %}
<p>No results found.</p>
<p id="no-results">No results found.</p>
{% else %}
{% if results.organizations %}
<h2>Organizations</h2>
<ul>
<h2 id="organizations-header">Organizations</h2>
<ul id="organizations-list">
{% for org in results.organizations %}
<li>
<li id="org-{{ org.pk }}">
<a href="{% url 'twitch:organization_detail' org.pk %}">{{ org.name }}</a>
</li>
{% endfor %}
</ul>
{% endif %}
{% if results.games %}
<h2>Games</h2>
<ul>
<h2 id="games-header">Games</h2>
<ul id="games-list">
{% for game in results.games %}
<li>
<li id="game-{{ game.pk }}">
<a href="{% url 'twitch:game_detail' game.pk %}">{{ game.display_name }}</a>
</li>
{% endfor %}
</ul>
{% endif %}
{% if results.campaigns %}
<h2>Campaigns</h2>
<ul>
<h2 id="campaigns-header">Campaigns</h2>
<ul id="campaigns-list">
{% for campaign in results.campaigns %}
<li>
<li id="campaign-{{ campaign.pk }}">
<a href="{% url 'twitch:campaign_detail' campaign.pk %}">{{ campaign.name }}</a>
</li>
{% endfor %}
</ul>
{% endif %}
{% if results.drops %}
<h2>Drops</h2>
<ul>
<h2 id="drops-header">Drops</h2>
<ul id="drops-list">
{% for drop in results.drops %}
<li>
<li id="drop-{{ drop.id }}">
<a href="{% url 'twitch:campaign_detail' drop.campaign.pk %}#drop-{{ drop.id }}">{{ drop.name }}</a> (in {{ drop.campaign.name }})
</li>
{% endfor %}
</ul>
{% endif %}
{% if results.benefits %}
<h2>Benefits</h2>
<ul>
{% for benefit in results.benefits %}<li>{{ benefit.name }}</li>{% endfor %}
<h2 id="benefits-header">Benefits</h2>
<ul id="benefits-list">
{% for benefit in results.benefits %}<li id="benefit-{{ benefit.id }}">{{ benefit.name }}</li>{% endfor %}
</ul>
{% endif %}
{% endif %}