Portfolio project for managing employees, shifts, holidays, skills and reporting, built as part of a Full Stack Software Development Diploma.
Design and create a labour management tool to demonstrate an increasing understanding of the libraries, frameworks, and deployment solutions available to developers.
My three main objectives were:
I wanted managers to navigate easily between employees, shifts, skills, and holidays. Django templates and Bootstrap 5 were used for styling and layout.
The backend framework enables secure authentication, full CRUD operations for employees, skills, and holiday requests, and lays the groundwork for future shift scheduling and reporting features. Django’s ORM, django-allauth, and django-crispy-forms power these workflows.
I integrated PostgreSQL from Code Institute database to manage employee data, skillsets and store Holiday data.
Target Audience
- Managers and team leads responsible for staff oversight.
- HR administrators tracking skills, holidays, and resource available.
- Small business owners seeking a simple way to view and manage employee data.
User Stories
- Understand core functionality
Quickly see that the tool lets them view employees, their roles, skills and holiday status. - Learn how to get started
Find the login process, as this contains sensitive data, this would be tailor made for each business. - Explore navigation
Discover where to click to view Employees, Skills, Holidays and (future) Shift Scheduling & Reports.
- Log in and out securely
Enter their credentials and access the firms dashboard. - View employee directory
Browse all staff members, see their roles, assigned shifts and areas of work. - Check skills inventory
Search or filter employees by skill to find the right person for the job. - Monitor holiday requests
See pending, approved and upcoming time-off grouped by area of work. - (Future) Manage shifts & generate reports
Assign or adjust shifts and pull utilization reports once those features are released.
- Backgrounds: Light gray (#f8f9fa) for a neutral, low-fatigue backdrop
- Text: Dark gray (#212529) for high readability
- Primary Accent: Bright blue (#0d6efd) on buttons and links to draw attention
- Status Indicators:
- Success – green (#198754)
- Warning – orange (#fd7e14)
- Error – red (#dc3545)
This neutral palette keeps the interface clean and consistent, with accents guiding the user toward interactive elements.
- Base font:
font-family: Arial, sans-serif;
A widely supported, easy-to-read system font that ensures consistency across devices. - Hierarchy:
- Headings use larger weights of Arial for clear section separation
- Body text remains standard weight for optimal legibility
- Favicon: 🧑💼 (Office worker emoji)
Chosen as a simple, universally recognizable icon to represent staff management and the core purpose of the tool.
Below is an outline of the main tables, their columns, data types, constraints, and relationships based on your models.py definitions.
| Column | Type | Constraints |
|---|---|---|
id |
AutoField |
Primary key |
full_name |
VARCHAR(100) |
Unique, NOT NULL |
gpid |
VARCHAR(20) |
Unique, NOT NULL |
shift |
VARCHAR(10) |
Choices: Green, Blue, Red, Yellow; Default: Green |
role |
VARCHAR(3) |
Choices: GSO, GO, MT, ST; Default: GSO; NOT NULL |
line |
VARCHAR(10) |
Choices: 1, 2, 3, 4, MOH, ALL; Default: 1; NOT NULL |
area_id |
INTEGER |
FK → skills_area(id), on_delete=PROTECT; NOT NULL |
active |
BOOLEAN |
Default: True |
Relationships:
- Many Employee rows relate to one Area row (
area_idFK).
| Column | Type | Constraints |
|---|---|---|
id |
AutoField |
Primary key |
name |
VARCHAR(100) |
Unique, NOT NULL |
| Column | Type | Constraints |
|---|---|---|
id |
AutoField |
Primary key |
name |
VARCHAR(100) |
Unique, NOT NULL |
| Column | Type | Constraints |
|---|---|---|
id |
AutoField |
Primary key |
employee_id |
INTEGER |
OneToOne FK → employees_employee(id), on_delete=CASCADE; NOT NULL |
primary_skill_id |
INTEGER |
FK → skills_skillmaster(id), on_delete=PROTECT; NOT NULL |
secondary_skill_id |
INTEGER |
FK → skills_skillmaster(id), on_delete=PROTECT; NULLABLE |
tertiary_skill_id |
INTEGER |
FK → skills_skillmaster(id), on_delete=PROTECT; NULLABLE |
Relationships:
- Each EmployeeSkill row is a 1–1 profile for an Employee.
- Skills in SkillMaster can appear as primary, secondary, or tertiary in many profiles.
| Column | Type | Constraints |
|---|---|---|
id |
AutoField |
Primary key |
employee_id |
INTEGER |
FK → employees_employee(id), on_delete=CASCADE; NOT NULL |
start_date |
DATE |
NOT NULL |
end_date |
DATE |
NOT NULL |
status |
VARCHAR(10) |
Choices: Pending, Approved, Rejected; Default: Pending; NOT NULL |
requested_at |
DATETIME |
auto_now_add=True |
reviewed_at |
DATETIME |
NULLABLE |
Relationships:
- Each HolidayRequest belongs to one Employee.
Only users that have been given strict access are able to log on to this webpage. This is due to it containing confidential information.
Perform full CRUD on employee records:
- Create new profiles with name, GPID, role, line and area
- Read the employee directory, filterable by role or line
- Update details such as active status or role
- Delete profiles when staff leave
Maintain and assign skill sets for each employee:
- Define master skills
- Attach primary, secondary, tertiary skills to an employee
- Search/filter employees by skill
Managers can submit time-off requests on behalf of employees; managers can then approve or reject based of discretion:
- View list of pending, approved, and rejected requests
- See requests grouped by area of work
- Shift Scheduling – drag-and-drop roster management with AI features to auto assign.
- Reporting – exportable CSV/PDF summaries of utilisation, skills coverage, holidays
- Role-Based Permissions – more granular access controls for HR vs. line managers
- Bulk Import/Export of employee data
- Email Notifications for request status changes
- Mobile-First Layout (responsive design is basic for now as the use will predomminatly be on desktop)
Here are the tools and services used to build and deploy this project:
- GitHub: code hosting and version control.
- Heroku: platform for deploying the application via a
Procfile. - PostgreSQL from Code Institute: external PostgreSQL database hosting (configured via
DATABASE_URL). - sqlparse: used for formatting SQL queries and migrations.
- Python 3
- Django 4.2.7
- django-allauth for authentication
- django-crispy-forms, crispy-bootstrap5, django-widget-tweaks, django-summernote for form rendering and rich-text editing
- Bootstrap 5, HTML5, CSS3, JavaScript
- dj-database-url, psycopg2-binary for database configuration & PostgreSQL driver
- Gunicorn, WhiteNoise for the WSGI server and static file serving
- PyJWT, oauthlib, requests-oauthlib, python3-openid for OAuth and JWT support
- asgiref, urllib3 as core dependencies
This project was designed using Agile methodology, utilising the Project Board and Issues sections in GitHub. GitHub Project Board
All tests were performed from the Manager perspective, using desktop, tablet, and mobile browsers. Any issues were fixed before moving on to the next feature.
| TEST | OUTCOME | PASS/FAIL |
|---|---|---|
| Manager Login | Successfully authenticated and redirected to Dashboard | Pass |
| View Employee Directory | Employee list displays names, roles, shifts, lines, and areas | Pass |
| Create Employee | New employee created and appears correctly in the directory | Pass |
| Edit Employee | Employee details (role, line, area, active status) updated | Pass |
| Delete Employee | Employee removed and no longer listed | Pass |
| Page Navigation: Employee → Skills | Clicking “Skills” on an employee loads that employee’s skill profile | Pass |
| Data Flow: Employee → Skills | Primary/secondary/tertiary skills saved for the selected employee | Pass |
| Define Skill Master Entry | New skill added to master list | Pass |
| Assign Skills to Employee | Primary/secondary/tertiary skills correctly saved | Pass |
| Edit Employee Skill Profile | Updated skill assignments saved | Pass |
| Delete Employee Skill Profile | Employee skill profile removed | Pass |
| Page Navigation: Employee → Holidays | Clicking “Holidays” on an employee loads that employee’s holiday list | Pass |
| Data Flow: Employee → Holidays | All holiday requests for the selected employee display correctly | Pass |
| View Holiday Requests | Pending, Approved, and Rejected requests display by area | Pass |
| Approve Holiday Request | Status changes to “Approved” and moves to the approved list | Pass |
| Decline Holiday Request | Status changes to “Rejected” and moves to the rejected list | Pass |
| (Future) Configure Shifts | Placeholder—feature in planning stage | N/A |
| (Future) Generate Reports | Placeholder—feature in planning stage | N/A |
-
Holiday Date Validation
- Issue: Requests where end date precedes start date were accepted without error.
- Fix: Added server-side validation to ensure
end_date >= start_date.
-
Duplicate GPID Constraint
- Issue: Integrity error when creating an employee with an existing GPID.
- Fix: Client-side form check and user-friendly error message on duplicate GPIDs.
-
Style Overrides
- Issue: Custom CSS was overridden by Bootstrap defaults after layout changes.
- Fix: Scoped override rules and increased specificity to preserve custom styles.
-
Employee Names
- Issue: Long or hyphenated employee names overflowed the table layout and caused misalignment.
- Fix: Added CSS (
word-wrap: break-word; max-width: 200px;) to table cells to contain names neatly.
-
Heroku Static Files
- Issue: CSS assets were not served on Heroku, resulting in a broken layout.
- Fix: Configured WhiteNoise in
settings.pyand ranpython manage.py collectstaticduring deployment.
-
Environment Variables & Allowed Hosts
- Issue:
DEBUG=Falsewithout properALLOWED_HOSTSconfiguration caused 500 errors in production. - Fix: Set
DEBUG=Falseand specifiedALLOWED_HOSTS=['your-app.herokuapp.com'](or['*']for testing) insettings.py.
- Issue:
-
Database Configuration on Deployment
- Issue: Heroku’s
DATABASE_URLwas not parsed correctly, leading to connection failures. - Fix: Integrated
dj_database_url.config()insettings.pyto parse and apply theDATABASE_URLautomatically.
- Issue: Heroku’s
I have tested each of the pages bar the page for Shift Schedule and Reports due to them being placeholders for future development.
The performance is low on the pages where there is massive amounts of data, such as holidays page this due to annual leave planner accounting for the full year, whereas in the employees page, there is c.400 data entries so far.
The following shows HTML validations - No errors found.
Python pep8 validation was done via Code Institute's Python Linter
The only errors recieved here were where some lines of text exceeded the limit of 79 characters, but these have now been rectified.
Python Files Tested:
- admin
- models
- forms
- views
- urls
- settings
The website’s source code is stored on GitHub for version control and collaboration. After each addition, change, or removal of code, run the following commands in your IDE’s terminal:
git add .
git commit -m "meaningful commit message"
git pushYour changes will be available in your GitHub repository at: https://github.com/Deepeshpatel11/Labor-Tool
To fork or copy the repository:
1. Go to the repository page: https://github.com/Deepeshpatel11/Labor-Tool
2. Click the **Fork** button in the top-right corner to create your own copy under your GitHub account.To clone the repo to your local machine:
- On the repo page, click the Code button (to the left of the Gitpod tab).
- Click the clipboard icon to copy the clone URL (
https://github.com/Deepeshpatel11/Labor-Tool.git). - Open your terminal (e.g., Git Bash) and navigate to your desired directory.
- Run:
git clone https://github.com/Deepeshpatel11/Labor-Tool.git
- Enter the cloned directory:
cd Labor-Tool
1. Log in to your [Heroku Dashboard](https://dashboard.heroku.com).
2. Click **New** → **Create new app**.
3. Enter an **App name**, choose a **Region**, then click **Create app**.
4. Under the **Settings** tab, click **Reveal Config Vars** and add:
- `SECRET_KEY` : `<your SECRET KEY>`
- `DATABASE_URL` : `<your Postgres Database URL>`
5. Still in **Settings**, click **Add buildpack** and add, in this order:
1. `heroku/python`
2. `heroku/nodejs`- Switch to the Deploy tab.
- Under Deployment method, select GitHub.
- Search for
Deepeshpatel11/Labor-Tooland click Connect. - Choose Automatic deploys (optional) to redeploy on every push, or Manual deploy to trigger builds yourself.
- Click Deploy Branch (or wait for automatic deploy).
- Once the build succeeds, click Open app to launch your live site.
- Deepesh Patel – concept, design, development, testing, documentation, and deployment.
- Jubril - Thank you for guiding me and helping me bring my vision to fruition.
- Version Control: GitHub
- CI/CD & Runtime: Heroku
- IDE & Containers: Visual Studio Code
- Django Documentation – for comprehensive framework guidance
- Bootstrap Documentation – for responsive UI patterns
- Code Institute – Full Stack Software Development Diploma curriculum
- Open-Source Community – maintainers of all third-party packages used
- Paigination - I used this guide to have responsive paigination https://www.sitepoint.com/community/t/responsive-table-that-converts-to-card-layout/322248/2
- Deployment - A special shout out to Oisin, whom helped me debug my code.
- Testing - Thank You Shiv for testing out the functionality of the website on different devices.
- Emotional Support - Prachi Thank you for dealing with my querks whilst this projecgt consumed me and pushing me to achieve this goal!




























