Debloat HTML
This commit is contained in:
parent
c7c2d86ddb
commit
547d4e6ab1
18 changed files with 874 additions and 1284 deletions
|
|
@ -1,66 +1,35 @@
|
|||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}Login{% endblock %}
|
||||
|
||||
{% extends "base.html" %}
|
||||
{% block title %}
|
||||
Login
|
||||
{% endblock title %}
|
||||
{% block content %}
|
||||
<div class="container mt-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="card shadow">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h4 class="mb-0"><i class="fas fa-sign-in-alt"></i> Login</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if form.errors %}
|
||||
<div class="alert alert-danger">
|
||||
<ul class="mb-0">
|
||||
{% for field, errors in form.errors.items %}
|
||||
{% for error in errors %}
|
||||
<li>{{ error }}</li>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<div class="mb-3">
|
||||
<label for="{{ form.username.id_for_label }}" class="form-label">Username</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fas fa-user"></i></span>
|
||||
<input type="text" class="form-control" name="username"
|
||||
id="{{ form.username.id_for_label }}" value="{{ form.username.value|default:'' }}"
|
||||
required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="{{ form.password.id_for_label }}" class="form-label">Password</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fas fa-lock"></i></span>
|
||||
<input type="password" class="form-control" name="password"
|
||||
id="{{ form.password.id_for_label }}" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-grid">
|
||||
<button type="submit" class="btn btn-primary btn-lg">
|
||||
<i class="fas fa-sign-in-alt"></i> Login
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="card-footer text-center">
|
||||
<p class="mb-0">Don't have an account? <a href="{% url 'accounts:signup' %}"
|
||||
class="text-decoration-none">Sign up here</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
<h4>Login</h4>
|
||||
{% if form.errors %}
|
||||
<ul>
|
||||
{% for field, errors in form.errors.items %}
|
||||
{% for error in errors %}<li>{{ error }}</li>{% endfor %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<label for="{{ form.username.id_for_label }}">Username</label>
|
||||
<input type="text"
|
||||
name="username"
|
||||
id="{{ form.username.id_for_label }}"
|
||||
value="{{ form.username.value|default:'' }}"
|
||||
required>
|
||||
<label for="{{ form.password.id_for_label }}">Password</label>
|
||||
<input type="password"
|
||||
name="password"
|
||||
id="{{ form.password.id_for_label }}"
|
||||
required>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
<p>
|
||||
Don't have an account? <a href="{% url 'accounts:signup' %}">Sign up here</a>
|
||||
</p>
|
||||
<style>
|
||||
.form-control {
|
||||
border-left: none;
|
||||
}
|
||||
|
|
@ -69,5 +38,5 @@
|
|||
background-color: #f8f9fa;
|
||||
border-right: none;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
</style>
|
||||
{% endblock content %}
|
||||
|
|
|
|||
|
|
@ -1,124 +1,29 @@
|
|||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}Profile{% endblock %}
|
||||
|
||||
{% extends "base.html" %}
|
||||
{% block title %}
|
||||
{{ user.username }}
|
||||
{% endblock title %}
|
||||
{% block content %}
|
||||
<div class="container mt-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card shadow">
|
||||
<div class="card-header bg-info text-white">
|
||||
<h4 class="mb-0"><i class="fas fa-user-circle"></i> User Profile</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-4 text-center">
|
||||
<div class="avatar-placeholder bg-light rounded-circle d-inline-flex align-items-center justify-content-center"
|
||||
style="width: 120px; height: 120px;">
|
||||
<i class="fas fa-user fa-3x text-muted"></i>
|
||||
</div>
|
||||
<h5 class="mt-3">{{ user.username }}</h5>
|
||||
<p class="text-muted">Member since {{ user.date_joined|date:"F Y" }}</p>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<h5>Account Information</h5>
|
||||
<table class="table table-borderless">
|
||||
<tr>
|
||||
<td><strong>Username:</strong></td>
|
||||
<td>{{ user.username }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Email:</strong></td>
|
||||
<td>{{ user.email|default:"Not provided" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Date Joined:</strong></td>
|
||||
<td>{{ user.date_joined|date:"F d, Y" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Last Login:</strong></td>
|
||||
<td>{{ user.last_login|date:"F d, Y H:i"|default:"Never" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Account Status:</strong></td>
|
||||
<td>
|
||||
{% if user.is_active %}
|
||||
<span class="badge bg-success">Active</span>
|
||||
{% else %}
|
||||
<span class="badge bg-danger">Inactive</span>
|
||||
{% endif %}
|
||||
{% if user.is_staff %}
|
||||
<span class="badge bg-warning">Staff</span>
|
||||
{% endif %}
|
||||
{% if user.is_superuser %}
|
||||
<span class="badge bg-danger">Superuser</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="d-flex justify-content-between">
|
||||
<a href="{% url 'twitch:dashboard' %}" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Back to Dashboard
|
||||
</a>
|
||||
<div>
|
||||
<button class="btn btn-outline-primary me-2"
|
||||
onclick="alert('Profile editing feature coming soon!')">
|
||||
<i class="fas fa-edit"></i> Edit Profile
|
||||
</button>
|
||||
<a href="{% url 'accounts:logout' %}" class="btn btn-danger">
|
||||
<i class="fas fa-sign-out-alt"></i> Logout
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Quick Stats Card -->
|
||||
<div class="card shadow mt-4">
|
||||
<div class="card-header bg-secondary text-white">
|
||||
<h5 class="mb-0"><i class="fas fa-chart-bar"></i> Quick Stats</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row text-center">
|
||||
<div class="col-md-6">
|
||||
<div class="stat-card">
|
||||
<h3 class="text-primary">-</h3>
|
||||
<p class="text-muted">Campaigns Tracked</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="stat-card">
|
||||
<h3 class="text-info">-</h3>
|
||||
<p class="text-muted">Games Followed</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.stat-card {
|
||||
padding: 1rem;
|
||||
border-radius: 0.375rem;
|
||||
background-color: #f8f9fa;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.stat-card h3 {
|
||||
font-size: 2rem;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.avatar-placeholder {
|
||||
border: 3px solid #dee2e6;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
<h2>{{ user.username }}</h2>
|
||||
<p>Joined {{ user.date_joined|date:"F d, Y" }}</p>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<strong>Date Joined:</strong>
|
||||
</td>
|
||||
<td>{{ user.date_joined|date:"F d, Y" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<strong>Last Login:</strong>
|
||||
</td>
|
||||
<td>{{ user.last_login|date:"F d, Y H:i"|default:"Never" }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<strong>Email:</strong>
|
||||
</td>
|
||||
<td>{{ user.email|default:"Not provided" }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<a href="{% url 'accounts:logout' %}">Logout</a>
|
||||
{% endblock content %}
|
||||
|
|
|
|||
|
|
@ -1,96 +1,40 @@
|
|||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %}Sign Up{% endblock %}
|
||||
|
||||
{% extends "base.html" %}
|
||||
{% block title %}
|
||||
Sign Up
|
||||
{% endblock title %}
|
||||
{% block content %}
|
||||
<div class="container mt-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6">
|
||||
<div class="card shadow">
|
||||
<div class="card-header bg-success text-white">
|
||||
<h4 class="mb-0"><i class="fas fa-user-plus"></i> Sign Up</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if form.errors %}
|
||||
<div class="alert alert-danger">
|
||||
<ul class="mb-0">
|
||||
{% for field, errors in form.errors.items %}
|
||||
{% for error in errors %}
|
||||
<li>{{ error }}</li>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<div class="mb-3">
|
||||
<label for="{{ form.username.id_for_label }}" class="form-label">Username</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fas fa-user"></i></span>
|
||||
<input type="text" class="form-control" name="username"
|
||||
id="{{ form.username.id_for_label }}" value="{{ form.username.value|default:'' }}"
|
||||
required>
|
||||
</div>
|
||||
{% if form.username.help_text %}
|
||||
<div class="form-text">{{ form.username.help_text }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="{{ form.password1.id_for_label }}" class="form-label">Password</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fas fa-lock"></i></span>
|
||||
<input type="password" class="form-control" name="password1"
|
||||
id="{{ form.password1.id_for_label }}" required>
|
||||
</div>
|
||||
{% if form.password1.help_text %}
|
||||
<div class="form-text">{{ form.password1.help_text }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="{{ form.password2.id_for_label }}" class="form-label">Confirm Password</label>
|
||||
<div class="input-group">
|
||||
<span class="input-group-text"><i class="fas fa-lock"></i></span>
|
||||
<input type="password" class="form-control" name="password2"
|
||||
id="{{ form.password2.id_for_label }}" required>
|
||||
</div>
|
||||
{% if form.password2.help_text %}
|
||||
<div class="form-text">{{ form.password2.help_text }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="d-grid">
|
||||
<button type="submit" class="btn btn-success btn-lg">
|
||||
<i class="fas fa-user-plus"></i> Sign Up
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="card-footer text-center">
|
||||
<p class="mb-0">Already have an account? <a href="{% url 'accounts:login' %}"
|
||||
class="text-decoration-none">Login here</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.form-control {
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
.input-group-text {
|
||||
background-color: #f8f9fa;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.form-text {
|
||||
font-size: 0.875em;
|
||||
color: #6c757d;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
<h4>Sign Up</h4>
|
||||
{% if form.errors %}
|
||||
<ul>
|
||||
{% for field, errors in form.errors.items %}
|
||||
{% for error in errors %}<li>{{ error }}</li>{% endfor %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
<label for="{{ form.username.id_for_label }}">Username</label>
|
||||
<input type="text"
|
||||
name="username"
|
||||
id="{{ form.username.id_for_label }}"
|
||||
value="{{ form.username.value|default:'' }}"
|
||||
required>
|
||||
{% if form.username.help_text %}{{ form.username.help_text }}{% 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 %}
|
||||
<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>
|
||||
</form>
|
||||
<p>
|
||||
Already have an account? <a href="{% url 'accounts:login' %}">Login here</a>
|
||||
</p>
|
||||
{% endblock content %}
|
||||
|
|
|
|||
|
|
@ -1,135 +1,41 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block title %}ttvdrops{% endblock %}</title>
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<!-- FontAwesome -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css">
|
||||
<style>
|
||||
/* Custom styles */
|
||||
.campaign-card {
|
||||
height: 100%;
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description"
|
||||
content="Twitch Drops Tracker - Track your Twitch drops and campaigns easily.">
|
||||
<meta name="keywords" content="Twitch, Drops">
|
||||
<title>
|
||||
{% block title %}
|
||||
ttvdrops
|
||||
{% endblock title %}
|
||||
</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
|
||||
Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
padding: 0 15px;
|
||||
max-width: 650px;
|
||||
font-size: 115%;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.campaign-active {
|
||||
border-left: 4px solid #9147ff;
|
||||
html {
|
||||
color-scheme: light dark;
|
||||
}
|
||||
|
||||
.campaign-upcoming {
|
||||
border-left: 4px solid #1d9bf0;
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.campaign-expired {
|
||||
border-left: 4px solid #6c757d;
|
||||
}
|
||||
|
||||
.drop-item {
|
||||
border-left: 4px solid #9147ff;
|
||||
}
|
||||
|
||||
.twitch-color {
|
||||
color: #9147ff;
|
||||
}
|
||||
|
||||
.bg-twitch {
|
||||
background-color: #9147ff;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.benefit-img {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
}
|
||||
|
||||
.card-header h3 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
</style>
|
||||
{% block extra_css %}{% endblock %}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark mb-4">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="{% url 'twitch:dashboard' %}">
|
||||
<i class="fa-brands fa-twitch me-2"></i>ttvdrops
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav ms-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if request.path == '/' %}active{% endif %}"
|
||||
href="{% url 'twitch:dashboard' %}">
|
||||
<i class="fas fa-home me-1"></i> Dashboard
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if '/campaigns/' in request.path %}active{% endif %}"
|
||||
href="{% url 'twitch:campaign_list' %}">
|
||||
<i class="fas fa-gift me-1"></i> Campaigns
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link {% if '/games/' in request.path %}active{% endif %}"
|
||||
href="{% url 'twitch:game_list' %}">
|
||||
<i class="fas fa-gamepad me-1"></i> Games
|
||||
</a>
|
||||
</li>
|
||||
{% if user.is_authenticated %}
|
||||
{% if user.is_staff %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'admin:index' %}">
|
||||
<i class="fas fa-cog me-1"></i> Admin
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button"
|
||||
data-bs-toggle="dropdown" aria-expanded="false">
|
||||
<i class="fas fa-user me-1"></i> {{ user.username }}
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
|
||||
<li><a class="dropdown-item" href="{% url 'accounts:profile' %}">
|
||||
<i class="fas fa-user-circle me-2"></i> Profile
|
||||
</a></li>
|
||||
<li>
|
||||
<hr class="dropdown-divider">
|
||||
</li>
|
||||
<li><a class="dropdown-item" href="{% url 'accounts:logout' %}">
|
||||
<i class="fas fa-sign-out-alt me-2"></i> Logout
|
||||
</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'accounts:login' %}">
|
||||
<i class="fas fa-sign-in-alt me-1"></i> Login
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'accounts:signup' %}">
|
||||
<i class="fas fa-user-plus me-1"></i> Sign Up
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
{% include "navbar.html" %}
|
||||
<div class="content">
|
||||
{% block content %}
|
||||
<!-- Main content will be injected here -->
|
||||
{% endblock content %}
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container mb-5">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<!-- Bootstrap JS Bundle with Popper -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||
{% block extra_js %}{% endblock %}
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
21
templates/navbar.html
Normal file
21
templates/navbar.html
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<nav>
|
||||
<a href="{% url 'twitch:dashboard' %}"
|
||||
{% if request.path == '/dashboard/' %}class="active"{% endif %}>Dashboard</a>
|
||||
<a href="{% url 'twitch:campaign_list' %}"
|
||||
{% if '/campaigns/' in request.path %}class="active"{% endif %}>Campaigns</a>
|
||||
<a href="{% url 'twitch:game_list' %}"
|
||||
{% if '/games/' in request.path %}class="active"{% endif %}>Games</a>
|
||||
{% if user.is_authenticated %}
|
||||
{% if user.is_staff %}
|
||||
<a href="{% url 'admin:index' %}"
|
||||
{% if '/admin/' in request.path %}class="active"{% endif %}>Admin</a>
|
||||
{% endif %}
|
||||
<a href="{% url 'accounts:profile' %}"
|
||||
{% if '/profile/' in request.path %}class="active"{% endif %}>{{ user.username }}</a>
|
||||
{% else %}
|
||||
<a href="{% url 'accounts:login' %}"
|
||||
{% if '/login/' in request.path %}class="active"{% endif %}>Login</a>
|
||||
<a href="{% url 'accounts:signup' %}"
|
||||
{% if '/signup/' in request.path %}class="active"{% endif %}>Sign Up</a>
|
||||
{% endif %}
|
||||
</nav>
|
||||
|
|
@ -1,152 +1,95 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ campaign.clean_name }} - Twitch Drops Tracker{% endblock %}
|
||||
|
||||
{% load static %}
|
||||
{% block title %}
|
||||
{{ campaign.clean_name }}
|
||||
{% endblock title %}
|
||||
{% block content %}
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="{% url 'twitch:dashboard' %}">Dashboard</a></li>
|
||||
<li class="breadcrumb-item"><a href="{% url 'twitch:campaign_list' %}">Campaigns</a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page">{{ campaign.clean_name }}</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-4">
|
||||
<div class="col-md-8">
|
||||
<h1 class="mb-3">{{ campaign.clean_name }}</h1>
|
||||
<div class="d-flex flex-wrap gap-2 mb-3">
|
||||
<a href="{% url 'twitch:game_detail' campaign.game.id %}" class="badge bg-primary text-decoration-none">
|
||||
<i class="fas fa-gamepad me-1"></i>{{ campaign.game.display_name }}
|
||||
</a>
|
||||
{% if campaign.start_at <= now and campaign.end_at >= now %}
|
||||
{% if campaign.status == 'ACTIVE' %}
|
||||
<span class="badge bg-success">Active</span>
|
||||
{% else %}
|
||||
<span class="badge bg-warning text-dark">{{ campaign.status|title }}</span>
|
||||
{% endif %}
|
||||
{% elif campaign.start_at > now %}
|
||||
<span class="badge bg-info text-dark">Upcoming</span>
|
||||
{% else %}
|
||||
<span class="badge bg-secondary">Expired</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<p>{{ campaign.description }}</p>
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-6">
|
||||
<p><strong><i class="far fa-calendar-alt me-2"></i>Start Date:</strong>
|
||||
{{ campaign.start_at|date:"F j, Y, g:i a" }}</p>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<p><strong><i class="far fa-calendar-alt me-2"></i>End Date:</strong>
|
||||
{{ campaign.end_at|date:"F j, Y, g:i a" }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% if campaign.details_url %}
|
||||
<h1>
|
||||
<a href="{% url 'twitch:game_detail' campaign.game.id %}">{{ campaign.game.display_name }}</a> - {{ campaign.clean_name }}
|
||||
</h1>
|
||||
<p>
|
||||
{# TODO: Link to organization #}
|
||||
<a href="#">{{ campaign.owner.name }}</a>
|
||||
</p>
|
||||
{% if campaign.image_url %}
|
||||
<img height="70"
|
||||
width="70"
|
||||
src="{{ campaign.image_url }}"
|
||||
alt="{{ campaign.name }}">
|
||||
{% endif %}
|
||||
<p>{{ campaign.description }}</p>
|
||||
<p>
|
||||
Start:
|
||||
{{ campaign.start_at }}
|
||||
</p>
|
||||
<p>
|
||||
End:
|
||||
{{ campaign.end_at }}
|
||||
</p>
|
||||
{% if campaign.details_url %}
|
||||
{# TODO: Archive this URL automatically #}
|
||||
<p>
|
||||
<a href="{{ campaign.details_url }}" target="_blank" class="btn btn-outline-primary">
|
||||
<i class="fas fa-external-link-alt me-2"></i>Official Details
|
||||
</a>
|
||||
<a href="{{ campaign.details_url }}" target="_blank">Official Details</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if campaign.account_link_url %}
|
||||
{% endif %}
|
||||
{% if campaign.account_link_url %}
|
||||
{# TODO: Archive this URL automatically #}
|
||||
<p>
|
||||
<a href="{{ campaign.account_link_url }}" target="_blank" class="btn btn-success">
|
||||
<i class="fas fa-link me-2"></i>Connect Account
|
||||
</a>
|
||||
<a href="{{ campaign.account_link_url }}" target="_blank">Connect Account</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
{% if campaign.image_url %}
|
||||
<img src="{{ campaign.image_url }}" class="img-fluid rounded shadow-sm" alt="{{ campaign.name }}">
|
||||
{% else %}
|
||||
<div class="bg-light rounded shadow-sm p-4 text-center">
|
||||
<i class="fas fa-image fa-5x text-muted mb-3"></i>
|
||||
<p class="text-muted">No image available</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="card mt-3 border-0 shadow-sm">
|
||||
<div class="card-header bg-dark text-white">
|
||||
<h5 class="mb-0"><i class="fas fa-info-circle me-2"></i>Campaign Info</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p><strong>Owner:</strong> {{ campaign.owner.name }}</p>
|
||||
<p><strong>Status:</strong> {{ campaign.status }}</p>
|
||||
<p><strong>Account Connected:</strong> {% if campaign.is_account_connected %}<span
|
||||
class="text-success">Yes</span>{% else %}<span class="text-danger">No</span>{% endif %}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-twitch">
|
||||
<h5 class="mb-0"><i class="fas fa-gift me-2"></i>Rewards</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if drops %}
|
||||
<div class="timeline-container">
|
||||
{% for drop in drops %}
|
||||
<div class="card mb-4 drop-item">
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<h4>{{ drop.name }}</h4>
|
||||
<p class="mb-2">
|
||||
<span class="badge bg-primary">{{ drop.required_minutes_watched }} minutes
|
||||
watched</span>
|
||||
{% if drop.required_subs > 0 %}
|
||||
<span class="badge bg-info">{{ drop.required_subs }} subscriptions
|
||||
required</span>
|
||||
{% endif %}
|
||||
</p>
|
||||
<p class="mb-2">
|
||||
<small class="text-muted">
|
||||
<i class="far fa-clock me-1"></i>Available:
|
||||
{{ drop.start_at|date:"M d, Y" }} - {{ drop.end_at|date:"M d, Y" }}
|
||||
</small>
|
||||
</p>
|
||||
<div class="progress mb-3" style="height: 25px;">
|
||||
<div class="progress-bar bg-twitch" role="progressbar" style="width: 0%;"
|
||||
aria-valuenow="0" aria-valuemin="0"
|
||||
aria-valuemax="{{ drop.required_minutes_watched }}">
|
||||
0 / {{ drop.required_minutes_watched }} minutes
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 text-center">
|
||||
{% for benefit in drop.benefits.all %}
|
||||
<div class="mb-2">
|
||||
{% if benefit.image_asset_url %}
|
||||
<img src="{{ benefit.image_asset_url }}" class="benefit-img mb-2"
|
||||
alt="{{ benefit.name }}">
|
||||
{% else %}
|
||||
<div class="bg-light rounded p-3 mb-2">
|
||||
<i class="fas fa-gift fa-3x text-muted"></i>
|
||||
</div>
|
||||
{% endif %}
|
||||
<p class="mb-0"><strong>{{ benefit.name }}</strong></p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-info">
|
||||
<i class="fas fa-info-circle me-2"></i>No drops found for this campaign.
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% 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 %}
|
||||
<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">
|
||||
{% 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 %}
|
||||
</table>
|
||||
{% else %}
|
||||
<p>No drops available for this campaign.</p>
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
|
|
|
|||
|
|
@ -1,286 +1,114 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Drop Campaigns - Twitch Drops Tracker{% endblock %}
|
||||
|
||||
{% load static %}
|
||||
{% block title %}
|
||||
Drop Campaigns - Twitch Drops Tracker
|
||||
{% endblock title %}
|
||||
{% block content %}
|
||||
<div class="row mb-3">
|
||||
<div class="col">
|
||||
<h1 class="mb-2"><i class="fas fa-gift me-2 twitch-color"></i>Drop Campaigns</h1>
|
||||
<p class="lead mb-3">Browse all Twitch drop campaigns.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-12">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-dark text-white py-2">
|
||||
<h5 class="mb-0"><i class="fas fa-filter me-2"></i>Filter Campaigns</h5>
|
||||
</div>
|
||||
<div class="card-body py-3">
|
||||
<form method="get" action="{% url 'twitch:campaign_list' %}" class="row g-3">
|
||||
<div class="col-md-3">
|
||||
<label for="game" class="form-label">Game</label>
|
||||
<select class="form-select" id="game" name="game">
|
||||
<option value="">All Games</option>
|
||||
{% for game in games %}
|
||||
<option value="{{ game.id }}" {% if selected_game == game.id %}selected{% endif %}>
|
||||
{{ game.display_name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label for="status" class="form-label">Status</label>
|
||||
<select class="form-select" id="status" name="status">
|
||||
<option value="">All Statuses</option>
|
||||
{% for status in status_options %}
|
||||
<option value="{{ status }}" {% if selected_status == status %}selected{% endif %}>
|
||||
{{ status|title }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label for="per_page" class="form-label">Per Page</label>
|
||||
<select class="form-select" id="per_page" name="per_page">
|
||||
{% for option in per_page_options %}
|
||||
<option value="{{ option }}" {% if selected_per_page == option %}selected{% endif %}>
|
||||
{{ option }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4 d-flex align-items-end">
|
||||
<button type="submit" class="btn btn-primary w-100">
|
||||
<i class="fas fa-search me-2"></i>Apply Filters
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-twitch py-2">
|
||||
<h5 class="mb-0"><i class="fas fa-list me-2"></i>Campaign List</h5>
|
||||
</div>
|
||||
<div class="card-body py-3">
|
||||
{% if campaigns %}
|
||||
<div class="row g-3">
|
||||
{% for campaign in campaigns %}
|
||||
<div class="col-md-6 col-lg-4 col-xl-3">
|
||||
{% if campaign.start_at <= now and campaign.end_at >= now %}
|
||||
{% if campaign.status == 'ACTIVE' %}
|
||||
<div class="campaign-card campaign-active border rounded p-2">
|
||||
{% else %}
|
||||
<div class="campaign-card border rounded p-2">
|
||||
{% endif %}
|
||||
{% elif campaign.start_at > now %}
|
||||
<div class="campaign-card campaign-upcoming border rounded p-2">
|
||||
{% else %}
|
||||
<div class="campaign-card campaign-expired border rounded p-2">
|
||||
{% endif %}
|
||||
<div class="d-flex">
|
||||
<div class="campaign-image flex-shrink-0 me-3">
|
||||
{% if campaign.image_url %}
|
||||
<img src="{{ campaign.image_url }}" width="70" height="70"
|
||||
class="rounded" alt="{{ campaign.name }}"
|
||||
style="object-fit: cover;">
|
||||
{% else %}
|
||||
<div class="bg-light rounded"
|
||||
style="width: 70px; height: 70px; display: flex; align-items: center; justify-content: center;">
|
||||
<i class="fas fa-image text-muted" style="font-size: 1.5rem;"></i>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="campaign-details min-w-0">
|
||||
<div class="title-wrapper" style="min-height: 2.4rem;">
|
||||
<h6 class="mb-1" title="{{ campaign.name }}"
|
||||
style="display: -webkit-box; display: box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; box-orient: vertical; overflow: hidden; font-size: 0.9rem;">
|
||||
{{ campaign.clean_name }}</h6>
|
||||
</div>
|
||||
<p class="mb-1 small text-muted text-truncate">
|
||||
<a href="{% url 'twitch:game_detail' campaign.game.id %}"
|
||||
class="text-decoration-none"
|
||||
title="{{ campaign.game.display_name }}">
|
||||
<i
|
||||
class="fas fa-gamepad me-1"></i>{{ campaign.game.display_name }}
|
||||
</a>
|
||||
</p>
|
||||
<p class="mb-0 small text-muted">
|
||||
<i
|
||||
class="far fa-calendar-alt me-1"></i>{{ campaign.start_at|date:"M d, Y" }}
|
||||
- {{ campaign.end_at|date:"M d, Y" }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between align-items-center mt-2">
|
||||
{% if campaign.start_at <= now and campaign.end_at >= now %}
|
||||
{% if campaign.status == 'ACTIVE' %}
|
||||
<span class="badge bg-success">Active</span>
|
||||
{% else %}
|
||||
<span class="badge bg-warning text-dark">{{ campaign.status|title }}</span>
|
||||
{% endif %}
|
||||
{% elif campaign.start_at > now %}
|
||||
<span class="badge bg-info text-dark">Upcoming</span>
|
||||
{% else %}
|
||||
<span class="badge bg-secondary">Expired</span>
|
||||
{% endif %}
|
||||
<a href="{% url 'twitch:campaign_detail' campaign.id %}"
|
||||
class="btn btn-sm btn-outline-primary">Details</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="alert alert-info py-2">
|
||||
<i class="fas fa-info-circle me-2"></i>No campaigns found with the current filters.
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pagination -->
|
||||
{% if is_paginated %}
|
||||
<div class="row mt-3">
|
||||
<div class="col-12">
|
||||
<nav aria-label="Campaign pagination">
|
||||
<ul class="pagination justify-content-center">
|
||||
{% if page_obj.has_previous %}
|
||||
<li class="page-item">
|
||||
<a class="page-link"
|
||||
href="?{% if selected_status %}status={{ selected_status }}&{% endif %}{% if selected_game %}game={{ selected_game }}&{% endif %}{% if selected_per_page != 24 %}per_page={{ selected_per_page }}&{% endif %}page=1"
|
||||
aria-label="First">
|
||||
<span aria-hidden="true">««</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a class="page-link"
|
||||
href="?{% if selected_status %}status={{ selected_status }}&{% endif %}{% if selected_game %}game={{ selected_game }}&{% endif %}{% if selected_per_page != 24 %}per_page={{ selected_per_page }}&{% endif %}page={{ page_obj.previous_page_number }}"
|
||||
aria-label="Previous">
|
||||
<span aria-hidden="true">«</span>
|
||||
</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="page-item disabled">
|
||||
<span class="page-link" aria-label="First">
|
||||
<span aria-hidden="true">««</span>
|
||||
</span>
|
||||
</li>
|
||||
<li class="page-item disabled">
|
||||
<span class="page-link" aria-label="Previous">
|
||||
<span aria-hidden="true">«</span>
|
||||
</span>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% for num in page_obj.paginator.page_range %}
|
||||
{% if page_obj.number == num %}
|
||||
<li class="page-item active">
|
||||
<span class="page-link">{{ num }}</span>
|
||||
</li>
|
||||
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
|
||||
<li class="page-item">
|
||||
<a class="page-link"
|
||||
href="?{% if selected_status %}status={{ selected_status }}&{% endif %}{% if selected_game %}game={{ selected_game }}&{% endif %}{% if selected_per_page != 24 %}per_page={{ selected_per_page }}&{% endif %}page={{ num }}">{{ num }}</a>
|
||||
</li>
|
||||
{% elif num == 1 or num == page_obj.paginator.num_pages %}
|
||||
<li class="page-item">
|
||||
<a class="page-link"
|
||||
href="?{% if selected_status %}status={{ selected_status }}&{% endif %}{% if selected_game %}game={{ selected_game }}&{% endif %}{% if selected_per_page != 24 %}per_page={{ selected_per_page }}&{% endif %}page={{ num }}">{{ num }}</a>
|
||||
</li>
|
||||
{% elif num == page_obj.number|add:'-4' or num == page_obj.number|add:'4' %}
|
||||
<li class="page-item disabled">
|
||||
<span class="page-link">...</span>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if page_obj.has_next %}
|
||||
<li class="page-item">
|
||||
<a class="page-link"
|
||||
href="?{% if selected_status %}status={{ selected_status }}&{% endif %}{% if selected_game %}game={{ selected_game }}&{% endif %}{% if selected_per_page != 24 %}per_page={{ selected_per_page }}&{% endif %}page={{ page_obj.next_page_number }}"
|
||||
aria-label="Next">
|
||||
<span aria-hidden="true">»</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="page-item">
|
||||
<a class="page-link"
|
||||
href="?{% if selected_status %}status={{ selected_status }}&{% endif %}{% if selected_game %}game={{ selected_game }}&{% endif %}{% if selected_per_page != 24 %}per_page={{ selected_per_page }}&{% endif %}page={{ page_obj.paginator.num_pages }}"
|
||||
aria-label="Last">
|
||||
<span aria-hidden="true">»»</span>
|
||||
</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="page-item disabled">
|
||||
<span class="page-link" aria-label="Next">
|
||||
<span aria-hidden="true">»</span>
|
||||
</span>
|
||||
</li>
|
||||
<li class="page-item disabled">
|
||||
<span class="page-link" aria-label="Last">
|
||||
<span aria-hidden="true">»»</span>
|
||||
</span>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 text-center">
|
||||
<small class="text-muted">
|
||||
Showing {{ page_obj.start_index }} to {{ page_obj.end_index }} of {{ page_obj.paginator.count }}
|
||||
campaigns
|
||||
(Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }})
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
<h1>Drop Campaigns</h1>
|
||||
<form method="get" action="{% url 'twitch:campaign_list' %}">
|
||||
<!-- Game Filter -->
|
||||
<select id="game" name="game">
|
||||
<option value="">All Games</option>
|
||||
{% for game in games %}
|
||||
<option value="{{ game.id }}"
|
||||
{% if selected_game == game.id %}selected{% endif %}>{{ game.display_name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<!-- Status Filter -->
|
||||
<select id="status" name="status">
|
||||
<option value="">All Statuses</option>
|
||||
{% for status in status_options %}
|
||||
<option value="{{ status }}"
|
||||
{% if selected_status == status %}selected{% endif %}>{{ status|title }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<button type="submit">Apply Filters</button>
|
||||
</form>
|
||||
<h5>Campaign List</h5>
|
||||
{% if campaigns %}
|
||||
{% for campaign in campaigns %}
|
||||
{% if campaign.image_url %}
|
||||
<img src="{{ campaign.image_url }}"
|
||||
width="70"
|
||||
height="70"
|
||||
alt="{{ campaign.name }}">
|
||||
{% else %}
|
||||
<img src="{% static 'images/placeholder.png' %}"
|
||||
width="70"
|
||||
height="70"
|
||||
alt="No Image Available">
|
||||
{% endif %}
|
||||
|
||||
<div class="row mt-3">
|
||||
<div class="col-12">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-dark text-white py-2">
|
||||
<h5 class="mb-0"><i class="fas fa-chart-bar me-2"></i>Quick Stats</h5>
|
||||
</div>
|
||||
<div class="card-body py-3">
|
||||
<div class="row text-center g-2">
|
||||
<div class="col-md-4 mb-2 mb-md-0">
|
||||
<div class="p-2 border rounded">
|
||||
<h3 class="twitch-color mb-0">
|
||||
{% if is_paginated %}
|
||||
{{ page_obj.paginator.count }}
|
||||
{% else %}
|
||||
{{ campaigns|length }}
|
||||
{% endif %}
|
||||
</h3>
|
||||
<p class="mb-0 small text-muted">Total Campaigns</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 mb-2 mb-md-0">
|
||||
<div class="p-2 border rounded">
|
||||
<h3 class="text-primary mb-0">{{ now|date:"F j, Y" }}</h3>
|
||||
<p class="mb-0 small text-muted">Current Date</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="p-2 border rounded">
|
||||
<a href="{% url 'twitch:game_list' %}" class="btn btn-primary w-100">
|
||||
<i class="fas fa-gamepad me-1"></i>All Games
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
<h6 title="{{ campaign.name }}">{{ campaign.clean_name }}</h6>
|
||||
<p>
|
||||
<a href="{% url 'twitch:game_detail' campaign.game.id %}"
|
||||
title="{{ campaign.game.display_name }}">{{ campaign.game.display_name }}</a>
|
||||
</p>
|
||||
<p>
|
||||
{{ campaign.start_at|date:"M d, Y" }}
|
||||
- {{ campaign.end_at|date:"M d, Y" }}
|
||||
</p>
|
||||
{% if campaign.start_at <= now and campaign.end_at >= now %}
|
||||
{% if campaign.status == 'ACTIVE' %}Active{% endif %}
|
||||
{% elif campaign.start_at > now %}
|
||||
Upcoming
|
||||
{% else %}
|
||||
Expired
|
||||
{% endif %}
|
||||
<a href="{% url 'twitch:campaign_detail' campaign.id %}">Details</a>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
No campaigns found with the current filters.
|
||||
{% endif %}
|
||||
<!-- Pagination -->
|
||||
{% if is_paginated %}
|
||||
<nav>
|
||||
<ul>
|
||||
{% if page_obj.has_previous %}
|
||||
<li>
|
||||
<a href="?{% if selected_status %}status={{ selected_status }}&{% endif %}{% if selected_game %}game={{ selected_game }}&{% endif %}{% if selected_per_page != 24 %}per_page={{ selected_per_page }}&{% endif %}page=1">
|
||||
««
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="?{% if selected_status %}status={{ selected_status }}&{% endif %}{% if selected_game %}game={{ selected_game }}&{% endif %}{% if selected_per_page != 24 %}per_page={{ selected_per_page }}&{% endif %}page={{ page_obj.previous_page_number }}"
|
||||
aria-label="Previous">«</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li>««</li>
|
||||
<li>«</li>
|
||||
{% endif %}
|
||||
{% for num in page_obj.paginator.page_range %}
|
||||
{% if page_obj.number == num %}
|
||||
<li>{{ num }}</li>
|
||||
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
|
||||
<li>
|
||||
<a href="?{% if selected_status %}status={{ selected_status }}&{% endif %}{% if selected_game %}game={{ selected_game }}&{% endif %}{% if selected_per_page != 24 %}per_page={{ selected_per_page }}&{% endif %}page={{ num }}">{{ num }}</a>
|
||||
</li>
|
||||
{% elif num == 1 or num == page_obj.paginator.num_pages %}
|
||||
<li>
|
||||
<a href="?{% if selected_status %}status={{ selected_status }}&{% endif %}{% if selected_game %}game={{ selected_game }}&{% endif %}{% if selected_per_page != 24 %}per_page={{ selected_per_page }}&{% endif %}page={{ num }}">{{ num }}</a>
|
||||
</li>
|
||||
{% elif num == page_obj.number|add:'-4' or num == page_obj.number|add:'4' %}
|
||||
<li>...</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if page_obj.has_next %}
|
||||
<li>
|
||||
<a href="?{% if selected_status %}status={{ selected_status }}&{% endif %}{% if selected_game %}game={{ selected_game }}&{% endif %}{% if selected_per_page != 24 %}per_page={{ selected_per_page }}&{% endif %}page={{ page_obj.next_page_number }}">»</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="?{% if selected_status %}status={{ selected_status }}&{% endif %}{% if selected_game %}game={{ selected_game }}&{% endif %}{% if selected_per_page != 24 %}per_page={{ selected_per_page }}&{% endif %}page={{ page_obj.paginator.num_pages }}">»»</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li>»</li>
|
||||
<li>»»</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</nav>
|
||||
<small>
|
||||
Showing {{ page_obj.start_index }} to {{ page_obj.end_index }} of {{ page_obj.paginator.count }}
|
||||
campaigns
|
||||
(Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }})
|
||||
</small>
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
|
|
|
|||
|
|
@ -1,192 +1,50 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Dashboard - Twitch Drops Tracker{% endblock %}
|
||||
|
||||
{% load static %}
|
||||
{% block title %}
|
||||
Dashboard
|
||||
{% endblock title %}
|
||||
{% block content %}
|
||||
<div class="row mb-2">
|
||||
<div class="col">
|
||||
<h2 class="mb-1"><i class="fas fa-tachometer-alt me-2 twitch-color"></i>Dashboard</h2>
|
||||
<p class="small text-muted mb-2">Track your active Twitch drop campaigns and progress.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.org-section {
|
||||
border-left: 3px solid #9146FF;
|
||||
padding-left: 10px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.game-section {
|
||||
border-left: 2px solid #6441A4;
|
||||
padding-left: 8px;
|
||||
margin-left: 5px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.org-section h5 {
|
||||
color: #9146FF;
|
||||
font-size: 1.1rem;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.game-section h6 {
|
||||
font-size: 0.95rem;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.game-section h6 a {
|
||||
color: #6441A4;
|
||||
}
|
||||
|
||||
.game-section h6 a:hover {
|
||||
color: #9146FF;
|
||||
}
|
||||
|
||||
.campaign-card {
|
||||
padding: 8px !important;
|
||||
margin-bottom: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.campaign-image img,
|
||||
.campaign-image div {
|
||||
width: 50px !important;
|
||||
height: 50px !important;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 0.75rem !important;
|
||||
}
|
||||
|
||||
.title-wrapper {
|
||||
min-height: 1.9rem !important;
|
||||
}
|
||||
|
||||
.title-wrapper h6 {
|
||||
font-size: 0.85rem !important;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.mb-3 {
|
||||
margin-bottom: 0.75rem !important;
|
||||
}
|
||||
|
||||
.mb-4 {
|
||||
margin-bottom: 1rem !important;
|
||||
}
|
||||
|
||||
.g-3 {
|
||||
--bs-gutter-y: 0.5rem !important;
|
||||
--bs-gutter-x: 0.5rem !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="row mb-2">
|
||||
<div class="col-12">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-twitch py-1">
|
||||
<h5 class="mb-0"><i class="fas fa-fire me-1"></i>Active Campaigns</h5>
|
||||
</div>
|
||||
<div class="card-body py-3">
|
||||
{% if campaigns_by_org_game %}
|
||||
{% for org_id, org_data in campaigns_by_org_game.items %}
|
||||
<div class="org-section mb-4">
|
||||
<h5><i class="fas fa-building me-1"></i>{{ org_data.name }}</h5>
|
||||
|
||||
{% for game_id, game_data in org_data.games.items %}
|
||||
<div class="game-section mb-3">
|
||||
<h6>
|
||||
<a href="{% url 'twitch:game_detail' game_id %}" class="text-decoration-none">
|
||||
<i class="fas fa-gamepad me-1"></i>{{ game_data.name }}
|
||||
</a>
|
||||
</h6>
|
||||
|
||||
<div class="row g-3">
|
||||
{% for campaign in game_data.campaigns %}
|
||||
<div class="col-md-4 col-lg-3 col-xl-2">
|
||||
<div class="campaign-card campaign-active border rounded">
|
||||
<div class="d-flex">
|
||||
<div class="campaign-image flex-shrink-0 me-2">
|
||||
{% if campaign.image_url %}
|
||||
<img src="{{ campaign.image_url }}" class="rounded"
|
||||
alt="{{ campaign.name }}" style="object-fit: cover;">
|
||||
{% else %}
|
||||
<div class="bg-light rounded"
|
||||
style="display: flex; align-items: center; justify-content: center;">
|
||||
<i class="fas fa-image text-muted" style="font-size: 1.2rem;"></i>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="campaign-details min-w-0">
|
||||
<div class="title-wrapper">
|
||||
<h6 class="mb-0" title="{{ campaign.name }}"
|
||||
style="display: -webkit-box; display: box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; box-orient: vertical; overflow: hidden;">
|
||||
{{ campaign.clean_name }}</h6>
|
||||
</div>
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="badge bg-success" style="font-size: 0.7rem;">Active</span>
|
||||
<small class="text-muted ms-1" style="font-size: 0.7rem;">Ends
|
||||
{{ campaign.end_at|date:"M d" }}</small>
|
||||
</div>
|
||||
<a href="{% url 'twitch:campaign_detail' campaign.id %}"
|
||||
class="stretched-link"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% if campaigns_by_org_game %}
|
||||
{% for org_id, org_data in campaigns_by_org_game.items %}
|
||||
<h2>{{ org_data.name }}</h2>
|
||||
{% for game_id, game_data in org_data.games.items %}
|
||||
<h3>
|
||||
<a href="{% url 'twitch:game_detail' game_id %}">{{ game_data.name }}</a>
|
||||
</h3>
|
||||
<p>{{ game_data.campaigns.0.description|default:"No description available."|linebreaksbr }}</p>
|
||||
<table style="width:100%">
|
||||
<tr>
|
||||
<th style="width:25%">Image</th>
|
||||
<th>Campaign</th>
|
||||
<th>Ends In</th>
|
||||
</tr>
|
||||
{% for campaign in game_data.campaigns %}
|
||||
<tr>
|
||||
<td>
|
||||
{% if campaign.image_url %}
|
||||
<img height="160"
|
||||
width="160"
|
||||
src="{{ campaign.image_url }}"
|
||||
alt="{{ campaign.name }}">
|
||||
{% else %}
|
||||
<img height="160"
|
||||
width="160"
|
||||
src="{% static 'images/placeholder.png' %}"
|
||||
alt="No Image Available">
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<a href="{% url 'twitch:campaign_detail' campaign.id %}">{{ campaign.clean_name }}</a>
|
||||
</td>
|
||||
<td>
|
||||
<span title="{{ campaign.end_at|date:'M d, Y H:i' }}">Ends in {{ campaign.end_at|timeuntil }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="alert alert-info py-2">
|
||||
<i class="fas fa-info-circle me-2"></i>No active campaigns at the moment.
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-dark text-white py-1">
|
||||
<h5 class="mb-0"><i class="fas fa-chart-bar me-1"></i>Quick Stats</h5>
|
||||
</div>
|
||||
<div class="card-body py-2">
|
||||
<div class="row text-center g-2">
|
||||
<div class="col-md-3 mb-1 mb-md-0">
|
||||
<div class="p-1 border rounded">
|
||||
<h4 class="twitch-color mb-0">{{ active_campaigns.count }}</h4>
|
||||
<p class="mb-0 small text-muted" style="font-size: 0.75rem;">Active Campaigns</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 mb-1 mb-md-0">
|
||||
<div class="p-1 border rounded">
|
||||
<h4 class="text-primary mb-0">{{ campaigns_by_org_game|length }}</h4>
|
||||
<p class="mb-0 small text-muted" style="font-size: 0.75rem;">Organizations</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 mb-1 mb-md-0">
|
||||
<div class="p-1 border rounded">
|
||||
<h4 class="text-primary mb-0">{{ now|date:"M j" }}</h4>
|
||||
<p class="mb-0 small text-muted" style="font-size: 0.75rem;">Current Date</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="p-1 border rounded">
|
||||
<a href="{% url 'twitch:campaign_list' %}" class="btn btn-primary btn-sm w-100">
|
||||
<i class="fas fa-list me-1"></i>All Campaigns
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
</table>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
No active campaigns at the moment.
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
|
|
|
|||
|
|
@ -1,169 +1,61 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}{{ game.display_name }} - Twitch Drops Tracker{% endblock %}
|
||||
|
||||
{% block title %}
|
||||
{{ game.display_name }}
|
||||
{% endblock title %}
|
||||
{% block content %}
|
||||
<div class="row mb-4">
|
||||
<div class="col">
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item"><a href="{% url 'twitch:game_list' %}">Games</a></li>
|
||||
<li class="breadcrumb-item active" aria-current="page">{{ game.display_name }}</li>
|
||||
</ol>
|
||||
</nav>
|
||||
<h1 class="mb-4">
|
||||
<i class="fas fa-gamepad me-2 twitch-color"></i>{{ game.display_name }}
|
||||
</h1>
|
||||
<p class="lead">View all drop campaigns for {{ game.display_name }}.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if active_campaigns %}
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-success text-white">
|
||||
<h5 class="mb-0"><i class="fas fa-circle-play me-2"></i>Active Campaigns</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Campaign</th>
|
||||
<th>Organization</th>
|
||||
<th>Time Remaining</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for campaign in active_campaigns %}
|
||||
<tr>
|
||||
<td>{{ campaign.clean_name }}</td>
|
||||
<td>{{ campaign.owner.name }}</td>
|
||||
<td>
|
||||
<span class="badge bg-success" data-bs-toggle="tooltip"
|
||||
title="Ends on {{ campaign.end_at|date:'M d, Y H:i' }}">
|
||||
Ends in {{ campaign.end_at|timeuntil }}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{% url 'twitch:campaign_detail' campaign.id %}"
|
||||
class="btn btn-sm btn-primary">
|
||||
<i class="fas fa-eye me-1"></i> View Details
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if upcoming_campaigns %}
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-info text-white">
|
||||
<h5 class="mb-0"><i class="fas fa-calendar-alt me-2"></i>Upcoming Campaigns</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Campaign</th>
|
||||
<th>Organization</th>
|
||||
<th>Starts In</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for campaign in upcoming_campaigns %}
|
||||
<tr>
|
||||
<td>{{ campaign.clean_name }}</td>
|
||||
<td>{{ campaign.owner.name }}</td>
|
||||
<td>
|
||||
<span class="badge bg-info text-dark" data-bs-toggle="tooltip"
|
||||
title="Starts on {{ campaign.start_at|date:'M d, Y H:i' }}">
|
||||
Starts in {{ campaign.start_at|timeuntil }}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{% url 'twitch:campaign_detail' campaign.id %}"
|
||||
class="btn btn-sm btn-primary">
|
||||
<i class="fas fa-eye me-1"></i> View Details
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if expired_campaigns %}
|
||||
<div class="row mb-4">
|
||||
<div class="col-12">
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card-header bg-secondary text-white">
|
||||
<h5 class="mb-0"><i class="fas fa-history me-2"></i>Past Campaigns</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Campaign</th>
|
||||
<th>Organization</th>
|
||||
<th>Ended</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for campaign in expired_campaigns %}
|
||||
<tr>
|
||||
<td>{{ campaign.clean_name }}</td>
|
||||
<td>{{ campaign.owner.name }}</td>
|
||||
<td>
|
||||
<span class="badge bg-secondary" data-bs-toggle="tooltip"
|
||||
title="Ended on {{ campaign.end_at|date:'M d, Y H:i' }}">
|
||||
{{ campaign.end_at|timesince }} ago
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<a href="{% url 'twitch:campaign_detail' campaign.id %}"
|
||||
class="btn btn-sm btn-primary">
|
||||
<i class="fas fa-eye me-1"></i> View Details
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if not active_campaigns and not upcoming_campaigns and not expired_campaigns %}
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="alert alert-info">
|
||||
<i class="fas fa-info-circle me-2"></i> No campaigns found for this game.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
<h1>{{ game.display_name }}</h1>
|
||||
{% if active_campaigns %}
|
||||
<h5>Active Campaigns</h5>
|
||||
<table>
|
||||
<tbody>
|
||||
{% for campaign in active_campaigns %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{% url 'twitch:campaign_detail' campaign.id %}">{{ campaign.clean_name }}</a>
|
||||
</td>
|
||||
<td>
|
||||
<span title="{{ campaign.end_at|date:'M d, Y H:i' }}">Ends in {{ campaign.end_at|timeuntil }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
{% if upcoming_campaigns %}
|
||||
<h5>Upcoming Campaigns</h5>
|
||||
<table>
|
||||
<tbody>
|
||||
{% for campaign in upcoming_campaigns %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{% url 'twitch:campaign_detail' campaign.id %}">{{ campaign.clean_name }}</a>
|
||||
</td>
|
||||
<td>
|
||||
<span title="Starts on {{ campaign.start_at|date:'M d, Y H:i' }}">Starts in {{ campaign.start_at|timeuntil }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
{% if expired_campaigns %}
|
||||
<h5>Past Campaigns</h5>
|
||||
<table>
|
||||
<tbody>
|
||||
{% for campaign in expired_campaigns %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{% url 'twitch:campaign_detail' campaign.id %}">{{ campaign.clean_name }}</a>
|
||||
</td>
|
||||
<td>
|
||||
<span title="Ended on {{ campaign.end_at|date:'M d, Y H:i' }}">{{ campaign.end_at|timesince }} ago</span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endif %}
|
||||
{% if not active_campaigns and not upcoming_campaigns and not expired_campaigns %}
|
||||
No campaigns found for this game.
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
|
|
|
|||
|
|
@ -1,60 +1,25 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Games by Organization - Twitch Drops Tracker{% endblock %}
|
||||
|
||||
{% block title %}
|
||||
Games by Organization - Twitch Drops Tracker
|
||||
{% endblock title %}
|
||||
{% block content %}
|
||||
<div class="row mb-4">
|
||||
<div class="col">
|
||||
<h1 class="mb-4"><i class="fas fa-gamepad me-2 twitch-color"></i>Games by Organization</h1>
|
||||
<p class="lead">Browse all games with Twitch drop campaigns, grouped by organization.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if games_by_org %}
|
||||
{% for organization, games in games_by_org.items %}
|
||||
<div class="card mb-4 shadow-sm">
|
||||
<div class="card-header bg-dark text-white">
|
||||
<h3 class="mb-0">
|
||||
<i class="fas fa-building me-2"></i>{{ organization.name }}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row row-cols-1 row-cols-md-3 g-4">
|
||||
{% for item in games %}
|
||||
<div class="col">
|
||||
<div class="card h-100 border-0 shadow-sm">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">
|
||||
<a href="{% url 'twitch:game_detail' item.game.id %}" class="text-decoration-none">
|
||||
{{ item.game.display_name }}
|
||||
</a>
|
||||
</h5>
|
||||
<div class="d-flex justify-content-between mt-3">
|
||||
<span class="badge bg-secondary">
|
||||
<i class="fas fa-gift me-1"></i> {{ item.campaign_count }} Campaigns
|
||||
</span>
|
||||
{% if item.active_count > 0 %}
|
||||
<span class="badge bg-success">
|
||||
<i class="fas fa-circle-play me-1"></i> {{ item.active_count }} Active
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer bg-transparent border-0">
|
||||
<a href="{% url 'twitch:game_detail' item.game.id %}" class="btn btn-sm btn-primary">
|
||||
<i class="fas fa-eye me-1"></i> View Campaigns
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="alert alert-info">
|
||||
<i class="fas fa-info-circle me-2"></i> No games found.
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
<h1>Games by Organization</h1>
|
||||
{% if games_by_org %}
|
||||
{% for organization, games in games_by_org.items %}
|
||||
<h2>{{ organization.name }}</h2>
|
||||
<table>
|
||||
<tbody>
|
||||
{% for item in games %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{% url 'twitch:game_detail' item.game.id %}">{{ item.game.display_name }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
No games found.
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue