Add breadcrumb navigation
All checks were successful
Deploy to Server / deploy (push) Successful in 20s

This commit is contained in:
Joakim Hellsén 2026-03-22 05:09:27 +01:00
commit 428f49879d
Signed by: Joakim Hellsén
SSH key fingerprint: SHA256:/9h/CsExpFp+PRhsfA0xznFx2CGfTT5R/kpuFfUgEQk
28 changed files with 350 additions and 416 deletions

View file

@ -20,11 +20,6 @@
{% endblock extra_head %}
{% block content %}
<main>
<nav aria-label="Breadcrumb">
<a href="{% url 'kick:dashboard' %}">Kick</a> &gt;
<a href="{% url 'kick:campaign_list' %}">Campaigns</a> &gt;
{{ campaign.name }}
</nav>
<div style="display: flex;
align-items: flex-start;
gap: 1.5rem;
@ -51,45 +46,30 @@
</div>
<div>
<h1 style="margin: 0 0 0.25rem 0;">{{ campaign.name }}</h1>
{% if campaign.category %}
<div>
<a href="{% url 'kick:game_campaign_feed' campaign.category.kick_id %}"
title="RSS feed for {{ campaign.category.name }} campaigns">[rss]</a>
<a href="{% url 'kick:game_campaign_feed_atom' campaign.category.kick_id %}"
title="Atom feed for {{ campaign.category.name }} campaigns">[atom]</a>
<a href="{% url 'kick:game_campaign_feed_discord' campaign.category.kick_id %}"
title="Discord feed for {{ campaign.category.name }} campaigns">[discord]</a>
<a href="{% url 'core:docs_rss' %}" title="RSS feed documentation">[explain]</a>
</div>
{% endif %}
<p style="margin: 0.25rem 0; color: #666;">
Status: {{ campaign.status|default:"unknown"|capfirst }}
{% if campaign.rule_name %}- Rule: {{ campaign.rule_name }}{% endif %}
</p>
{% if campaign.category or campaign.organization %}
<p style="margin: 0.25rem 0;">
{% if campaign.category %}
<a href="{% url 'kick:game_detail' campaign.category.kick_id %}">{{ campaign.category.name }}</a>
{% endif %}
{% if campaign.organization %}
{% if campaign.category %}-{% endif %}
<a href="{% url 'kick:organization_detail' campaign.organization.kick_id %}">{{ campaign.organization.name }}</a>
{% endif %}
</p>
{% endif %}
<p style="margin: 0.25rem 0; font-size: 0.85rem; color: #666;">
ID: {{ campaign.kick_id }}
{% if campaign.rule_id %}- Rule ID: {{ campaign.rule_id }}{% endif %}
- Added: <time datetime="{{ campaign.added_at|date:'c' }}"
title="{{ campaign.added_at|date:'DATETIME_FORMAT' }}">{{ campaign.added_at|date:"M d, Y" }}</time>
({{ campaign.added_at|timesince }} ago)
- Updated: <time datetime="{{ campaign.updated_at|date:'c' }}"
title="{{ campaign.updated_at|date:'DATETIME_FORMAT' }}">{{ campaign.updated_at|date:"M d, Y" }}</time>
({{ campaign.updated_at|timesince }} ago)
</p>
<div>
<a href="{% url 'kick:dashboard' %}">Kick</a> >
<a href="{% url 'kick:campaign_list' %}">Campaigns</a> >
{{ campaign.name }}
</div>
<div>
{% if campaign.category %}
Category:
<a href="{% url 'kick:game_detail' campaign.category.kick_id %}">{{ campaign.category.name }}</a>
{% endif %}
</div>
<div>
{% if campaign.organization %}
Organization:
<a href="{% url 'kick:organization_detail' campaign.organization.kick_id %}">{{ campaign.organization.name }}</a>
{% endif %}
</div>
{% if campaign.ends_at %}
<p style="margin: 0.25rem 0;">
<strong>Ends:</strong>
<div>
{% if campaign.ends_at > now %}
Ends
{% else %}
Ended at
{% endif %}
<time datetime="{{ campaign.ends_at|date:'c' }}"
title="{{ campaign.ends_at|date:'DATETIME_FORMAT' }}">{{ campaign.ends_at|date:"M d, Y H:i" }}</time>
{% if campaign.ends_at < now %}
@ -97,11 +77,15 @@
{% else %}
(in {{ campaign.ends_at|timeuntil }})
{% endif %}
</p>
</div>
{% endif %}
{% if campaign.starts_at %}
<p style="margin: 0.25rem 0;">
<strong>Starts:</strong>
<div>
{% if campaign.starts_at > now %}
Starts
{% else %}
Started at
{% endif %}
<time datetime="{{ campaign.starts_at|date:'c' }}"
title="{{ campaign.starts_at|date:'DATETIME_FORMAT' }}">{{ campaign.starts_at|date:"M d, Y H:i" }}</time>
{% if campaign.starts_at < now %}
@ -109,56 +93,37 @@
{% else %}
(in {{ campaign.starts_at|timeuntil }})
{% endif %}
</p>
</div>
{% endif %}
{% if campaign.duration %}
<p style="margin: 0.25rem 0;">
<strong>Duration:</strong> {{ campaign.duration }}
</p>
{% endif %}
<p style="margin: 0.25rem 0;">
{% if reward_count %}
{{ reward_count }} reward{{ reward_count|pluralize }}
({{ total_watch_minutes }} total watch minute{{ total_watch_minutes|pluralize }})
{% else %}
No rewards
{% endif %}
</p>
<div style="margin-top: 0.5rem; font-size: 0.9rem;">
<strong>Participating channels:</strong>
{% if campaign.duration %}<div>Duration: {{ campaign.duration }}</div>{% endif %}
<div>
Added <time datetime="{{ campaign.added_at|date:'c' }}"
title="{{ campaign.added_at|date:'DATETIME_FORMAT' }}">{{ campaign.added_at|date:"M d, Y" }}</time>
({{ campaign.added_at|timesince }} ago)
</div>
<div>
Updated <time datetime="{{ campaign.updated_at|date:'c' }}"
title="{{ campaign.updated_at|date:'DATETIME_FORMAT' }}">{{ campaign.updated_at|date:"M d, Y" }}</time>
({{ campaign.updated_at|timesince }} ago)
</div>
<div>
{% if campaign.channels.all %}
<ul style="margin: 0.25rem 0 0 0; padding-left: 1rem;">
{% for channel in campaign.channels.all|slice:":5" %}
<li>
{% if channel.user %}
<a href="{{ channel.channel_url }}"
rel="nofollow noopener"
target="_blank">{{ channel.user.username }}</a>
{% else %}
<a href="{{ channel.channel_url }}"
rel="nofollow noopener"
target="_blank">{{ channel.name }}</a>
{% endif %}
</li>
{% endfor %}
{% if campaign.channels.count > 5 %}
<li style="color: #666; font-style: italic;">... and {{ campaign.channels.count|add:"-5" }} more</li>
Participating channels:
{% for channel in campaign.channels.all|slice:":5" %}
{% if channel.user %}
<a href="{{ channel.channel_url }}">{{ channel.user.username }}</a>
{% else %}
<a href="{{ channel.channel_url }}">{{ channel.name }}</a>
{% endif %}
</ul>
{% else %}
<p style="margin: 0.25rem 0 0 0;">
<!-- Is game wide-->
<a href="{{ campaign.category.kick_url }}"
rel="nofollow noopener"
target="_blank">{{ campaign.category.name }}</a> is game wide.
</p>
{% endfor %}
{% if campaign.channels.count > 5 %}and {{ campaign.channels.count|add:"-5" }} more{% endif %}
{% endif %}
</div>
{% if campaign.created_at %}
<p style="margin: 0.25rem 0;">
<time datetime="{{ campaign.created_at|date:'c' }}"
title="{{ campaign.created_at|date:'DATETIME_FORMAT' }}">
Created: {{ campaign.created_at|date:"M d, Y H:i" }} ({{ campaign.created_at|timesince }} ago)
Created {{ campaign.created_at|date:"M d, Y H:i" }} ({{ campaign.created_at|timesince }} ago)
</time>
</p>
{% endif %}
@ -166,19 +131,27 @@
<p style="margin: 0.25rem 0;">
<time datetime="{{ campaign.api_updated_at|date:'c' }}"
title="{{ campaign.api_updated_at|date:'DATETIME_FORMAT' }}">
API Updated: {{ campaign.api_updated_at|date:"M d, Y H:i" }} ({{ campaign.api_updated_at|timesince }} ago)
API Updated {{ campaign.api_updated_at|date:"M d, Y H:i" }} ({{ campaign.api_updated_at|timesince }} ago)
</time>
</p>
{% endif %}
<p style="margin: 0.5rem 0 0 0;">
{% if campaign.url %}<a href="{{ campaign.url }}" rel="nofollow noopener" target="_blank">Details</a>{% endif %}
<div>
<a href="{% url 'kick:game_campaign_feed' campaign.category.kick_id %}"
title="RSS feed for {{ campaign.category.name }} campaigns">[rss]</a>
<a href="{% url 'kick:game_campaign_feed_atom' campaign.category.kick_id %}"
title="Atom feed for {{ campaign.category.name }} campaigns">[atom]</a>
<a href="{% url 'kick:game_campaign_feed_discord' campaign.category.kick_id %}"
title="Discord feed for {{ campaign.category.name }} campaigns">[discord]</a>
<a href="{% url 'core:docs_rss' %}" title="RSS documentation">[explain]</a>
{% if campaign.connect_url %}
{% if campaign.url %}-{% endif %}
<a href="{{ campaign.connect_url }}"
rel="nofollow noopener"
target="_blank">Connect account</a>
title="Connect URL for {{ campaign.name }}">[connect]</a>
{% endif %}
</p>
{% if campaign.url %}<a href="{{ campaign.url }}" title="About URL for {{ campaign.name }}">[about]</a>{% endif %}
{% if campaign.channels.count == 0 %}
{% if campaign.rule_name == "Watch to redeem" %}<a href="{{ campaign.category.kick_url }}">[watch]</a>{% endif %}
{% endif %}
</div>
</div>
</div>
<hr />
@ -210,9 +183,9 @@
<div>
<h3 style="margin: 0 0 0.25rem 0;">{{ reward.name }}</h3>
{% if reward.required_units %}
<p style="margin: 0.25rem 0;">{{ reward.required_units }} minutes watched</p>
<p>Watch {{ reward.required_units }} minutes to earn</p>
{% else %}
<p style="margin: 0.25rem 0;">No watch-time requirement</p>
<p>No watch-time requirement</p>
{% endif %}
</div>
</div>

