Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added mysite/accounts/__init__.py
Empty file.
3 changes: 3 additions & 0 deletions mysite/accounts/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.contrib import admin

# Register your models here.
6 changes: 6 additions & 0 deletions mysite/accounts/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class AccountsConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "accounts"
Empty file.
3 changes: 3 additions & 0 deletions mysite/accounts/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.db import models

# Create your models here.
3 changes: 3 additions & 0 deletions mysite/accounts/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
10 changes: 10 additions & 0 deletions mysite/accounts/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from django.urls import path

from .views import SignUpView, ProfileView

app_name = "accounts"

urlpatterns = [
path("signup/", SignUpView.as_view(), name="signup"),
path('profile/', ProfileView.as_view(), name="profile"),
]
21 changes: 21 additions & 0 deletions mysite/accounts/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User
from django.urls import reverse_lazy
from django.views.generic import CreateView, UpdateView


class SignUpView(CreateView):
form_class = UserCreationForm
success_url = reverse_lazy("login")
template_name = "registration/signup.html"

class ProfileView(LoginRequiredMixin, UpdateView):
model = User
fields = ["username", "first_name", "last_name", "email"]
template_name = "registration/user_settings.html"
context_object_name = "user"
success_url = reverse_lazy("dpp:home")

def get_object(self):
return self.request.user
31 changes: 31 additions & 0 deletions mysite/dpp/migrations/0040_productionline_created_by_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Generated by Django 6.0.5 on 2026-06-17 11:13

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('dpp', '0039_alter_instruction_label_and_more'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.AddField(
model_name='productionline',
name='created_by',
field=models.ForeignKey(default=2, on_delete=django.db.models.deletion.CASCADE, related_name='production_lines', to=settings.AUTH_USER_MODEL),
preserve_default=False,
),
migrations.AlterField(
model_name='productbatch',
name='model',
field=models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='batch', to='dpp.productmodel'),
),
migrations.AlterUniqueTogether(
name='transport',
unique_together={('production_line', 'product')},
),
]
2 changes: 2 additions & 0 deletions mysite/dpp/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from django.db import models, transaction
from django.db.models.signals import m2m_changed
from django.dispatch import receiver
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator, MaxValueValidator, FileExtensionValidator
from django_countries.fields import CountryField
Expand Down Expand Up @@ -588,6 +589,7 @@ class ProductionLine(models.Model):
modified_at = models.DateField(auto_now=True)
mass_balance = models.ForeignKey(Document, blank=True, null=True, on_delete=models.SET_NULL, related_name='pl_mass_balance', help_text="Add a document showing all material flows going in and out of the production line. (Optional)")
energy_balance = models.ForeignKey(Document, blank=True, null=True, on_delete=models.SET_NULL, related_name='pl_energy_balance', help_text="Add a document showing all energy flows going in and out of the production line. (Optional)")
created_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name='production_lines')

