Frontpage update (#179)

This PR introduces an overhaul for the front page and login features while keeping the rest of the application intact.

## Major Changes

- TailwindCSS + DaisyUI Integration: Add  modern CSS framework for component-based utility styling
- Build System: Added pnpm for CSS building; can be extended for updated frontend builds in the future
- Navbar + Footer: Redesigned and includable; old version retained for unstyled elements
- Optimized Assets: Added minified and CSS-stylable logos

## New Features

- Static Pages: Added comprehensive mockups of static pages (legal, privacy policy, terms of use, contact, etc.). **Note:** These have to be fixed before a public release, as their content is largely unreviewed and incorrect. Probably best to do in a separate PR that only contains updates to these.
- Discourse API: Implement minimal features based on RestAPI for controllable results.

## Current bugs
- [x] The static pages include the default navbar and footer on the login page. This will likely not work, as users need to access it before logging in; no good workaround so far (problem with Django templating system).
- [ ] The front page predict link is currently non-functional; the redesigned page is almost ready but better done in a separate PR as it also touches Django code.
- [x] Visual bug with the news cards. Still intend to fix for this PR

Co-authored-by: Tim Lorsbach <tim@lorsba.ch>
Reviewed-on: enviPath/enviPy#179
Reviewed-by: jebus <lorsbach@envipath.com>
Co-authored-by: Tobias O <tobias.olenyi@envipath.com>
Co-committed-by: Tobias O <tobias.olenyi@envipath.com>
This commit is contained in:
2025-11-12 01:09:39 +13:00
committed by jebus
parent 34589efbde
commit ddf1fd3515
47 changed files with 4271 additions and 999 deletions

View File

@ -1,31 +1,94 @@
{% extends "static/static_base.html" %}
{% extends "static/login_base.html" %}
{% block title %}enviPath - Set New Password{% endblock %}
{% block content %}
<div class="modal-dialog" style="margin:30px auto; z-index:9999;">
<div class="modal-content">
<div class="modal-body">
<h2>Enter new password</h2>
<form method="post">
{% csrf_token %}
<p>
<label for="id_new_password1">New password:</label>
<input type="password" class="form-control" name="new_password1" autocomplete="new-password"
required=""
aria-describedby="id_new_password1_helptext" id="id_new_password1">
<span class="helptext" id="id_new_password1_helptext"></span></p>
<!-- Title -->
<div class="mb-8">
<h2 class="text-3xl font-bold mb-2">Set New Password</h2>
<p class="text-base-content/70">Please enter your new password below.</p>
</div>
{{ form.new_password1.help_text|safe }}
<p>
<label for="id_new_password2">New password confirmation:</label>
<input type="password" class="form-control" name="new_password2" autocomplete="new-password"
required=""
aria-describedby="id_new_password2_helptext" id="id_new_password2">
{{ form.new_password2.help_text|safe }}
</p>
<button class="btn btn-primary" type="submit">Reset Password</button>
</form>
<!-- Messages -->
{% if validlink %}
<!-- Password Requirements Info -->
<div class="alert alert-info mb-4 text-sm">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="h-6 w-6 shrink-0 stroke-current">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<div>
<div class="font-bold">Password Requirements</div>
<div class="text-xs mt-1">
• 8 to 30 characters<br>
• Upper and lower case letters<br>
• Digits and special characters (_, -, +)
</div>
</div>
</div>
{% endblock %}
<!-- Reset Password Form -->
<form method="post" class="space-y-4">
{% csrf_token %}
<div class="form-control">
<label class="label" for="id_new_password1">
<span class="label-text">New Password</span>
</label>
<input type="password" id="id_new_password1" name="new_password1" placeholder="••••••••"
class="input input-bordered w-full" required autocomplete="new-password">
{% if form.new_password1.help_text %}
<label class="label">
<span class="label-text-alt text-base-content/60">{{ form.new_password1.help_text }}</span>
</label>
{% endif %}
{% if form.new_password1.errors %}
<label class="label">
<span class="label-text-alt text-error">{{ form.new_password1.errors|join:", " }}</span>
</label>
{% endif %}
</div>
<div class="form-control">
<label class="label" for="id_new_password2">
<span class="label-text">Confirm New Password</span>
</label>
<input type="password" id="id_new_password2" name="new_password2" placeholder="••••••••"
class="input input-bordered w-full" required autocomplete="new-password">
{% if form.new_password2.help_text %}
<label class="label">
<span class="label-text-alt text-base-content/60">{{ form.new_password2.help_text }}</span>
</label>
{% endif %}
{% if form.new_password2.errors %}
<label class="label">
<span class="label-text-alt text-error">{{ form.new_password2.errors|join:", " }}</span>
</label>
{% endif %}
</div>
<button type="submit" class="btn btn-primary w-full">Reset Password</button>
</form>
{% else %}
<!-- Invalid Link -->
<div class="alert alert-error mb-6">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 shrink-0 stroke-current" fill="none" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<div>
<div class="font-bold">Invalid Reset Link</div>
<div class="text-sm">This password reset link is invalid or has expired.</div>
</div>
</div>
<div class="space-y-4">
<a href="{% url 'password_reset' %}" class="btn btn-primary w-full">Request New Reset Link</a>
</div>
{% endif %}
<!-- Back to Sign In -->
<div class="mt-6 text-center text-sm text-base-content/70">
<p>Remember your password?
<a href="{% url 'login' %}" class="link link-primary">Sign in</a>
</p>
</div>
{% endblock %}