From 02ae3bdd145faa7d7985f87bd77b214f95142c23 Mon Sep 17 00:00:00 2001 From: James <james2.burt@live.uwe.ac.uk> Date: Wed, 19 Mar 2025 15:34:16 +0000 Subject: [PATCH] log in systems for all users work correctly as well as /admin page all with database --- .idea/DjangoDocker.iml | 7 +- .idea/misc.xml | 2 +- ActualProjectCode/DjangoProject/core/admin.py | 16 +- ActualProjectCode/DjangoProject/core/forms.py | 6 + .../DjangoProject/core/models.py | 15 +- ActualProjectCode/DjangoProject/core/views.py | 69 +++++- .../DjangoProject/server/settings.py | 4 +- .../DjangoProject/server/urls.py | 10 +- .../DjangoProject/static/styles.css | 218 +++++++++++------- .../DjangoProject/templates/index.html | 38 ++- .../DjangoProject/templates/login.html | 23 ++ .../DjangoProject/templates/profile.html | 25 ++ .../DjangoProject/templates/register.html | 22 ++ 13 files changed, 324 insertions(+), 131 deletions(-) create mode 100644 ActualProjectCode/DjangoProject/core/forms.py create mode 100644 ActualProjectCode/DjangoProject/templates/login.html create mode 100644 ActualProjectCode/DjangoProject/templates/profile.html create mode 100644 ActualProjectCode/DjangoProject/templates/register.html diff --git a/.idea/DjangoDocker.iml b/.idea/DjangoDocker.iml index 95172f2d..72ca9979 100644 --- a/.idea/DjangoDocker.iml +++ b/.idea/DjangoDocker.iml @@ -14,13 +14,10 @@ </component> <component name="NewModuleRootManager"> <content url="file://$MODULE_DIR$"> + <sourceFolder url="file://$MODULE_DIR$/ActualProjectCode/DjangoProject" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/mainDockerImage/backend" isTestSource="false" /> </content> - <orderEntry type="jdk" jdkName="Python 3.13" jdkType="Python SDK" /> + <orderEntry type="jdk" jdkName="C:\Users\james\AppData\Local\Programs\Python\Python311\python.exe" jdkType="Python SDK" /> <orderEntry type="sourceFolder" forTests="false" /> </component> - <component name="PyDocumentationSettings"> - <option name="format" value="PLAIN" /> - <option name="myDocStringFormat" value="Plain" /> - </component> </module> \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 1d3ce46b..52b60581 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,5 +3,5 @@ <component name="Black"> <option name="sdkName" value="Python 3.13" /> </component> - <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.13" project-jdk-type="Python SDK" /> + <component name="ProjectRootManager" version="2" project-jdk-name="C:\Users\james\AppData\Local\Programs\Python\Python311\python.exe" project-jdk-type="Python SDK" /> </project> \ No newline at end of file diff --git a/ActualProjectCode/DjangoProject/core/admin.py b/ActualProjectCode/DjangoProject/core/admin.py index 62ebc348..6dc9bd61 100644 --- a/ActualProjectCode/DjangoProject/core/admin.py +++ b/ActualProjectCode/DjangoProject/core/admin.py @@ -3,4 +3,18 @@ from core import models # Register your models here. -admin.site.register(models.user) \ No newline at end of file +from django.contrib import admin +from django.contrib.auth.models import User +from .models import Profile + +# Register the Profile model in the admin +admin.site.register(Profile) + +# Customize the User Admin to display profile fields +class UserAdmin(admin.ModelAdmin): + list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'is_active') + list_filter = ('is_staff', 'is_active') + search_fields = ('username', 'email') + +admin.site.unregister(User) # Unregister the default User model +admin.site.register(User, UserAdmin) # Re-register with customization diff --git a/ActualProjectCode/DjangoProject/core/forms.py b/ActualProjectCode/DjangoProject/core/forms.py new file mode 100644 index 00000000..68b9df47 --- /dev/null +++ b/ActualProjectCode/DjangoProject/core/forms.py @@ -0,0 +1,6 @@ +from django import forms +from django.contrib.auth.models import User + +class UserLoginForm(forms.Form): + username = forms.CharField(max_length=100) + password = forms.CharField(widget=forms.PasswordInput) diff --git a/ActualProjectCode/DjangoProject/core/models.py b/ActualProjectCode/DjangoProject/core/models.py index 6ec709cf..4e743ecd 100644 --- a/ActualProjectCode/DjangoProject/core/models.py +++ b/ActualProjectCode/DjangoProject/core/models.py @@ -1,14 +1,9 @@ -from platform import mac_ver - +from django.contrib.auth.models import User from django.db import models -# Create your models here. - -class user(models.Model): - userID = models.IntegerField(primary_key=True) - username = models.CharField(max_length=100) - password = models.CharField(max_length=100) - usertypes = models.CharField(max_length=100) +class Profile(models.Model): + user = models.OneToOneField(User, on_delete=models.CASCADE) + role = models.CharField(max_length=100, choices=[('admin', 'Admin'), ('user', 'User'), ('ai_engineer', 'AI Engineer'), ('finance', 'Finance Team')]) def __str__(self): - return self.username \ No newline at end of file + return f"{self.user.username} - {self.role}" \ No newline at end of file diff --git a/ActualProjectCode/DjangoProject/core/views.py b/ActualProjectCode/DjangoProject/core/views.py index 91ea44a2..9962f78e 100644 --- a/ActualProjectCode/DjangoProject/core/views.py +++ b/ActualProjectCode/DjangoProject/core/views.py @@ -1,3 +1,68 @@ -from django.shortcuts import render +from django.contrib.auth import authenticate, login, logout +from django.contrib.auth.forms import UserCreationForm +from django.shortcuts import render, redirect +from django.contrib.auth.decorators import login_required +from django.http import HttpResponse +from .models import Profile +from .forms import UserLoginForm -# Create your views here. + +# Registration view +def register_view(request): + if request.method == 'POST': + form = UserCreationForm(request.POST) + if form.is_valid(): + user = form.save() + # Create a profile for the user + role = request.POST.get('role', 'user') # Default to 'user' if not provided + Profile.objects.create(user=user, role=role) + return redirect('login') + else: + form = UserCreationForm() + return render(request, 'register.html', {'form': form}) + +# Login view +def login_view(request): + if request.method == 'POST': + form = UserLoginForm(request.POST) + if form.is_valid(): + username = form.cleaned_data['username'] + password = form.cleaned_data['password'] + user = authenticate(request, username=username, password=password) + if user is not None: + login(request, user) + # Get the profile and role + profile = user.profile + role = profile.role + # Redirect to the correct profile page based on the user's role + if role == 'ai_engineer': + return redirect('ai_engineer_dashboard') + elif role == 'finance': + return redirect('finance_dashboard') + else: + return redirect('user_dashboard') + else: + # Handle invalid login + return render(request, 'login.html', {'error': 'Invalid credentials'}) + else: + form = UserLoginForm() + return render(request, 'login.html', {'form': form}) + +def user_dashboard(request): + return render(request, 'profile.html') + + +def ai_engineer_dashboard(request): + return render(request, 'profile.html') + +def finance_dashboard(request): + return render(request, 'profile.html') + +def logout_view(request): + logout(request) + return redirect('home') # Replace 'home' with the URL name for your homepage + +# Profile view (only accessible if logged in) +@login_required +def profile_view(request): + return render(request, 'profile.html', {'user': request.user}) diff --git a/ActualProjectCode/DjangoProject/server/settings.py b/ActualProjectCode/DjangoProject/server/settings.py index 38c9d5e1..52b3245d 100644 --- a/ActualProjectCode/DjangoProject/server/settings.py +++ b/ActualProjectCode/DjangoProject/server/settings.py @@ -56,8 +56,7 @@ ROOT_URLCONF = 'server.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [BASE_DIR / 'templates'] - , + 'DIRS': [BASE_DIR / 'templates'], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ @@ -106,7 +105,6 @@ AUTH_PASSWORD_VALIDATORS = [ }, ] - # Internationalization # https://docs.djangoproject.com/en/5.1/topics/i18n/ diff --git a/ActualProjectCode/DjangoProject/server/urls.py b/ActualProjectCode/DjangoProject/server/urls.py index 13c75576..4ca26845 100644 --- a/ActualProjectCode/DjangoProject/server/urls.py +++ b/ActualProjectCode/DjangoProject/server/urls.py @@ -14,6 +14,7 @@ Including another URLconf 1. Import the include() function: from django.urls import include, path 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ +from django.contrib.auth.views import LogoutView # from django.contrib import admin from django.urls import path @@ -21,12 +22,19 @@ from django.contrib import admin from django.urls import path from django.urls import include from django.shortcuts import render +from core import views def home(request): return render(request, 'index.html') urlpatterns = [ - path('admin/', admin.site.urls), path('', home, name='home'), + path('admin/', admin.site.urls), + path('logout/', views.logout_view, name='logout'), + path('login/', views.login_view, name='login'), + path('register/', views.register_view, name='register'), + path('profile/', views.user_dashboard, name='user_dashboard'), + path('ai_engineer_dashboard/', views.ai_engineer_dashboard, name='ai_engineer_dashboard'), + path('finance_dashboard/', views.finance_dashboard, name='finance_dashboard'), ] \ No newline at end of file diff --git a/ActualProjectCode/DjangoProject/static/styles.css b/ActualProjectCode/DjangoProject/static/styles.css index 4c2e9910..8106da0f 100644 --- a/ActualProjectCode/DjangoProject/static/styles.css +++ b/ActualProjectCode/DjangoProject/static/styles.css @@ -1,127 +1,179 @@ -/* Global Styles */ +/* Reset some default styles */ * { - margin: 0; - padding: 0; - box-sizing: border-box; - font-family: Arial, sans-serif; + margin: 0; + padding: 0; + box-sizing: border-box; } body { - background-color: #f4f7fc; - color: #333; - font-size: 16px; - line-height: 1.6; - font-family: Arial, sans-serif; - margin: 0; - padding: 0; + font-family: Arial, sans-serif; + background-color: #f4f7f6; + color: #333; + padding: 20px; } -h1, h2, h3 { - font-weight: bold; +h1, h2 { + color: #2c3e50; + margin-bottom: 20px; } -.container { - width: 80%; - margin: 0 auto; - padding: 20px; +/* Navbar Styles */ +nav { + background-color: #2c3e50; + padding: 10px; + margin-bottom: 30px; + border-radius: 5px; } -header { - text-align: center; - margin-bottom: 40px; +nav ul { + list-style-type: none; + text-align: right; } -h1 { - color: #3498db; +nav ul li { + display: inline; + margin-left: 20px; } -#login-section, #dashboard-section { - max-width: 500px; - margin: 0 auto; - padding: 20px; - background-color: white; - border-radius: 8px; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); +nav ul li a { + color: #ecf0f1; + text-decoration: none; + font-weight: bold; } -#login-section h2, #dashboard-section h2 { - color: #2c3e50; - margin-bottom: 20px; +nav ul li a:hover { + text-decoration: underline; } -.input-group { - margin-bottom: 15px; +/* Form Styles */ +form { + background-color: #fff; + padding: 20px; + border-radius: 5px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + margin: 0 auto; + max-width: 400px; } -input[type="text"], input[type="password"] { - width: 100%; - padding: 10px; - border: 1px solid #ddd; - border-radius: 4px; - font-size: 16px; +input[type="text"], input[type="password"], input[type="email"], select { + width: 100%; + padding: 12px; + margin: 10px 0 20px 0; + border: 1px solid #ccc; + border-radius: 5px; + box-sizing: border-box; } button { - width: 100%; - padding: 12px; - border: none; - background-color: #3498db; - color: white; - font-size: 16px; - border-radius: 4px; - cursor: pointer; - margin-top: 10px; + background-color: #3498db; + color: white; + border: none; + padding: 15px 20px; + width: 100%; + border-radius: 5px; + cursor: pointer; + font-size: 16px; } button:hover { - background-color: #2980b9; + background-color: #2980b9; } -select { - padding: 5px; - font-size: 16px; +/* Error message */ +.error-message { + color: red; + margin-bottom: 20px; } -.hidden { - display: none; +/* Profile Page Styles */ +.profile-container { + max-width: 1000px; + margin: 0 auto; + padding: 20px; + background-color: white; + border-radius: 5px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); } -.user-type-selection button { - margin-top: 10px; - width: 48%; - display: inline-block; - background-color: #2ecc71; +.profile-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 20px; } -.user-type-selection button:hover { - background-color: #27ae60; +.profile-header h1 { + font-size: 28px; } -.dashboard { - margin-top: 20px; - text-align: center; +.profile-header a { + color: #3498db; + text-decoration: none; } -.dashboard button { - background-color: #e67e22; +.profile-header a:hover { + text-decoration: underline; } -#dashboard-section { - text-align: center; - padding-top: 50px; + +.profile-info { + margin-bottom: 30px; +} + +.profile-info p { + font-size: 18px; + margin: 10px 0; +} + +button.logout { + width: auto; + padding: 10px 20px; + margin-top: 20px; + background-color: #e74c3c; + color: white; + border: none; + border-radius: 5px; + cursor: pointer; } -.dashboard button:hover { - background-color: #d35400; + +button.logout:hover { + background-color: #c0392b; } -#role-name { - font-weight: bold; + +/* Dashboard specific */ +.dashboard-section { + padding: 20px; + background-color: #ecf0f1; + border-radius: 5px; + margin-bottom: 20px; } -#logout-btn { - background-color: red; - color: white; - border: none; - font-size: 16px; - cursor: pointer; + +.dashboard-section h2 { + font-size: 24px; + margin-bottom: 15px; } -#logout-btn:hover { - background-color: darkred; + +.dashboard-section p { + font-size: 16px; + line-height: 1.5; +} + +.dashboard-section .button-container { + display: flex; + justify-content: flex-start; + gap: 15px; +} + +.dashboard-section .button-container button { + width: auto; + padding: 10px 20px; + font-size: 16px; + background-color: #3498db; + color: white; + border: none; + border-radius: 5px; + cursor: pointer; +} + +.dashboard-section .button-container button:hover { + background-color: #2980b9; } diff --git a/ActualProjectCode/DjangoProject/templates/index.html b/ActualProjectCode/DjangoProject/templates/index.html index 3e1cdedd..5833b773 100644 --- a/ActualProjectCode/DjangoProject/templates/index.html +++ b/ActualProjectCode/DjangoProject/templates/index.html @@ -1,33 +1,21 @@ <!DOCTYPE html> -<html lang="en"> +<html> <head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>MLaaS - Machine Learning as a Service</title> + <title>ShallowSink - Home</title> {% load static %} - <link rel="stylesheet" type="text/css" href="{% static 'styles.css' %}"> + <link rel="stylesheet" href="{% static 'styles.css' %}"> </head> <body> - <!-- Login Section --> - <div id="login-section"> - <h2>Login</h2> - <label for="role">Select Role:</label> - <select id="role" name="role"> - <option value="end-user">End-User</option> - <option value="ai-engineer">AI Engineer</option> - <option value="administrator">Administrator</option> - <option value="finance-team">Finance Team</option> - </select><br><br> - <button id="login-btn">Login</button> - </div> - - <!-- Dashboard Section --> - <div id="dashboard-section" style="display:none;"> - <h1>Welcome <span id="role-name"></span></h1> - <div id="dashboard-content"></div> - <button id="logout-btn">Logout</button> - </div> - <script src="{% static 'scripts.js' %}"></script> + <nav> + <ul> + <li><a href="{% url 'login' %}">Login</a></li> + <li><a href="{% url 'register' %}">Register</a></li> + </ul> + </nav> + <h1>Welcome to ShallowSink</h1> + <p>Your trusted platform for making better tech decisions.</p> + {% block content %} + {% endblock %} </body> </html> diff --git a/ActualProjectCode/DjangoProject/templates/login.html b/ActualProjectCode/DjangoProject/templates/login.html new file mode 100644 index 00000000..f861568b --- /dev/null +++ b/ActualProjectCode/DjangoProject/templates/login.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html> +<head> + <title>Login</title> + {% load static %} + <link rel="stylesheet" href="{% static 'styles.css' %}"> +</head> +<body> + <h2>Login</h2> + <form method="post"> + {% csrf_token %} + <label for="id_username">Username:</label> + <input type="text" name="username" id="id_username" required><br> + + <label for="id_password">Password:</label> + <input type="password" name="password" id="id_password" required><br> + + <button type="submit">Login</button> + </form> + {% block content %} + {% endblock %} +</body> +</html> diff --git a/ActualProjectCode/DjangoProject/templates/profile.html b/ActualProjectCode/DjangoProject/templates/profile.html new file mode 100644 index 00000000..29f54320 --- /dev/null +++ b/ActualProjectCode/DjangoProject/templates/profile.html @@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> +<head> + <title>Profile</title> +</head> +<body> + <nav> + <ul> + <li><a href="{% url 'logout' %}">Logout</a></li> + </ul> + </nav> + <h1>Welcome, {{ user.username }}!</h1> + + {% if user.profile.role == 'ai_engineer' %} + <h2>AI Engineer Dashboard</h2> + <p>Access AI-related tools and data.</p> + {% elif user.profile.role == 'finance' %} + <h2>Finance Dashboard</h2> + <p>View financial reports and tools.</p> + {% else %} + <h2>User Dashboard</h2> + <p>Manage your tasks and profile.</p> + {% endif %} +</body> +</html> diff --git a/ActualProjectCode/DjangoProject/templates/register.html b/ActualProjectCode/DjangoProject/templates/register.html new file mode 100644 index 00000000..7b4fc342 --- /dev/null +++ b/ActualProjectCode/DjangoProject/templates/register.html @@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html> +<head> + <title>Register</title> +</head> +<body> + <h2>Register</h2> + <form method="post"> + {% csrf_token %} + {{ form.as_p }} + + <label for="id_role">Role:</label> + <select name="role" id="id_role" required> + <option value="user">User</option> + <option value="ai_engineer">AI Engineer</option> + <option value="finance">Finance Team</option> + </select> + + <button type="submit">Register</button> + </form> +</body> +</html> -- GitLab