def __str__(self):
return self.name
Expand Down
23 changes: 20 additions & 3 deletions mysite/dpp/templates/dpp/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,28 @@ <h1 class="text-xl font-bold">Lasers4MaaS DPP Platform</h1>
<object data="/static/img/leaf-svgrepo-com.svg" type="image/svg+xml" width="24" height="24"></object>
Sustainability evaluations
</a>
<a href="#" class="flex items-center px-4 py-2 mt-2 text-gray-100 hover:bg-gray-700">
</nav>
</div>
<div class="text-gray-100 px-4 py-2 mt-2">
{% if user.is_authenticated %}
<div class="flex items-center hover:bg-gray-700">
<a href="{% url 'accounts:profile' %}" class="flex items-center">
<object data="/static/img/user-svgrepo-com.svg" type="image/svg+xml" width="24" height="24"></object>
User profile
<span class="ml-2">{{ user.username }}</span>
</a>
</nav>
<form action="{% url 'logout' %}" method="post" class="ml-auto">
{% csrf_token %}
<button type="submit" class="hover:underline">
Log Out
</button>
</form>
</div>
{% else %}
<a href="{% url 'login' %}" class="flex items-center hover:bg-gray-700">
<object data="/static/img/user-svgrepo-com.svg" type="image/svg+xml" width="24" height="24"></object>
<span class="ml-2">Log In</span>
</a>
{% endif %}
</div>
</aside>
{% endif %} <!-- End of sidebar-->
Expand Down
165 changes: 69 additions & 96 deletions mysite/dpp/templates/dpp/welcome.html
Original file line number Diff line number Diff line change
@@ -1,104 +1,77 @@
{% extends "base.html" %}
{% load i18n %}
{% load static %}
<link rel="stylesheet" href="{% static 'css/components.css' %}">

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Welcome | Lasers4MaaS SCE</title>
<script src="https://cdn.tailwindcss.com"></script>
<style type="text/css">
.sidenav {
height: 100%;
width: 150pt;
position: fixed;
z-index: 1;
top: 80px;
left: 0;
background-color: #666;
overflow-x: hidden;
padding-top: 10px;
}
</style>
</head>
{% if not is_popup %}
{% block header %}
<div id="header" style="background:#088488; color:white; padding:15px 20px; min-height:60px;">
<div style="max-width:1200px; margin:auto; display:flex">
<!-- Logo + Title -->
<div style="display:flex; align-items:left; gap:15px;">
<img src="{% static 'img/L4M_logo.png' %}"
style="height: 40px; width: auto;"
alt="Logo">
<a href="/" style="color:white; text-decoration:none; font-size:22px; font-weight:bold;">
Lasers4MaaS Sustainability Cost Evaluation
{% block title %}Welcome | Lasers4MaaS SCE{% endblock %}

{% block content %}
<h1 class="text-2xl py-3 font-bold">Welcome to the Lasers4MaaS SCE Platform</h1>

{% if user.is_authenticated %}
<p>Logged in as {{user.username}}</p>
<form action="{% url 'logout' %}" method="post">
{% csrf_token %}
<button type="submit" class="px-4 py-2 bg-black text-white font-bold rounded hover:bg-gray-700 transition">Log Out</button>
</form>

{% if latest_lines %}
<p>Recently modified production lines:</p>
<div class="overflow-x-auto">
<table class="divide-gray-200">
<thead class="bg-gray-100">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">
Name
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">
Last Modified
</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
{% for production_line in latest_lines %}
<tr class="hover:bg-gray-50">
<td class="px-2 py-4 whitespace-nowrap text-sm font-medium">
<a href="{% url 'dpp:productionline_detail' production_line.pk %}"
class="text-indigo-600 hover:text-indigo-800 hover:underline">
{{ production_line.name }}
</a>
</div>
</div>
</div>
{% endblock %}
</td>
<td class="px-2 py-4 whitespace-nowrap text-sm text-gray-500">
{{ production_line.modified_at|date:"d M Y" }}
</td>
</tr>
{% empty %}
<tr>
<td colspan="2" class="px-6 py-4 text-center text-gray-500">
No production lines created yet.
</td>
</tr>
{% endfor %}
<tr class="hover:bg-gray-50">
<td class="px-4 py-4 whitespace-nowrap text-sm font-medium">
<a href="{% url 'dpp:productionline_list' %}"
class="text-indigo-600 hover:text-indigo-800 hover:underline">
See detailed list
</a>
</td>
<td></td>
</tr>
</tbody>
</table>
</div>
{% else %}
<p>No production lines created yet.</p>
{% endif %}

