diff --git a/postgresTest/PROJECT1/__pycache__/forms.cpython-311.pyc b/postgresTest/PROJECT1/__pycache__/forms.cpython-311.pyc index e43f987ffec4721365fff7387a20d7e579fcc1de..8ec5d4336fe99bbf4023b50e27d5a05d31a20302 100644 Binary files a/postgresTest/PROJECT1/__pycache__/forms.cpython-311.pyc and b/postgresTest/PROJECT1/__pycache__/forms.cpython-311.pyc differ diff --git a/postgresTest/PROJECT1/__pycache__/models.cpython-311.pyc b/postgresTest/PROJECT1/__pycache__/models.cpython-311.pyc index 2adcd25c545d82e61e2acce51c02a32f5d154f82..2198e6f579183f0d627e8ea744b59016fba39080 100644 Binary files a/postgresTest/PROJECT1/__pycache__/models.cpython-311.pyc and b/postgresTest/PROJECT1/__pycache__/models.cpython-311.pyc differ diff --git a/postgresTest/PROJECT1/__pycache__/views.cpython-311.pyc b/postgresTest/PROJECT1/__pycache__/views.cpython-311.pyc index c994f8664d23059ce276573f94aac5f6c7c4e9c5..2a4904c7dfe3350cf6b9330d4cfba15495488931 100644 Binary files a/postgresTest/PROJECT1/__pycache__/views.cpython-311.pyc and b/postgresTest/PROJECT1/__pycache__/views.cpython-311.pyc differ diff --git a/postgresTest/PROJECT1/forms.py b/postgresTest/PROJECT1/forms.py index 132bf80df73eee7d7a1d2836744b9b1848f6e881..fc1a406b4ba2178583e278ad6774626f67ae0597 100644 --- a/postgresTest/PROJECT1/forms.py +++ b/postgresTest/PROJECT1/forms.py @@ -1,12 +1,12 @@ from django import forms from django.contrib.auth.forms import UserCreationForm from django.contrib.auth import get_user_model -from .models import Contact, CustomUser +from .models import Contact, CustomUser, Employee +from django.core.validators import RegexValidator, EmailValidator import datetime - - +# RoleAssignmentForm for assigning roles class RoleAssignmentForm(forms.ModelForm): class Meta: model = CustomUser @@ -21,12 +21,20 @@ class RoleAssignmentForm(forms.ModelForm): } - +# CustomUserCreationForm for creating users with role and validation class CustomUserCreationForm(UserCreationForm): + email = forms.EmailField( + required=True, + widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Email'}), + validators=[EmailValidator(message="Enter a valid email address.")] + ) + class Meta(UserCreationForm.Meta): model = get_user_model() - fields = UserCreationForm.Meta.fields + fields = UserCreationForm.Meta.fields + ('email',) # Ensure email is included in the form + +# ContactForm with custom validation and widgets for collecting contact info class ContactForm(forms.ModelForm): class Meta: model = Contact @@ -38,18 +46,86 @@ class ContactForm(forms.ModelForm): 'message': forms.Textarea(attrs={'placeholder': 'Message', 'required': True, 'class': 'form-control message-box'}), } -from django import forms -from .models import Employee + # Additional validation for phone number to ensure proper format + def clean_phone(self): + phone = self.cleaned_data.get('phone') + phone_validator = RegexValidator( + regex=r'^\+?1?\d{9,15}$', + message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed." + ) + phone_validator(phone) + return phone + +# OnboardingForm with custom widgets and validation for employee onboarding class OnboardingForm(forms.ModelForm): + # Adding file fields for Police Report, ID card images (front and back), and CV + police_report = forms.FileField(required=True, label="Police Report") + id_card_front = forms.ImageField(required=True, label="ID Card (Front)") + id_card_back = forms.ImageField(required=True, label="ID Card (Back)") + cv = forms.FileField(required=True, label="CV (Resume)") + class Meta: model = Employee - fields = ['first_name', 'last_name', 'email', 'department', 'start_date', 'job_title'] + fields = [ + 'first_name', 'last_name', 'email', 'phone', 'address', + 'department', 'job_title', 'start_date', 'date_of_birth', + 'id_card_number', 'emergency_contact_name', 'emergency_contact_phone', + 'banking_information', 'police_report', 'id_card_front', 'id_card_back', 'cv' + ] widgets = { 'first_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'First Name'}), 'last_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Last Name'}), 'email': forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Email Address'}), + 'phone': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Phone Number'}), + 'address': forms.Textarea(attrs={'class': 'form-control', 'placeholder': 'Residential Address'}), 'department': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Department'}), - 'start_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}), 'job_title': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Job Title'}), + 'start_date': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}), + 'date_of_birth': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}), + 'id_card_number': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'ID Card Number'}), + 'emergency_contact_name': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Emergency Contact Name'}), + 'emergency_contact_phone': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Emergency Contact Phone'}), + 'banking_information': forms.Textarea(attrs={'class': 'form-control', 'placeholder': 'Banking Information (optional)'}), } + + # Additional validation for email + def clean_email(self): + email = self.cleaned_data.get('email') + email_validator = EmailValidator(message="Enter a valid email address.") + email_validator(email) + return email + + # Additional validation for start date + def clean_start_date(self): + start_date = self.cleaned_data.get('start_date') + if start_date > datetime.date.today(): + raise forms.ValidationError("Start date cannot be in the future.") + return start_date + + # Additional validation for date of birth + def clean_date_of_birth(self): + date_of_birth = self.cleaned_data.get('date_of_birth') + if date_of_birth >= datetime.date.today(): + raise forms.ValidationError("Date of birth must be in the past.") + return date_of_birth + + # Validation for phone number + def clean_phone(self): + phone = self.cleaned_data.get('phone') + phone_validator = RegexValidator( + regex=r'^\+?1?\d{9,15}$', + message="Enter a valid phone number in the format: '+999999999'. Up to 15 digits allowed." + ) + phone_validator(phone) + return phone + + # Validation for emergency contact phone number + def clean_emergency_contact_phone(self): + emergency_contact_phone = self.cleaned_data.get('emergency_contact_phone') + phone_validator = RegexValidator( + regex=r'^\+?1?\d{9,15}$', + message="Enter a valid emergency contact phone number in the format: '+999999999'. Up to 15 digits allowed." + ) + phone_validator(emergency_contact_phone) + return emergency_contact_phone diff --git a/postgresTest/PROJECT1/migrations/0022_rename_price_job_salary_employee_id_card_number_and_more.py b/postgresTest/PROJECT1/migrations/0022_rename_price_job_salary_employee_id_card_number_and_more.py new file mode 100644 index 0000000000000000000000000000000000000000..f216b97d4db6fc5f07160ffbfff83e83930dca01 --- /dev/null +++ b/postgresTest/PROJECT1/migrations/0022_rename_price_job_salary_employee_id_card_number_and_more.py @@ -0,0 +1,40 @@ +# Generated by Django 5.0.6 on 2024-10-09 09:54 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('PROJECT1', '0021_employee_delete_account_remove_cartitem_job_and_more'), + ] + + operations = [ + migrations.RenameField( + model_name='job', + old_name='price', + new_name='salary', + ), + migrations.AddField( + model_name='employee', + name='id_card_number', + field=models.CharField(default=12345, max_length=20, validators=[django.core.validators.RegexValidator(message='Enter a valid ID card number.', regex='^\\d{5,20}$')]), + preserve_default=False, + ), + migrations.AlterField( + model_name='contact', + name='email', + field=models.EmailField(max_length=254, validators=[django.core.validators.EmailValidator()]), + ), + migrations.AlterField( + model_name='contact', + name='phone', + field=models.CharField(max_length=15, validators=[django.core.validators.RegexValidator(message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.", regex='^\\+?1?\\d{9,15}$')]), + ), + migrations.AlterField( + model_name='employee', + name='email', + field=models.EmailField(max_length=254, unique=True, validators=[django.core.validators.EmailValidator()]), + ), + ] diff --git a/postgresTest/PROJECT1/migrations/__pycache__/0022_rename_price_job_salary_employee_id_card_number_and_more.cpython-311.pyc b/postgresTest/PROJECT1/migrations/__pycache__/0022_rename_price_job_salary_employee_id_card_number_and_more.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f9e77b4991a5da18652fabc6ef189bc350d0d0e5 Binary files /dev/null and b/postgresTest/PROJECT1/migrations/__pycache__/0022_rename_price_job_salary_employee_id_card_number_and_more.cpython-311.pyc differ diff --git a/postgresTest/PROJECT1/models.py b/postgresTest/PROJECT1/models.py index e47e624ad8bc21478ea77ab9f5efe947dde80803..bc825fb79d4755f887810cb39781d0a21a612241 100644 --- a/postgresTest/PROJECT1/models.py +++ b/postgresTest/PROJECT1/models.py @@ -1,19 +1,46 @@ -from django.conf import settings from django.db import models from django.contrib.auth.models import AbstractUser +from django.core.validators import EmailValidator, RegexValidator class Employee(models.Model): first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100) - email = models.EmailField(unique=True) + email = models.EmailField(unique=True, validators=[EmailValidator()]) + phone = models.CharField( + max_length=15, + validators=[ + RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.") + ] + ) + address = models.TextField() # Residential address department = models.CharField(max_length=100) - start_date = models.DateField() job_title = models.CharField(max_length=100) + start_date = models.DateField() + date_of_birth = models.DateField() + id_card_number = models.CharField( + max_length=20, + validators=[RegexValidator(regex=r'^\d{5,20}$', message='Enter a valid ID card number.')] + ) + emergency_contact_name = models.CharField(max_length=100) + emergency_contact_phone = models.CharField( + max_length=15, + validators=[ + RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Emergency contact phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.") + ] + ) + banking_information = models.TextField(blank=True, null=True) # Optional for salary deposits + + # New file upload fields + police_report = models.FileField(upload_to='documents/police_reports/', blank=True, null=True) + id_card_front = models.ImageField(upload_to='documents/id_cards/', blank=True, null=True) + id_card_back = models.ImageField(upload_to='documents/id_cards/', blank=True, null=True) + cv = models.FileField(upload_to='documents/cv/', blank=True, null=True) def __str__(self): return f"{self.first_name} {self.last_name} - {self.department}" - + + # The CustomUser model class CustomUser(AbstractUser): ROLE_CHOICES = ( @@ -24,22 +51,29 @@ class CustomUser(AbstractUser): ) role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='EMPLOYEE') -# The Job model + +# The Job model (with 'salary' field) class Job(models.Model): name = models.CharField(max_length=100) - img = models.ImageField(upload_to='pics', blank=True, null=True) # Optional if needed + img = models.ImageField(upload_to='pics', blank=True, null=True) desc = models.TextField() - price = models.IntegerField(blank=True, null=True) # Optional if needed + salary = models.IntegerField(blank=True, null=True) form_url = models.URLField(blank=True, null=True) def __str__(self): return self.name + # The Contact model class Contact(models.Model): name = models.CharField(max_length=100) - phone = models.CharField(max_length=15) - email = models.EmailField() + phone = models.CharField( + max_length=15, + validators=[ + RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.") + ] + ) + email = models.EmailField(validators=[EmailValidator()]) message = models.TextField() created_at = models.DateTimeField(auto_now_add=True) diff --git a/postgresTest/PROJECT1/templates/base.html b/postgresTest/PROJECT1/templates/base.html index 5aaeaf25b8d8e53b58f7ff47af10276e19413084..08784b217cec7cd2a52a7c76367888bf1453f257 100644 --- a/postgresTest/PROJECT1/templates/base.html +++ b/postgresTest/PROJECT1/templates/base.html @@ -14,7 +14,7 @@ <link rel="icon" href="{% static 'images/fevicon/fevicon.png' %}" type="image/gif" /> <!-- Title --> - <title>{% block title %}HR System{% endblock title %}</title> + <title>{% block title %}HR System Onboarding{% endblock %}</title> <!-- Stylesheets --> <link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.css' %}" /> @@ -22,7 +22,6 @@ <link href="{% static 'css/font-awesome.min.css' %}" rel="stylesheet" /> <link href="{% static 'css/style.css' %}" rel="stylesheet" /> <link href="{% static 'css/responsive.css' %}" rel="stylesheet" /> - <link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.10.2/fullcalendar.min.css" rel="stylesheet" /> <style> /* Custom CSS for the toggling effect */ @@ -49,7 +48,9 @@ margin-left: 250px; width: calc(100% - 250px); transition: all 0.3s; - padding-top: 20px; + padding: 20px; + background-color: #f7f7f7; + min-height: 100vh; } .toggled .sidebar-wrapper { @@ -76,6 +77,44 @@ margin-right: 10px; } + /* Onboarding-specific styles */ + .onboarding-header { + font-size: 28px; + font-weight: 700; + color: #333; + text-align: center; + margin-bottom: 20px; + } + + .onboarding-step { + background-color: #fff; + padding: 15px; + border-radius: 8px; + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1); + margin-bottom: 20px; + } + + .onboarding-step h4 { + font-size: 22px; + color: #007bff; + } + + .onboarding-step p { + font-size: 16px; + color: #555; + } + + .btn-next { + display: block; + width: 100%; + text-align: center; + background-color: #007bff; + color: white; + padding: 10px; + border-radius: 5px; + margin-top: 20px; + } + /* Custom CSS for the login icon in the top right corner */ .login-icon { position: absolute; @@ -93,7 +132,7 @@ <div class="container-fluid"> <nav class="navbar navbar-expand-lg custom_nav-container"> <a class="navbar-brand" href="{% url 'home' %}"> - <span>HR System</span> + <span>HR Onboarding</span> </a> <!-- Login Icon in the top right corner --> <a href="{% url 'login' %}" class="login-icon"> @@ -111,69 +150,65 @@ <a href="{% url 'dashboard' %}" class="list-group-item list-group-item-action bg-light"> <i class="fa fa-tachometer" aria-hidden="true"></i> Dashboard </a> - <a href="{% url 'redirect_to_current_month' %}" class="list-group-item list-group-item-action bg-light"> - <i class="fa fa-calendar" aria-hidden="true"></i> Calendar - </a> - <a href="{% url 'job' %}" class="list-group-item list-group-item-action bg-light"> - <i class="fa fa-briefcase" aria-hidden="true"></i> Jobs + + <!-- Links specifically for onboarding --> + <a href="{% url 'onboard_employee' %}" class="list-group-item list-group-item-action bg-light"> + <i class="fa fa-user-plus" aria-hidden="true"></i> Onboard Employee </a> - <a href="{% url 'leave' %}" class="list-group-item list-group-item-action bg-light"> - <i class="fa fa-plane" aria-hidden="true"></i> Leave + + <a href="{% url 'employee_list' %}" class="list-group-item list-group-item-action bg-light"> + <i class="fa fa-users" aria-hidden="true"></i> View Employees </a> - - <!-- Add this for admin/HR users --> - {% if request.user.is_staff %} - <a href="{% url 'all_leave_forms' %}" class="list-group-item list-group-item-action bg-light"> - <i class="fa fa-file-alt" aria-hidden="true"></i> All Leave Forms - </a> - {% endif %} - - <a href="{% url 'meeting_list' %}" class="list-group-item list-group-item-action bg-light"> - <i class="fa fa-calendar-check-o" aria-hidden="true"></i> Scheduled Meetings - </a> - + + <!-- Removed the Meetings link --> + <a href="#" class="list-group-item list-group-item-action bg-light"> <i class="fa fa-cogs" aria-hidden="true"></i> Settings </a> + <a href="#" class="list-group-item list-group-item-action bg-light"> <i class="fa fa-file-text" aria-hidden="true"></i> Reports </a> - <a href="{% url 'inventory' %}" class="list-group-item list-group-item-action bg-light"> - <i class="fa fa-archive" aria-hidden="true"></i> Inventory - </a> - <a href="{% url 'employee' %}" class="list-group-item list-group-item-action bg-light"> - <i class="fa fa-user" aria-hidden="true"></i> Employee - </a> </div> -</div> + </div> + - <div class="page-content-wrapper" id="page-content-wrapper"> + <!-- Main content area --> + <div class="page-content-wrapper" id="page-content-wrapper"> <i class="fa fa-bars toggle-icon" id="menu-toggle"></i> <div class="container-fluid"> - {% block content %} - <!-- Your content goes here --> - {% endblock content %} + <div class="onboarding-header"> + <!-- Remove this second block title --> + <h1>Welcome to HR Onboarding</h1> + </div> + + <div class="onboarding-content"> + {% block content %} + <!-- Content such as onboarding steps, forms, etc. will be injected here --> + <div class="onboarding-step"> + <h4>Step 1: Complete Your Profile</h4> + <p>Please provide all the necessary personal information to complete your profile.</p> + </div> + + <div class="onboarding-step"> + <h4>Step 2: Review Company Policies</h4> + <p>Make sure to go through the company policies to understand our code of conduct.</p> + </div> + + <a href="#" class="btn-next">Proceed to the Next Step</a> + {% endblock content %} + </div> </div> - </div> </div> <!-- jQuery --> <script type="text/javascript" src="{% static 'js/jquery-3.4.1.min.js' %}"></script> <!-- popper js --> - <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script> + <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script> <!-- bootstrap js --> <script type="text/javascript" src="{% static 'js/bootstrap.js' %}"></script> <!-- custom js --> <script type="text/javascript" src="{% static 'js/custom.js' %}"></script> - <!-- fullcalendar js --> - <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script> - <script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.10.2/fullcalendar.min.js"></script> - <!-- Google Platform API --> -<script src="https://apis.google.com/js/platform.js" async defer></script> - -<!-- Your Custom JS --> -<script type="text/javascript" src="{% static 'js/custom.js' %}"></script> - <script> // Toggle sidebar @@ -181,13 +216,6 @@ e.preventDefault(); $("#sidebar-wrapper").toggleClass("collapsed"); }); - - // Initialize calendar - $(document).ready(function() { - $('#calendar').fullCalendar({ - // Add your calendar options here - }); - }); </script> </body> </html> diff --git a/postgresTest/PROJECT1/templates/index.html b/postgresTest/PROJECT1/templates/index.html index bf52bca95b58454a826bbc9c25a0a5ae322aa9fa..670681bde631463cde65e825d86113e06230d040 100644 --- a/postgresTest/PROJECT1/templates/index.html +++ b/postgresTest/PROJECT1/templates/index.html @@ -3,7 +3,7 @@ {% load static %} {% block content %} -<!-- Carousel section --> +<!-- Carousel Section (highlighting onboarding-specific content) --> <section class="slider_section"> <div id="customCarousel1" class="carousel slide" data-ride="carousel"> <div class="carousel-inner"> @@ -12,9 +12,9 @@ <div class="carousel-item active"> <img src="{% static 'images/banner1.png' %}" alt="Admin Positions" class="d-block w-100"> <div class="carousel-caption d-none d-md-block"> - <h5 class="text-dark-gray">Admin Positions</h5> - <p class="text-dark-gray">Get a 50% discount on all self-sales.</p> - <a href="{% url 'job' %}" class="btn btn-primary"style="background-color: #333; border-color: #333;">Apply Now</a> + <h5 class="text-dark-gray">Admin Positions Available</h5> + <p class="text-dark-gray">Join the HR admin team and get exclusive career perks.</p> + <a href="#" class="btn btn-primary" style="background-color: #007bff; border-color: #007bff;">Apply Now</a> </div> </div> @@ -22,19 +22,19 @@ <div class="carousel-item"> <img src="{% static 'images/banner2.png' %}" alt="Procurement Officer" class="d-block w-100"> <div class="carousel-caption d-none d-md-block"> - <h5 class="text-dark-gray">First-class Procurement Officer</h5> - <p class="text-dark-gray">Get a 10% pay increase now!</p> - <a href="{% url 'job' %}" class="btn btn-primary"style="background-color: #333; border-color: #333;">Apply Now</a> + <h5 class="text-dark-gray">Procurement Officer Roles</h5> + <p class="text-dark-gray">Looking for experienced procurement officers with leadership potential.</p> + <a href="#" class="btn btn-primary" style="background-color: #007bff; border-color: #007bff;">Apply Now</a> </div> </div> <!-- Slide 3: Product Tester --> <div class="carousel-item"> - <img src="{% static 'images/banne3.png' %}" alt="Product Tester" class="d-block w-100"> + <img src="{% static 'images/banner3.png' %}" alt="Product Tester" class="d-block w-100"> <div class="carousel-caption d-none d-md-block"> - <h5 class="text-dark-gray">Product Tester</h5> - <p class="text-dark-gray">Mentorship positions available.</p> - <a href="{% url 'job' %}" class="btn btn-primary"style="background-color: #333; border-color: #333;">Apply Now</a> + <h5 class="text-dark-gray">Become a Product Tester</h5> + <p class="text-dark-gray">Get hands-on with our latest products as part of the product testing team.</p> + <a href="#" class="btn btn-primary" style="background-color: #007bff; border-color: #007bff;">Apply Now</a> </div> </div> @@ -60,19 +60,20 @@ </section> <!-- End Carousel Section --> -<!-- Soapbox Section --> +<!-- Contact Section (Soapbox Form for Feedback) --> <section class="contact_section layout_padding"> <div class="container"> - <!-- Soapbox Heading --> + <!-- Heading for the Soapbox Form --> <div class="heading_container"> - <h2>Soapbox Us</h2> + <h2>Get in Touch with Us</h2> + <p>We're here to assist you. Drop us your questions or feedback.</p> </div> <!-- Soapbox Form Row --> <div class="row"> <div class="col-md-6"> <div class="form_container"> - <form method="post" action="{% url 'contact' %}"> + <form method="post" action="#"> {% csrf_token %} {% for field in form %} <div class="form-group"> @@ -89,13 +90,28 @@ </div> {% endfor %} <div class="btn_box"> - <button type="submit" class="btn btn-primary" style="background-color: #333; border-color: #333;">SEND</button> + <button type="submit" class="btn btn-primary" style="background-color: #007bff; border-color: #007bff;">Submit</button> </div> </form> </div> </div> + + <!-- Adding a right-side section for onboarding --> + <div class="col-md-6"> + <div class="onboarding-info"> + <h4>How We Can Help</h4> + <p>Our onboarding process is designed to be smooth and efficient, allowing you to get started with minimal hassle.</p> + <ul> + <li>Dedicated HR Support</li> + <li>Step-by-step onboarding guide</li> + <li>24/7 assistance for all inquiries</li> + </ul> + <a href="#" class="btn btn-outline-primary" style="margin-top: 20px;">Learn More</a> + </div> + </div> </div> </div> </section> +<!-- End Contact Section --> {% endblock content %} diff --git a/postgresTest/PROJECT1/templates/onboard_employee.html b/postgresTest/PROJECT1/templates/onboard_employee.html index 1921e8c798b5b6f9d5de31a7d7c0340ce33a708c..cd7779ce4e272134d3da4fe458e40b6d023dd4a2 100644 --- a/postgresTest/PROJECT1/templates/onboard_employee.html +++ b/postgresTest/PROJECT1/templates/onboard_employee.html @@ -9,9 +9,96 @@ Onboard New Employee {% block content %} <h1>Onboard New Employee</h1> -<form method="POST"> +<!-- Make sure to add enctype for file uploads --> +<form method="POST" enctype="multipart/form-data"> {% csrf_token %} - {{ form.as_p }} <!-- This renders all form fields as paragraphs --> + + <div class="form-group"> + {{ form.first_name.label_tag }} + {{ form.first_name }} + </div> + + <div class="form-group"> + {{ form.last_name.label_tag }} + {{ form.last_name }} + </div> + + <div class="form-group"> + {{ form.email.label_tag }} + {{ form.email }} + </div> + + <div class="form-group"> + {{ form.phone.label_tag }} + {{ form.phone }} + </div> + + <div class="form-group"> + {{ form.address.label_tag }} + {{ form.address }} + </div> + + <div class="form-group"> + {{ form.department.label_tag }} + {{ form.department }} + </div> + + <div class="form-group"> + {{ form.job_title.label_tag }} + {{ form.job_title }} + </div> + + <div class="form-group"> + {{ form.start_date.label_tag }} + {{ form.start_date }} + </div> + + <div class="form-group"> + {{ form.date_of_birth.label_tag }} + {{ form.date_of_birth }} + </div> + + <div class="form-group"> + {{ form.id_card_number.label_tag }} + {{ form.id_card_number }} + </div> + + <div class="form-group"> + {{ form.emergency_contact_name.label_tag }} + {{ form.emergency_contact_name }} + </div> + + <div class="form-group"> + {{ form.emergency_contact_phone.label_tag }} + {{ form.emergency_contact_phone }} + </div> + + <div class="form-group"> + {{ form.banking_information.label_tag }} + {{ form.banking_information }} + </div> + + <!-- File uploads for Police Report, ID card images (front and back), and CV --> + <div class="form-group"> + {{ form.police_report.label_tag }} + {{ form.police_report }} + </div> + + <div class="form-group"> + {{ form.id_card_front.label_tag }} + {{ form.id_card_front }} + </div> + + <div class="form-group"> + {{ form.id_card_back.label_tag }} + {{ form.id_card_back }} + </div> + + <div class="form-group"> + {{ form.cv.label_tag }} + {{ form.cv }} + </div> + <button type="submit" class="btn btn-primary">Submit</button> </form> <!-- End of Onboard New Employee Section --> diff --git a/postgresTest/PROJECT1/views.py b/postgresTest/PROJECT1/views.py index 0cbc0ebfa5d8eb69c17356204e1afbdd1a4bc299..7581dcbc3706c148356634d1656300a68356a434 100644 --- a/postgresTest/PROJECT1/views.py +++ b/postgresTest/PROJECT1/views.py @@ -6,22 +6,36 @@ from .models import Job, CustomUser from .forms import CustomUserCreationForm, ContactForm, RoleAssignmentForm, OnboardingForm from django.contrib.auth.views import LoginView from django.contrib.auth.forms import UserChangeForm +from django.http import HttpResponseForbidden @login_required def dashboard(request): return render(request, 'dashboard.html') + @login_required def onboard_employee(request): - if request.method == 'POST': # This handles the form submission + # Ensure only staff can onboard employees + if not request.user.is_staff: + return HttpResponseForbidden("You don't have permission to onboard employees.") + + if request.method == 'POST': form = OnboardingForm(request.POST) + if form.is_valid(): - form.save() # This saves the form data to the database (Employee model) + employee = form.save() + + # Example: Logging action without exposing sensitive information + print(f"New employee onboarded: {employee.first_name} {employee.last_name}") + messages.success(request, 'Employee has been successfully onboarded.') return redirect('onboarding_success') + else: + messages.error(request, 'Please correct the errors below.') else: - form = OnboardingForm() # This displays an empty form for a GET request + form = OnboardingForm() + return render(request, 'onboard_employee.html', {'form': form}) @@ -32,14 +46,23 @@ def onboarding_success(request): @login_required def edit_role(request, user_id): + # Ensure only staff can edit roles user = get_object_or_404(CustomUser, pk=user_id) + + if not request.user.is_staff: + return HttpResponseForbidden("You don't have permission to edit roles.") + if request.method == 'POST': form = RoleAssignmentForm(request.POST, instance=user) if form.is_valid(): form.save() + messages.success(request, 'Role has been successfully updated.') return redirect('employee_list') # or the appropriate URL name + else: + messages.error(request, 'Please correct the errors below.') else: form = RoleAssignmentForm(instance=user) + return render(request, 'edit_role.html', {'form': form, 'user': user}) @@ -49,6 +72,10 @@ class CustomLoginView(LoginView): @login_required def employee_list(request): + # Staff members can view the employee list + if not request.user.is_staff: + return HttpResponseForbidden("You don't have permission to view this page.") + employees = CustomUser.objects.all().order_by('role') return render(request, 'employee.html', {'employees': employees}) @@ -64,6 +91,7 @@ def profile_edit_view(request): form = UserChangeForm(request.POST, instance=request.user) if form.is_valid(): form.save() + messages.success(request, 'Your profile has been updated.') return redirect('profile') else: form = UserChangeForm(instance=request.user) @@ -79,9 +107,10 @@ def register(request): form = CustomUserCreationForm(request.POST) if form.is_valid(): user = form.save() - username = form.cleaned_data.get('username') - messages.success(request, f'Account created for {username}!') + messages.success(request, f'Account created successfully!') return redirect('custom_login') + else: + messages.error(request, 'Please correct the errors below.') else: form = CustomUserCreationForm() return render(request, 'register.html', {'form': form}) @@ -99,17 +128,22 @@ def delete_account(request): request.user.delete() auth_logout(request) messages.success(request, 'Your account has been successfully deleted.') - return redirect('login') + return redirect('custom_login') def home(request): jobs = Job.objects.all() form = ContactForm() - context = { - 'jobs': jobs, - 'form': form, - } - return render(request, 'index.html', context) + + if request.method == 'POST': + form = ContactForm(request.POST) + if form.is_valid(): + form.save() + messages.success(request, 'Your message has been sent.') + else: + messages.error(request, 'Please correct the errors below.') + + return render(request, 'index.html', {'jobs': jobs, 'form': form}) def jobs(request): diff --git a/postgresTest/postgresTest/__pycache__/settings.cpython-311.pyc b/postgresTest/postgresTest/__pycache__/settings.cpython-311.pyc index 4b06af23f9a702b123867653db896b8bb70f8261..97d8a260ce94ce031ef32511349472b221183146 100644 Binary files a/postgresTest/postgresTest/__pycache__/settings.cpython-311.pyc and b/postgresTest/postgresTest/__pycache__/settings.cpython-311.pyc differ diff --git a/postgresTest/postgresTest/settings.py b/postgresTest/postgresTest/settings.py index fafc284e9888e56cfe9ae572e8cb84d635fe476d..a0ec1b636e66410b1f685d16f1e927328559c044 100644 --- a/postgresTest/postgresTest/settings.py +++ b/postgresTest/postgresTest/settings.py @@ -43,12 +43,13 @@ INSTALLED_APPS = [ "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", - 'PROJECT1.apps.Project1Config', # reg i - 'django.contrib.sites', # Added for allauth - 'allauth', # Added for allauth - 'allauth.account', # Added for allauth - 'allauth.socialaccount', # Added for allauth - 'allauth.socialaccount.providers.google', # Added for Google Sign-In + 'PROJECT1.apps.Project1Config', + 'django.contrib.sites', + 'allauth', + 'allauth.account', + 'allauth.socialaccount', + 'allauth.socialaccount.providers.google', + 'django_cryptography' ] # Authentication backends