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

@ -90,6 +90,7 @@ def login(request):
if username != request.POST.get("username"):
context["message"] = "Login failed!"
return render(request, "static/login.html", context)
password = request.POST.get("password")
# Get email for username and check if the account is active
@ -104,6 +105,7 @@ def login(request):
except get_user_model().DoesNotExist:
context["message"] = "Login failed!"
return render(request, "static/login.html", context)
try:
user = authenticate(username=email, password=password)
except Exception:
@ -141,9 +143,14 @@ def register(request):
context = get_base_context(request)
if request.method == "GET":
context["title"] = "enviPath"
context["next"] = request.GET.get("next", "")
return render(request, "static/register.html", context)
# Redirect to unified login page with signup tab
next_url = request.GET.get("next", "")
redirect_url = reverse("login") + "#signup"
if next_url:
redirect_url += f"?next={next_url}"
return redirect(redirect_url)
elif request.method == "POST":
context["title"] = "enviPath"
if next := request.POST.get("next"):
@ -156,18 +163,18 @@ def register(request):
if not (username and email and password):
context["message"] = "Invalid username/email/password"
return render(request, "static/register.html", context)
return render(request, "static/login.html", context)
if password != rpassword or password == "":
context["message"] = "Registration failed, provided passwords differ!"
return render(request, "static/register.html", context)
return render(request, "static/login.html", context)
try:
u = UserManager.create_user(username, email, password)
logger.info(f"Created user {u.username} ({u.pk})")
except Exception:
context["message"] = "Registration failed! Couldn't create User Account."
return render(request, "static/register.html", context)
return render(request, "static/login.html", context)
if s.ADMIN_APPROVAL_REQUIRED:
context["success_message"] = (
@ -674,7 +681,7 @@ def search(request):
if request.method == "GET":
package_urls = request.GET.getlist("packages")
searchterm = request.GET.get("search").strip()
searchterm = request.GET.get("search", "").strip()
mode = request.GET.get("mode")
@ -2894,3 +2901,60 @@ def userinfo(request):
"email_verified": user.is_active,
}
return JsonResponse(res)
# Static Pages
def static_terms_of_use(request):
context = get_base_context(request)
context["title"] = "enviPath - Terms of Use"
context["public_mode"] = True
return render(request, "static/terms_of_use.html", context)
def static_privacy_policy(request):
context = get_base_context(request)
context["title"] = "enviPath - Privacy Policy"
context["public_mode"] = True
return render(request, "static/privacy_policy.html", context)
def static_cookie_policy(request):
context = get_base_context(request)
context["title"] = "enviPath - Cookie Policy"
context["public_mode"] = True
return render(request, "static/cookie_policy.html", context)
def static_about_us(request):
context = get_base_context(request)
context["title"] = "enviPath - About Us"
context["public_mode"] = True
return render(request, "static/about_us.html", context)
def static_contact_support(request):
context = get_base_context(request)
context["title"] = "enviPath - Contact & Support"
context["public_mode"] = True
return render(request, "static/contact.html", context)
def static_careers(request):
context = get_base_context(request)
context["title"] = "enviPath - Careers"
context["public_mode"] = True
return render(request, "static/careers.html", context)
def static_cite(request):
context = get_base_context(request)
context["title"] = "enviPath - How to Cite"
context["public_mode"] = True
return render(request, "static/cite.html", context)
def static_legal(request):
context = get_base_context(request)
context["title"] = "enviPath - Legal Information"
context["public_mode"] = True
return render(request, "static/legal.html", context)