{% block content %}
<body class="px-6 py-6">
<h1 class="text-2xl py-3 font-bold">Welcome to the Lasers4MaaS SCE Platform</h1>
{% if latest_lines %}
<p>Recently modified production lines:</p>
<div class="overflow-x-auto">
<table class="divide-gray-200">
<thead class="bg-gray-100">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">
Name
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wider">
Last Modified
</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
{% for production_line in latest_lines %}
<tr class="hover:bg-gray-50">
<td class="px-2 py-4 whitespace-nowrap text-sm font-medium">
<a href="{% url 'dpp:productionline_detail' production_line.pk %}"
class="text-indigo-600 hover:text-indigo-800 hover:underline">
{{ production_line.name }}
</a>
</td>
<td class="px-2 py-4 whitespace-nowrap text-sm text-gray-500">
{{ production_line.modified_at|date:"d M Y" }}
</td>
</tr>
{% empty %}
<tr>
<td colspan="2" class="px-6 py-4 text-center text-gray-500">
No production lines created yet.
</td>
</tr>
{% endfor %}
<tr class="hover:bg-gray-50">
<td class="px-4 py-4 whitespace-nowrap text-sm font-medium">
<a href="{% url 'dpp:productionline_list' %}"
class="text-indigo-600 hover:text-indigo-800 hover:underline">
See detailed list
</a>
</td>
<td></td>
</tr>
</tbody>
</table>
</div>
{% else %}
<p>No production lines created yet.</p>
{% endif %}
<div class="add-button">
<a href="{% url 'dpp:productionline_add' %}" class="btn btn-primary">
Start a new production line
</a>
</div>

<div class="add-button">
<a href="{% url 'dpp:productionline_add' %}" class="btn btn-primary">
Start a new production line
</a>
</div>
</body>
{% else %}
<p>You are not logged in</p>
<a href="{% url 'login' %}" class="px-4 py-2 bg-blue-500 text-white font-bold rounded hover:bg-blue-700 transition">Log In</a>
{% endif %}
{% endblock %}
</html>
7 changes: 4 additions & 3 deletions mysite/dpp/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@

def home(request):
"""Welcome page """
latest_lines = ProductionLine.objects.order_by("-modified_at")[:5]
if len(latest_lines) > 5:
latest_lines = latest_lines[:5]
if request.user.is_authenticated:
latest_lines = ProductionLine.objects.filter(created_by=request.user).order_by("-modified_at")[:5]
else:
latest_lines = ProductionLine.objects.order_by("-modified_at")[:5]
context = {'latest_lines': latest_lines}
return render(request, "dpp/welcome.html", context)

Expand Down
7 changes: 6 additions & 1 deletion mysite/mysite/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
'crispy_forms',
'crispy_tailwind',
'api',
'accounts',
'dpp.apps.DppConfig',
'rest_framework',
]
Expand All @@ -61,7 +62,7 @@
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'DIRS': [BASE_DIR / "templates"],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
Expand Down Expand Up @@ -137,3 +138,7 @@
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

# Redirect users to the homepage
LOGIN_REDIRECT_URL = "/dpp/welcome"
LOGOUT_REDIRECT_URL = "/dpp/welcome"
2 changes: 2 additions & 0 deletions mysite/mysite/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@
path('admin/', admin.site.urls),
path('api/', include("api.urls")), # API endpoints
path('dpp/', include("dpp.urls")), # Frontend application
path("accounts/", include("accounts.urls")), # User registration
path("accounts/", include("django.contrib.auth.urls")), # User login
]
36 changes: 36 additions & 0 deletions mysite/templates/base.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{% load i18n %}
{% load static %}
<link rel="stylesheet" href="{% static 'css/components.css' %}">

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}Lasers4MaaS authentication{% endblock %}</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
{% block header %}
<div id="header" style="background:#088488; color:white; padding:15px 20px; min-height:60px;">
<div style="max-width:1200px; margin:auto; display:flex">
<!-- Logo + Title -->
<div style="display:flex; align-items:left; gap:15px;">
<img src="{% static 'img/L4M_logo.png' %}"
style="height: 40px; width: auto;"
alt="Logo">
<a href="/" style="color:white; text-decoration:none; font-size:22px; font-weight:bold;">
Lasers4MaaS Sustainability Cost Evaluation
</a>
</div>
</div>
</div>
{% endblock %}

<body class="px-6 py-6">
<main>
{% block content %}
{% endblock %}
</main>
</body>

</html>
Loading