View file

@ -18,7 +18,13 @@
{% endblock extra_head %}
{% block content %}
<main>
<h1>Kick Drop Campaigns</h1>
<h1>List of Kick drops</h1>
<div>
<a href="{% url 'kick:dashboard' %}">Kick</a> > Campaigns
</div>
<div>
Scraped from <a href="https://web.kick.com/api/v1/drops/campaigns">Kick API</a>.
</div>
<div>
<a href="{% url 'kick:campaign_feed' %}"
title="RSS feed for all campaigns">[rss]</a>

View file

@ -60,9 +60,7 @@
</div>
{% if category.kick_url %}
<p style="margin: 0.25rem 0;">
<a href="{{ category.kick_url }}"
rel="nofollow noopener"
target="_blank">{{ category.kick_url }}</a>
<a href="{{ category.kick_url }}">{{ category.kick_url }}</a>
</p>
{% endif %}
<p style="margin: 0.25rem 0; font-size: 0.85rem; color: #666;">
@ -161,9 +159,7 @@
{% endif %}
{% if campaign.connect_url %}
<p style="margin: 0.25rem 0;">
<a href="{{ campaign.connect_url }}"
rel="nofollow noopener"
target="_blank">Connect account</a>
<a href="{{ campaign.connect_url }}">Connect account</a>
</p>
{% endif %}
<div style="margin-top: 0.5rem; font-size: 0.9rem;">
@ -173,13 +169,9 @@
{% for channel in campaign.channels.all|slice:":5" %}
<li>
{% if channel.user %}
<a href="{{ channel.channel_url }}"
rel="nofollow noopener"
target="_blank">{{ channel.user.username }}</a>
<a href="{{ channel.channel_url }}">{{ channel.user.username }}</a>
{% else %}
<a href="{{ channel.channel_url }}"
rel="nofollow noopener"
target="_blank">{{ channel.slug }}</a>
<a href="{{ channel.channel_url }}">{{ channel.slug }}</a>
{% endif %}
</li>
{% endfor %}
@ -190,9 +182,7 @@
{% else %}
<p style="margin: 0.25rem 0 0 0;">
{% if category.kick_url %}
<a href="{{ category.kick_url }}"
rel="nofollow noopener"
target="_blank">{{ category.name }}</a> is game wide.
<a href="{{ category.kick_url }}">{{ category.name }}</a> is game wide.
{% else %}
Game wide.
{% endif %}
@ -304,9 +294,7 @@
{% endif %}
{% if campaign.connect_url %}
<p style="margin: 0.25rem 0;">
<a href="{{ campaign.connect_url }}"
rel="nofollow noopener"
target="_blank">Connect account</a>
<a href="{{ campaign.connect_url }}">Connect account</a>
</p>
{% endif %}
<div style="margin-top: 0.5rem; font-size: 0.9rem;">
@ -316,13 +304,9 @@
{% for channel in campaign.channels.all|slice:":5" %}
<li>
{% if channel.user %}
<a href="{{ channel.channel_url }}"
rel="nofollow noopener"
target="_blank">{{ channel.user.username }}</a>
<a href="{{ channel.channel_url }}">{{ channel.user.username }}</a>
{% else %}
<a href="{{ channel.channel_url }}"
rel="nofollow noopener"
target="_blank">{{ channel.slug }}</a>
<a href="{{ channel.channel_url }}">{{ channel.slug }}</a>
{% endif %}
</li>
{% endfor %}
@ -333,9 +317,7 @@
{% else %}
<p style="margin: 0.25rem 0 0 0;">
{% if category.kick_url %}
<a href="{{ category.kick_url }}"
rel="nofollow noopener"
target="_blank">{{ category.name }}</a> is game wide.
<a href="{{ category.kick_url }}">{{ category.name }}</a> is game wide.
{% else %}
Game wide.
{% endif %}
@ -447,9 +429,7 @@
{% endif %}
{% if campaign.connect_url %}
<p style="margin: 0.25rem 0;">
<a href="{{ campaign.connect_url }}"
rel="nofollow noopener"
target="_blank">Connect account</a>
<a href="{{ campaign.connect_url }}">Connect account</a>
</p>
{% endif %}
<div style="margin-top: 0.5rem; font-size: 0.9rem;">
@ -459,13 +439,9 @@
{% for channel in campaign.channels.all|slice:":5" %}
<li>
{% if channel.user %}
<a href="{{ channel.channel_url }}"
rel="nofollow noopener"
target="_blank">{{ channel.user.username }}</a>
<a href="{{ channel.channel_url }}">{{ channel.user.username }}</a>
{% else %}
<a href="{{ channel.channel_url }}"
rel="nofollow noopener"
target="_blank">{{ channel.slug }}</a>
<a href="{{ channel.channel_url }}">{{ channel.slug }}</a>
{% endif %}
</li>
{% endfor %}
@ -476,9 +452,7 @@
{% else %}
<p style="margin: 0.25rem 0 0 0;">
{% if category.kick_url %}
<a href="{{ category.kick_url }}"
rel="nofollow noopener"
target="_blank">{{ category.name }}</a> is game wide.
<a href="{{ category.kick_url }}">{{ category.name }}</a> is game wide.
{% else %}
Game wide.
{% endif %}

