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,59 +1,236 @@
{% extends "static/static_base.html" %}
{% extends "static/login_base.html" %}
{% block title %}enviPath - Sign In{% endblock %}
{% block extra_styles %}
/* Tab styling */ .tab-content { display: none; } .tab-content.active {
display: block; } input[type="radio"].tab-radio { display: none; } .tab-label
{ cursor: pointer; padding: 0.75rem 1.5rem; border-bottom: 2px solid
transparent; transition: all 0.3s ease; } .tab-label:hover { background-color:
rgba(0, 0, 0, 0.05); } input[type="radio"].tab-radio:checked + .tab-label {
border-bottom-color: #3b82f6; font-weight: 600; }
{% endblock %}
{% block content %}
{% if message %}
<div class="alert alert-danger" role="alert">
{{ message }}
</div>
{% elif success_message %}
<div class="alert alert-success" role="alert">
{{ success_message }}
</div>
{% else %}
<div class="alert alert-success" role="alert">
Kia ora! We are running our closed beta tests at the moment. It would be great to get your help as tester,
you
can apply to become tester by registering for this page, just hit the button below. More information on the
beta
test is available in our <a href="https://community.envipath.org/t/apply-to-join-our-closed-beta/95">
community
form</a>
</div>
{% endif %}
<div class="modal-dialog" style="margin:30px auto; z-index:9999;">
<div class="modal-content">
<div class="modal-body">
<form class="form-horizontal" method="post" action="{% url 'login' %}">
{% csrf_token %}
<fieldset>
<div class="control-group">
<label class="control-label" for="username">Username</label>
<div class="controls">
<input required id="username" name="username" type="text"
class="form-control" placeholder="username" autocomplete="username">
</div>
<label class="control-label" for="passwordinput">Password:</label>
<div class="controls">
<input required id="passwordinput" name="password" class="form-control"
type="password" placeholder="********" autocomplete="current-password">
</div>
<div class="form-group text-center" style="margin-top:15px;">
<a href="{% url 'password_reset' %}">Forgot your password?</a>
</div>
</div>
<!-- Tab Navigation -->
<div class="border-b border-base-300 mb-6">
<div class="flex justify-start">
<input
type="radio"
name="auth-tab"
id="tab-signin"
class="tab-radio"
checked
/>
<label for="tab-signin" class="tab-label">Sign In</label>
<div class="control-group">
<label class="control-label" for="signin"></label>
<div class="controls">
<button id="signin" name="signin" class="btn btn-success pull-right">Sign In
</button>
<a class="btn btn-primary" href="{% url 'register' %}">Create an Account</a>
</div>
</div>
<input type="hidden" name="next" value="{{ next }}"/>
</fieldset>
</form>
</div>
</div>
<input type="radio" name="auth-tab" id="tab-signup" class="tab-radio" />
<label for="tab-signup" class="tab-label">Register</label>
</div>
</div>
<!-- Sign In Tab -->
<div id="content-signin" class="tab-content active">
<form method="post" action="{% url 'login' %}" class="space-y-4">
{% csrf_token %}
<input type="hidden" name="login" value="true" />
<div class="form-control">
<label class="label" for="username">
<span class="label-text">Username</span>
</label>
<input
type="text"
id="username"
name="username"
placeholder="username"
class="input input-bordered w-full"
required
autocomplete="username"
/>
</div>
<div class="form-control">
<label class="label" for="passwordinput">
<span class="label-text">Password</span>
</label>
<input
type="password"
id="passwordinput"
name="password"
placeholder="••••••••"
class="input input-bordered w-full"
required
autocomplete="current-password"
/>
</div>
<div class="text-right">
<a href="{% url 'password_reset' %}" class="link link-primary text-sm"
>Forgot password?</a
>
</div>
<input type="hidden" name="next" value="{{ next }}" />
<button type="submit" name="signin" class="btn btn-primary w-full">
Sign In
</button>
</form>
</div>
<!-- Register Tab -->
<div id="content-signup" class="tab-content">
<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>
<form method="post" action="{% url 'register' %}" class="space-y-4">
{% csrf_token %}
<input type="hidden" name="register" value="true" />
<div class="form-control">
<label class="label" for="userid">
<span class="label-text">Username</span>
</label>
<input
type="text"
id="userid"
name="username"
placeholder="username"
class="input input-bordered w-full"
required
autocomplete="username"
/>
</div>
<div class="form-control">
<label class="label" for="email">
<span class="label-text">Email</span>
</label>
<input
type="email"
id="email"
name="email"
placeholder="user@envipath.org"
class="input input-bordered w-full"
required
autocomplete="email"
/>
</div>
<div class="form-control">
<label class="label" for="password">
<span class="label-text">Password</span>
</label>
<input
type="password"
id="password"
name="password"
placeholder="••••••••"
class="input input-bordered w-full"
required
autocomplete="new-password"
/>
</div>
<div class="form-control">
<label class="label" for="rpassword">
<span class="label-text">Repeat Password</span>
</label>
<input
type="password"
id="rpassword"
name="rpassword"
placeholder="••••••••"
class="input input-bordered w-full"
required
autocomplete="new-password"
/>
</div>
<input type="hidden" name="next" value="{{ next }}" />
<button type="submit" name="confirmsignup" class="btn btn-success w-full">
Sign Up
</button>
</form>
<!-- Why Register Section -->
<div class="mt-6 p-4 bg-base-200 rounded-lg">
<h3 class="font-semibold mb-2">Why register?</h3>
<p class="text-sm mb-2">
enviPath is free for academic research and educational purposes.
However, we require registration to ensure the security of the platform
and to prevent abuse.
</p>
<p class="text-sm mt-3">
Questions? Check our
<a
href="https://wiki.envipath.org/"
target="_blank"
class="link link-primary"
>documentation</a
>
or the
<a
href="https://community.envipath.org/"
target="_blank"
class="link link-primary"
>community forums</a
>.
</p>
</div>
</div>
{% endblock %}
{% block extra_scripts %}
<script>
// Tab switching functionality
document.querySelectorAll('input[name="auth-tab"]').forEach((radio) => {
radio.addEventListener("change", function () {
// Hide all content
document.querySelectorAll(".tab-content").forEach((content) => {
content.classList.remove("active");
});
// Show selected content
const contentId = "content-" + this.id.replace("tab-", "");
document.getElementById(contentId).classList.add("active");
});
});
// Check for hash in URL to auto-select tab
window.addEventListener("DOMContentLoaded", function () {
const hash = window.location.hash.substring(1); // Remove the # symbol
if (hash === "signup" || hash === "signin") {
const tabRadio = document.getElementById("tab-" + hash);
if (tabRadio) {
tabRadio.checked = true;
// Trigger change event to show correct content
tabRadio.dispatchEvent(new Event("change"));
}
}
});
</script>
{% endblock %}