working base site setup with gatekeeping working

This commit is contained in:
2026-08-03 12:43:33 -05:00
parent 2764644d8b
commit 85e6241ad4
37 changed files with 1146 additions and 58 deletions
+2 -2
View File
@@ -8,8 +8,8 @@
<link rel="stylesheet" href="{% static 'css/style.css' %}">
{% block extra_head %}{% endblock %}
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css">
<link rel="stylesheet" href="{% static 'fonts/roboto.css' %}">
<link rel="stylesheet" href="{% static 'fontawesome/css/all.min.css' %}">
<link rel="icon" type="image/png" href="{% static 'Logo.png' %}">
</head>
<body>
+30
View File
@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Packs Site - Restricted{% endblock %}</title>
{% load static %}
<link rel="stylesheet" href="{% static 'css/style.css' %}">
<link rel="icon" type="image/png" href="{% static 'Logo.png' %}">
</head>
<body>
<main class="gate-main">
<div class="gate-card">
<img src="{% static 'Logo.png' %}" alt="Packs" height="64">
<h1>Restricted Access</h1>
<p>This site is private. Enter the master password to continue.</p>
{% if error %}
<p class="gate-error">{{ error }}</p>
{% endif %}
<form method="post" action="{% url 'landing:gate' %}">
{% csrf_token %}
<input type="password" name="password" placeholder="Master password" autofocus required>
<button type="submit">Enter</button>
</form>
</div>
</main>
</body>
</html>
+146
View File
@@ -0,0 +1,146 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Home - Packs Site{% endblock %}
{% block content %}
<div class="home-hero">
<div class="home-hero-inner">
<h1>Packs Site</h1>
<p>Hosted datapacks for Needs Of Nature &amp; Animation Director.</p>
<p class="home-hero-sub">Browse and download packs shared by the community. Upload your own once you have a creator account.</p>
<div class="home-hero-actions">
<a href="#" class="btn btn-primary"><i class="fas fa-download"></i> Browse packs</a>
<a href="#" class="btn btn-secondary"><i class="fas fa-upload"></i> Upload a pack</a>
</div>
</div>
</div>
<div class="home-stats">
<div class="stat-card">
<i class="fas fa-users"></i>
<span class="stat-value">0</span>
<span class="stat-label">Creators</span>
</div>
<div class="stat-card">
<i class="fas fa-box-open"></i>
<span class="stat-value">0</span>
<span class="stat-label">Packs</span>
</div>
<div class="stat-card">
<i class="fas fa-download"></i>
<span class="stat-value">0</span>
<span class="stat-label">Downloads</span>
</div>
<div class="stat-card">
<i class="fas fa-tag"></i>
<span class="stat-value">0</span>
<span class="stat-label">Versions</span>
</div>
</div>
<div class="home-section">
<div class="home-section-header">
<h2>Latest packs</h2>
<a href="#" class="home-section-link">View all <i class="fas fa-arrow-right"></i></a>
</div>
<div class="pack-grid">
{% comment %} Example cards — replace with real Pack objects when the library model lands. {% endcomment %}
<a href="#" class="pack-card">
<div class="pack-card-thumb">
<img src="{% static 'Logo.png' %}" alt="">
</div>
<div class="pack-card-body">
<h3>Example Pack</h3>
<p class="pack-card-author"><i class="fas fa-user"></i> a_creator</p>
<p class="pack-card-desc">Placeholder description for a datapack.</p>
<div class="pack-card-meta">
<span class="pack-card-version"><i class="fas fa-tag"></i> v1.0.0</span>
<span class="pack-card-downloads"><i class="fas fa-download"></i> 0</span>
</div>
</div>
</a>
<a href="#" class="pack-card">
<div class="pack-card-thumb">
<img src="{% static 'Logo.png' %}" alt="">
</div>
<div class="pack-card-body">
<h3>Another Pack</h3>
<p class="pack-card-author"><i class="fas fa-user"></i> someone</p>
<p class="pack-card-desc">This card shows what the library grid will look like.</p>
<div class="pack-card-meta">
<span class="pack-card-version"><i class="fas fa-tag"></i> v0.9.2</span>
<span class="pack-card-downloads"><i class="fas fa-download"></i> 0</span>
</div>
</div>
</a>
<a href="#" class="pack-card">
<div class="pack-card-thumb">
<img src="{% static 'Logo.png' %}" alt="">
</div>
<div class="pack-card-body">
<h3>Third Example</h3>
<p class="pack-card-author"><i class="fas fa-user"></i> dev</p>
<p class="pack-card-desc">Static assets, profile pictures and zip downloads land under /media/&lt;user&gt;/&lt;pack&gt;/.</p>
<div class="pack-card-meta">
<span class="pack-card-version"><i class="fas fa-tag"></i> v1.1.0</span>
<span class="pack-card-downloads"><i class="fas fa-download"></i> 0</span>
</div>
</div>
</a>
<a href="#" class="pack-card">
<div class="pack-card-thumb">
<img src="{% static 'Logo.png' %}" alt="">
</div>
<div class="pack-card-body">
<h3>And Another</h3>
<p class="pack-card-author"><i class="fas fa-user"></i> tester</p>
<p class="pack-card-desc">Responsive grid, Catppuccin-styled, ready for real data.</p>
<div class="pack-card-meta">
<span class="pack-card-version"><i class="fas fa-tag"></i> v0.1.0</span>
<span class="pack-card-downloads"><i class="fas fa-download"></i> 0</span>
</div>
</div>
</a>
</div>
</div>
<div class="home-section">
<div class="home-section-header">
<h2>How it works</h2>
</div>
<div class="how-grid">
<div class="how-card">
<i class="fas fa-key"></i>
<h3>Enter the site</h3>
<p>Use the master password to get in. It only grants access to browse and download.</p>
</div>
<div class="how-card">
<i class="fas fa-user-plus"></i>
<h3>Create an account</h3>
<p>Creators register to get their own profile, upload packs and manage their content.</p>
</div>
<div class="how-card">
<i class="fas fa-upload"></i>
<h3>Share packs</h3>
<p>Upload a .zip plus page assets. Everything is stored under your own folder.</p>
</div>
<div class="how-card">
<i class="fas fa-robot"></i>
<h3>Keep mods updated</h3>
<p>The Fabric mod checks the API with your personal token and downloads new versions automatically.</p>
</div>
</div>
</div>
<div class="home-section">
<div class="home-gate-note">
<i class="fas fa-shield-halved"></i>
<p>This is a private site. All content is gated and only reachable by authorized users. Unauthorized API or media requests are rejected with <code>401 Unauthorized</code>.</p>
</div>
</div>
{% endblock %}
+13
View File
@@ -0,0 +1,13 @@
{% extends 'base.html' %}
{% block title %}Login - Packs{% endblock %}
{% block content %}
<h1>Login</h1>
<form method="post" action="{% url 'profiles:login' %}">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Log in</button>
</form>
<p>No account? <a href="{% url 'profiles:register' %}">Register</a></p>
{% endblock %}
+13
View File
@@ -0,0 +1,13 @@
{% extends 'base.html' %}
{% block title %}Register - Packs{% endblock %}
{% block content %}
<h1>Register</h1>
<form method="post" action="{% url 'profiles:register' %}">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Register</button>
</form>
<p>Already have an account? <a href="{% url 'profiles:login' %}">Log in</a></p>
{% endblock %}
+60
View File
@@ -0,0 +1,60 @@
{% extends 'base.html' %}
{% block title %}Settings - Packs{% endblock %}
{% block content %}
<h1>Settings</h1>
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
<h2>API Tokens</h2>
<p>Tokens let non-browser clients (like a Fabric mod) access the API and download packs.</p>
<p class="token-hint">
Send credentials as <code>Authorization: Bearer &lt;username&gt; &lt;token&gt;</code>,
e.g. <code>Authorization: Bearer {{ request.user.username }} &lt;token&gt;</code>
</p>
<form method="post" action="{% url 'profiles:token_create' %}" class="token-create">
{% csrf_token %}
<input type="text" name="label" placeholder="Token label (e.g. Fabric updater)" required>
<button type="submit">Create token</button>
</form>
{% if tokens %}
<table class="token-table">
<thead>
<tr>
<th>Label</th>
<th>Credential</th>
<th>Created</th>
<th>Last used</th>
<th></th>
</tr>
</thead>
<tbody>
{% for token in tokens %}
<tr>
<td>{{ token.label }}</td>
<td><code>{{ request.user.username }} {{ token.token }}</code></td>
<td>{{ token.created_at }}</td>
<td>{{ token.last_used|default:"never" }}</td>
<td>
<form method="post" action="{% url 'profiles:token_delete' token.id %}">
{% csrf_token %}
<button type="submit">Revoke</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No tokens yet.</p>
{% endif %}
{% endblock %}