View file

@ -19,6 +19,9 @@
{% block content %}
<main>
<h1>Kick Games</h1>
<div>
<a href="{% url 'kick:dashboard' %}">Kick</a> > Games
</div>
<div>
<a href="{% url 'kick:game_feed' %}" title="RSS feed for all games">[rss]</a>
<a href="{% url 'kick:game_feed_atom' %}"

View file

@ -18,7 +18,10 @@
{% endblock extra_head %}
{% block content %}
<main>
<h1>Active Kick Drop Campaigns</h1>
<h1>Active Kick Drops</h1>
<div>
Scraped from <a href="https://web.kick.com/api/v1/drops/campaigns">Kick API</a>.
</div>
<!-- RSS Feeds -->
<div>
<a href="{% url 'kick:campaign_feed' %}"
@ -114,9 +117,7 @@
{% endif %}
{% if campaign.connect_url %}
<p style="margin: 0.25rem 0;">
<a href="{{ campaign.connect_url }}"
rel="nofollow noopener"
target="_blank">Connect account</a>
<a href="{{ campaign.connect_url }}">Connect account</a>
</p>
{% endif %}
<div style="margin-top: 0.5rem; font-size: 0.9rem;">
@ -126,13 +127,9 @@
{% for channel in campaign.channels.all|slice:":5" %}
<li>
{% if channel.user %}
<a href="{{ channel.channel_url }}"
rel="nofollow noopener"
target="_blank">{{ channel.user.username }}</a>
<a href="{{ channel.channel_url }}">{{ channel.user.username }}</a>
{% else %}
<a href="{{ channel.channel_url }}"
rel="nofollow noopener"
target="_blank">{{ channel.slug }}</a>
<a href="{{ channel.channel_url }}">{{ channel.slug }}</a>
{% endif %}
</li>
{% endfor %}

View file

@ -19,6 +19,9 @@
{% block content %}
<main>
<h1>Kick Organizations</h1>
<div>
<a href="{% url 'kick:dashboard' %}">Kick</a> > Organizations
</div>
<div>
<a href="{% url 'kick:organization_feed' %}"
title="RSS feed for all organizations">[rss]</a>
@ -34,7 +37,7 @@
<li>
<a href="{% url 'kick:organization_detail' org.kick_id %}">{{ org.name }}</a>
{% if org.campaign_count %}- {{ org.campaign_count }} campaign{{ org.campaign_count|pluralize }}{% endif %}
{% if org.url %}- <a href="{{ org.url }}" rel="nofollow noopener" target="_blank">{{ org.url }}</a>{% endif %}
{% if org.url %}- <a href="{{ org.url }}">{{ org.url }}</a>{% endif %}
</li>
{% endfor %}
</ul>

View file

@ -28,7 +28,7 @@
{% if org.restricted %}<p style="margin: 0.25rem 0; color: #b00;">Restricted</p>{% endif %}
{% if org.url %}
<p style="margin: 0.25rem 0;">
<a href="{{ org.url }}" rel="nofollow noopener" target="_blank">{{ org.url }}</a>
<a href="{{ org.url }}">{{ org.url }}</a>
</p>
{% endif %}
<p style="margin: 0.25rem 0; font-size: 0.85rem; color: #666;">
@ -121,9 +121,7 @@
{% endif %}
{% if campaign.connect_url %}
<p style="margin: 0.25rem 0;">
<a href="{{ campaign.connect_url }}"
rel="nofollow noopener"
target="_blank">Connect account</a>
<a href="{{ campaign.connect_url }}">Connect account</a>
</p>
{% endif %}
<div style="margin-top: 0.5rem; font-size: 0.9rem;">
@ -133,13 +131,9 @@
{% for channel in campaign.channels.all|slice:":5" %}
<li>
{% if channel.user %}
<a href="{{ channel.channel_url }}"
rel="nofollow noopener"
target="_blank">{{ channel.user.username }}</a>
<a href="{{ channel.channel_url }}">{{ channel.user.username }}</a>
{% else %}
<a href="{{ channel.channel_url }}"
rel="nofollow noopener"
target="_blank">{{ channel.slug }}</a>
<a href="{{ channel.channel_url }}">{{ channel.slug }}</a>
{% endif %}
</li>
{% endfor %}