commit 8d63bd6193df33a4c2c7edf0800c5cafd6de4481 Author: VARUN Date: Tue Apr 2 13:26:32 2024 +0530 initial commit diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..492648b --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..8eec2f9 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/skyonnweb.iml b/.idea/skyonnweb.iml new file mode 100644 index 0000000..74d515a --- /dev/null +++ b/.idea/skyonnweb.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..5596b44 --- /dev/null +++ b/main.py @@ -0,0 +1,16 @@ +# This is a sample Python script. + +# Press Shift+F10 to execute it or replace it with your code. +# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings. + + +def print_hi(name): + # Use a breakpoint in the code line below to debug your script. + print(f'Hi, {name}') # Press Ctrl+F8 to toggle the breakpoint. + + +# Press the green button in the gutter to run the script. +if __name__ == '__main__': + print_hi('PyCharm') + +# See PyCharm help at https://www.jetbrains.com/help/pycharm/ diff --git a/skyonnweb/manage.py b/skyonnweb/manage.py new file mode 100644 index 0000000..8c91b94 --- /dev/null +++ b/skyonnweb/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" +import os +import sys + + +def main(): + """Run administrative tasks.""" + os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'skyonnweb.settings') + try: + from django.core.management import execute_from_command_line + except ImportError as exc: + raise ImportError( + "Couldn't import Django. Are you sure it's installed and " + "available on your PYTHONPATH environment variable? Did you " + "forget to activate a virtual environment?" + ) from exc + execute_from_command_line(sys.argv) + + +if __name__ == '__main__': + main() diff --git a/skyonnweb/profile_pics/001_-_Admin_Dashboard_-.png b/skyonnweb/profile_pics/001_-_Admin_Dashboard_-.png new file mode 100644 index 0000000..a05250c Binary files /dev/null and b/skyonnweb/profile_pics/001_-_Admin_Dashboard_-.png differ diff --git a/skyonnweb/profile_pics/001_-_Admin_Dashboard_-_WRKZrun.png b/skyonnweb/profile_pics/001_-_Admin_Dashboard_-_WRKZrun.png new file mode 100644 index 0000000..a05250c Binary files /dev/null and b/skyonnweb/profile_pics/001_-_Admin_Dashboard_-_WRKZrun.png differ diff --git a/skyonnweb/profile_pics/001_-_Admin_Dashboard_-_bJymqUf.png b/skyonnweb/profile_pics/001_-_Admin_Dashboard_-_bJymqUf.png new file mode 100644 index 0000000..a05250c Binary files /dev/null and b/skyonnweb/profile_pics/001_-_Admin_Dashboard_-_bJymqUf.png differ diff --git a/skyonnweb/profile_pics/001_-_Admin_Dashboard_-_l2c3o5F.png b/skyonnweb/profile_pics/001_-_Admin_Dashboard_-_l2c3o5F.png new file mode 100644 index 0000000..a05250c Binary files /dev/null and b/skyonnweb/profile_pics/001_-_Admin_Dashboard_-_l2c3o5F.png differ diff --git a/skyonnweb/profile_pics/0391605a-c602-4996-94f1-a2e8ce0c7e2d.webm b/skyonnweb/profile_pics/0391605a-c602-4996-94f1-a2e8ce0c7e2d.webm new file mode 100644 index 0000000..348e348 Binary files /dev/null and b/skyonnweb/profile_pics/0391605a-c602-4996-94f1-a2e8ce0c7e2d.webm differ diff --git a/skyonnweb/profile_pics/2762751.jpg b/skyonnweb/profile_pics/2762751.jpg new file mode 100644 index 0000000..4bda14b Binary files /dev/null and b/skyonnweb/profile_pics/2762751.jpg differ diff --git a/skyonnweb/profile_pics/2762751_npMMFLh.jpg b/skyonnweb/profile_pics/2762751_npMMFLh.jpg new file mode 100644 index 0000000..4bda14b Binary files /dev/null and b/skyonnweb/profile_pics/2762751_npMMFLh.jpg differ diff --git a/skyonnweb/profile_pics/2762751_rA3oUct.jpg b/skyonnweb/profile_pics/2762751_rA3oUct.jpg new file mode 100644 index 0000000..4bda14b Binary files /dev/null and b/skyonnweb/profile_pics/2762751_rA3oUct.jpg differ diff --git a/skyonnweb/profile_pics/Login_page_in_HTML.png b/skyonnweb/profile_pics/Login_page_in_HTML.png new file mode 100644 index 0000000..228b404 Binary files /dev/null and b/skyonnweb/profile_pics/Login_page_in_HTML.png differ diff --git a/skyonnweb/profile_pics/Login_page_in_HTML_ODqHEPB.png b/skyonnweb/profile_pics/Login_page_in_HTML_ODqHEPB.png new file mode 100644 index 0000000..228b404 Binary files /dev/null and b/skyonnweb/profile_pics/Login_page_in_HTML_ODqHEPB.png differ diff --git a/skyonnweb/profile_pics/Manager_Dashboard.png b/skyonnweb/profile_pics/Manager_Dashboard.png new file mode 100644 index 0000000..a3367a1 Binary files /dev/null and b/skyonnweb/profile_pics/Manager_Dashboard.png differ diff --git a/skyonnweb/profile_pics/Manager_Dashboard_BJH5c4E.png b/skyonnweb/profile_pics/Manager_Dashboard_BJH5c4E.png new file mode 100644 index 0000000..a3367a1 Binary files /dev/null and b/skyonnweb/profile_pics/Manager_Dashboard_BJH5c4E.png differ diff --git a/skyonnweb/profile_pics/Manager_Dashboard_Bu1yh5a.png b/skyonnweb/profile_pics/Manager_Dashboard_Bu1yh5a.png new file mode 100644 index 0000000..a3367a1 Binary files /dev/null and b/skyonnweb/profile_pics/Manager_Dashboard_Bu1yh5a.png differ diff --git a/skyonnweb/profile_pics/Manager_Dashboard_DVGDNYK.png b/skyonnweb/profile_pics/Manager_Dashboard_DVGDNYK.png new file mode 100644 index 0000000..a3367a1 Binary files /dev/null and b/skyonnweb/profile_pics/Manager_Dashboard_DVGDNYK.png differ diff --git a/skyonnweb/profile_pics/Manager_Dashboard_JjtBMGB.png b/skyonnweb/profile_pics/Manager_Dashboard_JjtBMGB.png new file mode 100644 index 0000000..a3367a1 Binary files /dev/null and b/skyonnweb/profile_pics/Manager_Dashboard_JjtBMGB.png differ diff --git a/skyonnweb/profile_pics/Manager_Dashboard_QmrcdRE.png b/skyonnweb/profile_pics/Manager_Dashboard_QmrcdRE.png new file mode 100644 index 0000000..a3367a1 Binary files /dev/null and b/skyonnweb/profile_pics/Manager_Dashboard_QmrcdRE.png differ diff --git a/skyonnweb/profile_pics/New_Job_Posting_-.png b/skyonnweb/profile_pics/New_Job_Posting_-.png new file mode 100644 index 0000000..26751a1 Binary files /dev/null and b/skyonnweb/profile_pics/New_Job_Posting_-.png differ diff --git a/skyonnweb/profile_pics/New_Job_Posting_-_1AwS2ng.png b/skyonnweb/profile_pics/New_Job_Posting_-_1AwS2ng.png new file mode 100644 index 0000000..26751a1 Binary files /dev/null and b/skyonnweb/profile_pics/New_Job_Posting_-_1AwS2ng.png differ diff --git a/skyonnweb/profile_pics/New_Job_Posting_-_3lCtXfC.png b/skyonnweb/profile_pics/New_Job_Posting_-_3lCtXfC.png new file mode 100644 index 0000000..26751a1 Binary files /dev/null and b/skyonnweb/profile_pics/New_Job_Posting_-_3lCtXfC.png differ diff --git a/skyonnweb/profile_pics/New_Job_Posting_-_72XBNEo.png b/skyonnweb/profile_pics/New_Job_Posting_-_72XBNEo.png new file mode 100644 index 0000000..26751a1 Binary files /dev/null and b/skyonnweb/profile_pics/New_Job_Posting_-_72XBNEo.png differ diff --git a/skyonnweb/profile_pics/New_Job_Posting_-_qd0gaPT.png b/skyonnweb/profile_pics/New_Job_Posting_-_qd0gaPT.png new file mode 100644 index 0000000..26751a1 Binary files /dev/null and b/skyonnweb/profile_pics/New_Job_Posting_-_qd0gaPT.png differ diff --git a/skyonnweb/profile_pics/Screenshot_1.png b/skyonnweb/profile_pics/Screenshot_1.png new file mode 100644 index 0000000..3c5ba30 Binary files /dev/null and b/skyonnweb/profile_pics/Screenshot_1.png differ diff --git a/skyonnweb/profile_pics/Screenshot_2024-03-06_125339.png b/skyonnweb/profile_pics/Screenshot_2024-03-06_125339.png new file mode 100644 index 0000000..9de84ca Binary files /dev/null and b/skyonnweb/profile_pics/Screenshot_2024-03-06_125339.png differ diff --git a/skyonnweb/profile_pics/Screenshot_2024-03-06_125421.png b/skyonnweb/profile_pics/Screenshot_2024-03-06_125421.png new file mode 100644 index 0000000..5bd47ad Binary files /dev/null and b/skyonnweb/profile_pics/Screenshot_2024-03-06_125421.png differ diff --git a/skyonnweb/profile_pics/Screenshot_2024-03-06_125421_e6790TX.png b/skyonnweb/profile_pics/Screenshot_2024-03-06_125421_e6790TX.png new file mode 100644 index 0000000..5bd47ad Binary files /dev/null and b/skyonnweb/profile_pics/Screenshot_2024-03-06_125421_e6790TX.png differ diff --git a/skyonnweb/profile_pics/WhatsApp_Image_2023-11-03_at_10.56.39.jpeg b/skyonnweb/profile_pics/WhatsApp_Image_2023-11-03_at_10.56.39.jpeg new file mode 100644 index 0000000..fb91192 Binary files /dev/null and b/skyonnweb/profile_pics/WhatsApp_Image_2023-11-03_at_10.56.39.jpeg differ diff --git a/skyonnweb/profile_pics/WhatsApp_Image_2023-11-03_at_11.04.39.jpeg b/skyonnweb/profile_pics/WhatsApp_Image_2023-11-03_at_11.04.39.jpeg new file mode 100644 index 0000000..a6a229c Binary files /dev/null and b/skyonnweb/profile_pics/WhatsApp_Image_2023-11-03_at_11.04.39.jpeg differ diff --git a/skyonnweb/skyonnadmin/__init__.py b/skyonnweb/skyonnadmin/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/skyonnweb/skyonnadmin/admin.py b/skyonnweb/skyonnadmin/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/skyonnweb/skyonnadmin/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/skyonnweb/skyonnadmin/apps.py b/skyonnweb/skyonnadmin/apps.py new file mode 100644 index 0000000..24690bd --- /dev/null +++ b/skyonnweb/skyonnadmin/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class SkyonnadminConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'skyonnadmin' diff --git a/skyonnweb/skyonnadmin/migrations/0001_initial.py b/skyonnweb/skyonnadmin/migrations/0001_initial.py new file mode 100644 index 0000000..f386406 --- /dev/null +++ b/skyonnweb/skyonnadmin/migrations/0001_initial.py @@ -0,0 +1,38 @@ +# Generated by Django 4.2.11 on 2024-03-14 07:02 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='skyonnAdmin', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('first_name', models.CharField(max_length=50)), + ('last_name', models.CharField(max_length=50)), + ('phone', models.CharField(max_length=15, unique=True)), + ('phone_number_2', models.CharField(blank=True, max_length=15, null=True)), + ('company_email', models.EmailField(max_length=254, null=True)), + ('personal_email', models.EmailField(max_length=254, null=True)), + ('address', models.TextField(null=True)), + ('work_location', models.CharField(max_length=100, null=True)), + ('picture', models.ImageField(null=True, upload_to='profile_pics/')), + ('role', models.CharField(max_length=20)), + ('admin_id', models.CharField(max_length=10, unique=True)), + ('is_active', models.BooleanField(default=True)), + ('is_staff', models.BooleanField(default=False)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/skyonnweb/skyonnadmin/migrations/0002_contact_subcompanydetails_clientdetails.py b/skyonnweb/skyonnadmin/migrations/0002_contact_subcompanydetails_clientdetails.py new file mode 100644 index 0000000..5b42375 --- /dev/null +++ b/skyonnweb/skyonnadmin/migrations/0002_contact_subcompanydetails_clientdetails.py @@ -0,0 +1,75 @@ +# Generated by Django 4.2.11 on 2024-03-18 07:10 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('skyonnadmin', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='Contact', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('first_name', models.CharField(max_length=50)), + ('last_name', models.CharField(max_length=50)), + ('phone_no1', models.CharField(max_length=20)), + ('phone_no2', models.CharField(blank=True, max_length=20, null=True)), + ('company_email', models.EmailField(max_length=254)), + ('designation', models.CharField(max_length=100)), + ('department', models.CharField(max_length=100)), + ], + ), + migrations.CreateModel( + name='SubcompanyDetails', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('parent_company', models.CharField(max_length=100)), + ('sub_company', models.CharField(max_length=100)), + ('location', models.CharField(max_length=100)), + ('department', models.CharField(max_length=100)), + ('gst_no', models.CharField(max_length=50)), + ('address', models.CharField(max_length=200)), + ('client_id', models.CharField(max_length=20, null=True)), + ('admin_first_name', models.CharField(max_length=50)), + ('admin_last_name', models.CharField(max_length=50)), + ('admin_phone_no1', models.CharField(max_length=20)), + ('admin_phone_no2', models.CharField(blank=True, max_length=20, null=True)), + ('admin_company_email', models.EmailField(max_length=254)), + ('admin_designation', models.CharField(max_length=100, null=True)), + ('admin_department', models.CharField(max_length=100, null=True)), + ('admin_location', models.CharField(max_length=100, null=True)), + ('accounts_contacts', models.ManyToManyField(related_name='subcompany_accounts_contacts', to='skyonnadmin.contact')), + ('admin_contacts', models.ManyToManyField(related_name='subcompany_admin_contacts', to='skyonnadmin.contact')), + ('hr_contacts', models.ManyToManyField(related_name='subcompany_hr_contacts', to='skyonnadmin.contact')), + ('recruiter_contacts', models.ManyToManyField(related_name='subcompany_recruiter_contacts', to='skyonnadmin.contact')), + ], + ), + migrations.CreateModel( + name='ClientDetails', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('parent_company', models.CharField(max_length=100)), + ('location', models.CharField(max_length=100)), + ('department', models.CharField(max_length=100)), + ('gst_no', models.CharField(max_length=50)), + ('address', models.CharField(max_length=200)), + ('client_id', models.CharField(max_length=20, null=True)), + ('admin_first_name', models.CharField(max_length=50)), + ('admin_last_name', models.CharField(max_length=50)), + ('admin_phone_no1', models.CharField(max_length=20)), + ('admin_phone_no2', models.CharField(blank=True, max_length=20, null=True)), + ('admin_company_email', models.EmailField(max_length=254)), + ('admin_designation', models.CharField(max_length=100, null=True)), + ('admin_department', models.CharField(max_length=100, null=True)), + ('admin_location', models.CharField(max_length=100, null=True)), + ('accounts_contacts', models.ManyToManyField(related_name='accounts_contacts', to='skyonnadmin.contact')), + ('admin_contacts', models.ManyToManyField(related_name='admin_contacts', to='skyonnadmin.contact')), + ('hr_contacts', models.ManyToManyField(related_name='hr_contacts', to='skyonnadmin.contact')), + ('recruiter_contacts', models.ManyToManyField(related_name='recruiter_contacts', to='skyonnadmin.contact')), + ], + ), + ] diff --git a/skyonnweb/skyonnadmin/migrations/__init__.py b/skyonnweb/skyonnadmin/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/skyonnweb/skyonnadmin/models.py b/skyonnweb/skyonnadmin/models.py new file mode 100644 index 0000000..0ed76a1 --- /dev/null +++ b/skyonnweb/skyonnadmin/models.py @@ -0,0 +1,123 @@ +from django.contrib.auth.models import AbstractBaseUser, BaseUserManager +from django.db import models + + +class CustomUserManager(BaseUserManager): + def create_user(self, phone, password=None, **extra_fields): + if not phone: + raise ValueError('The Phone number must be set') + user = self.model(phone=phone, **extra_fields) + user.set_password(password) + user.save(using=self._db) + return user + + def create_superuser(self, phone, password=None, **extra_fields): + extra_fields.setdefault('is_staff', True) + extra_fields.setdefault('is_superuser', True) + + if extra_fields.get('is_staff') is not True: + raise ValueError('Superuser must have is_staff=True.') + if extra_fields.get('is_superuser') is not True: + raise ValueError('Superuser must have is_superuser=True.') + + return self.create_user(phone, password, **extra_fields) + + +class skyonnAdmin(AbstractBaseUser): + ADMIN_ID_PREFIX = 'SKYA' # Prefix for AdminId + + first_name = models.CharField(max_length=50) + last_name = models.CharField(max_length=50) + phone = models.CharField(max_length=15, unique=True) + phone_number_2 = models.CharField(max_length=15, blank=True, null=True) + company_email = models.EmailField(null=True) # Additional email field + personal_email = models.EmailField(null=True) # Additional email field + address = models.TextField(null=True) # Additional address field + work_location = models.CharField(max_length=100, null=True) # Additional work location field + picture = models.ImageField(upload_to='profile_pics/', null=True) # Additional picture field + role = models.CharField(max_length=20) # Additional role field + admin_id = models.CharField(max_length=10, unique=True) # AdminId field + + is_active = models.BooleanField(default=True) + is_staff = models.BooleanField(default=False) + + objects = CustomUserManager() + + USERNAME_FIELD = 'phone' + + def save(self, *args, **kwargs): + if not self.admin_id: + last_admin = skyonnAdmin.objects.order_by('-id').first() + if last_admin: + last_id = last_admin.admin_id[4:] # Extract the serial number part + new_id = int(last_id) + 1 + else: + new_id = 1 + self.admin_id = f'{self.ADMIN_ID_PREFIX}{new_id:03d}' + super().save(*args, **kwargs) + + def __str__(self): + return self.phone + + +class Contact(models.Model): + client_id = models.CharField(max_length=20, null=True) + first_name = models.CharField(max_length=50) + last_name = models.CharField(max_length=50) + phone_no1 = models.CharField(max_length=20) + phone_no2 = models.CharField(max_length=20, blank=True, null=True) + company_email = models.EmailField() + designation = models.CharField(max_length=100) + department = models.CharField(max_length=100) + + def __str__(self): + return f"{self.first_name} {self.last_name} - {self.company_email}" + + +class ClientDetails(models.Model): + parent_company = models.CharField(max_length=100) + location = models.CharField(max_length=100) + department = models.CharField(max_length=100) + gst_no = models.CharField(max_length=50) + address = models.CharField(max_length=200) + client_id = models.CharField(max_length=20, null=True) + admin_first_name = models.CharField(max_length=50) + admin_last_name = models.CharField(max_length=50) + admin_phone_no1 = models.CharField(max_length=20) + admin_phone_no2 = models.CharField(max_length=20, blank=True, null=True) + admin_company_email = models.EmailField() + admin_designation = models.CharField(max_length=100, null=True) + admin_department = models.CharField(max_length=100, null=True) + admin_location = models.CharField(max_length=100, null=True) + admin_contacts = models.ManyToManyField(Contact, related_name='admin_contacts') + hr_contacts = models.ManyToManyField(Contact, related_name='hr_contacts') + accounts_contacts = models.ManyToManyField(Contact, related_name='accounts_contacts') + recruiter_contacts = models.ManyToManyField(Contact, related_name='recruiter_contacts') + + def __str__(self): + return f"{self.parent_company} - {self.location}" + + +class SubcompanyDetails(models.Model): + parent_company = models.CharField(max_length=100) + sub_company = models.CharField(max_length=100) + location = models.CharField(max_length=100) + department = models.CharField(max_length=100) + gst_no = models.CharField(max_length=50) + address = models.CharField(max_length=200) + client_id = models.CharField(max_length=20, null=True) + admin_first_name = models.CharField(max_length=50) + admin_last_name = models.CharField(max_length=50) + admin_phone_no1 = models.CharField(max_length=20) + admin_phone_no2 = models.CharField(max_length=20, blank=True, null=True) + admin_company_email = models.EmailField() + admin_designation = models.CharField(max_length=100, null=True) + admin_department = models.CharField(max_length=100, null=True) + admin_location = models.CharField(max_length=100, null=True) + admin_contacts = models.ManyToManyField(Contact, related_name='subcompany_admin_contacts') + hr_contacts = models.ManyToManyField(Contact, related_name='subcompany_hr_contacts') + accounts_contacts = models.ManyToManyField(Contact, related_name='subcompany_accounts_contacts') + recruiter_contacts = models.ManyToManyField(Contact, related_name='subcompany_recruiter_contacts') + + def __str__(self): + return f"{self.parent_company} - {self.location}" diff --git a/skyonnweb/skyonnadmin/tests.py b/skyonnweb/skyonnadmin/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/skyonnweb/skyonnadmin/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/skyonnweb/skyonnadmin/urls.py b/skyonnweb/skyonnadmin/urls.py new file mode 100644 index 0000000..b1ecb97 --- /dev/null +++ b/skyonnweb/skyonnadmin/urls.py @@ -0,0 +1,25 @@ +from django.urls import path +from . import views + +urlpatterns = [ + path('', views.home, name='admin_home'), + path('create_admin/', views.create_admin, name='create_admin'), + path('admin-login/', views.login, name='admin-login'), # URL for login + path('admin/dashboard//', views.admin_dashboard, name='dashboard'), + path('admin_logout/', views.logout_view, name='admin_logout'), + # path('client_details/', views.client_details, name='client_details'), + # path('save-details/', views.save_details, name='save_details'), + # path('save-details-subcompany/', views.save_details_subcompany, name='save-details-subcompany'), + # path('api/get_subcompanies/', views.get_locations, name='get_subcompanies'), + # path('get_subcompany_details/', views.get_combined_details, name='get_subcompany_details'), + path('client-details/', views.client_details, name='client-details'), + path('add_subclient/', views.add_subclient, name='add_subclient'), + path('add_client/', views.add_client, name='add_client'), + path('existing_client/', views.existing_client, name='existing_client'), + path('get_contacts/', views.get_contacts, name='get_contacts'), + path('save-details/', views.save_details, name='save_details'), + path('save-details-subcompany/', views.save_details_subcompany, name='save-details-subcompany'), + path('api/get_subcompanies/', views.get_locations, name='get_subcompanies'), + path('get_subcompany_details/', views.get_combined_details, name='get_subcompany_details'), + +] diff --git a/skyonnweb/skyonnadmin/views.py b/skyonnweb/skyonnadmin/views.py new file mode 100644 index 0000000..10731d1 --- /dev/null +++ b/skyonnweb/skyonnadmin/views.py @@ -0,0 +1,334 @@ +from django.contrib import messages +from django.contrib.auth import authenticate, login as auth_login, logout +from django.shortcuts import render, redirect, get_object_or_404 +from .models import skyonnAdmin, ClientDetails, SubcompanyDetails, Contact +from django.contrib.auth.hashers import make_password +from django.http import HttpResponse +import random +import string +from django.http import JsonResponse +import json +from django.core.serializers.json import DjangoJSONEncoder +from django.views.decorators.csrf import csrf_exempt + + +def home(request): + return render(request, 'skyonnadmin/home.html') + + +def create_admin(request): + if request.method == 'POST': + # Retrieve data from the form + first_name = request.POST['first_name'] + last_name = request.POST['last_name'] + phone_number = request.POST['phone'] + phone_number_2 = request.POST.get('phone_number_2') + company_email = request.POST['company_email'] + personal_email = request.POST.get('personal_email') + address = request.POST['address'] + work_location = request.POST['work_location'] + role = 'admin' + password = request.POST['password'] # Assuming there's a password field in the form + hashed_password = make_password(password) + + # Generate admin ID based on the last ID in the database + last_admin = skyonnAdmin.objects.order_by('-id').first() + if last_admin: + last_id = int(last_admin.admin_id[4:]) # Extract the serial number part and convert to int + new_id = last_id + 1 + else: + new_id = 1 + admin_id = f'SKYA{new_id:03d}' # Construct the new admin ID + + # Create the admin user + admin = skyonnAdmin.objects.create( + first_name=first_name, + last_name=last_name, + phone=phone_number, + phone_number_2=phone_number_2, + company_email=company_email, + personal_email=personal_email, + address=address, + work_location=work_location, + role=role, + admin_id=admin_id, + password=hashed_password + ) + admin.backend = 'user.backend.PhoneAuthenticationBackend' + auth_login(request, admin) + + return redirect('dashboard', admin_id=admin.admin_id) + else: + return render(request, 'skyonnadmin/home.html') + # # Redirect to the admin signup page + # return redirect('home') + # + # return render(request, 'skyonnadmin/home.html') + + +def login(request): + if request.method == 'POST': + phone = request.POST.get('phone') + password = request.POST.get('password') + print("Phone:", phone) + + # Retrieve the admin object based on the provided phone number + admin = skyonnAdmin.objects.filter(phone=phone).first() + print(admin) + + if admin is not None: + # Check if the provided password matches the stored password + if admin.check_password(password): + # Password is correct, login successful + # You can implement your login logic here + print("Admin ID:", admin.admin_id) + return redirect('dashboard', admin_id=admin.admin_id) + else: + # Password is incorrect + messages.error(request, 'Invalid password.') + else: + # Admin with the provided phone number does not exist + messages.error(request, 'No admin found for the provided phone number.') + + return render(request, 'skyonnadmin/home.html') + + +def admin_dashboard(request, admin_id): + admin = get_object_or_404(skyonnAdmin, admin_id=admin_id) + + # Get the manager's first name + first_name = admin.first_name.capitalize() + full_name = f"{first_name}" + print(full_name) + + return render(request, 'skyonnadmin/admin_dashboard.html', {'first_name': full_name, 'admin_id': admin_id}) + # Admin dashboard logic goes here + + +def logout_view(request): + logout(request) + return redirect('admin_home') + + +def client_details(request): + + return render(request, 'skyonnadmin/client_details.html') + + +def add_subclient(request): + admin_id = request.GET.get('admin_id', None) + clients = ClientDetails.objects.all() + return render(request, 'skyonnadmin/add_subclient.html', {'clients': clients,'admin_id': admin_id}) + + +def add_client(request): + admin_id = request.GET.get('admin_id', None) + print(admin_id) + clients = ClientDetails.objects.all() + return render(request, 'skyonnadmin/add_client.html', {'clients': clients,'admin_id': admin_id}) + + +def existing_client(request): + return render(request, 'skyonnadmin/existing_client.html') + + +def save_details(request): + if request.method == 'POST': + # Extract data from the first form + parent_company = request.POST.get('ParentCompany', '') + location = request.POST.get('Location', '') + department = request.POST.get('Department', '') + gst_no = request.POST.get('GSTNo', '') + address = request.POST.get('Address', '') + + # Extract data from the second form + first_name = request.POST.get('Admin_FirstName', '') + last_name = request.POST.get('Admin_LastName', '') + phone_no1 = request.POST.get('Admin_PhoneNo1', '') + phone_no2 = request.POST.get('Admin_PhoneNo2', '') + company_email = request.POST.get('Admin_CompanyEmail', '') + designation = request.POST.get('Admin_Designation', '') + admin_department = request.POST.get('Admin_Department', '') + admin_location = request.POST.get('Admin_Location', '') + print(admin_location) + client_id = generate_client_id(parent_company) + + # Save data into the database + job_details = ClientDetails( + parent_company=parent_company, + location=location, + department=department, + gst_no=gst_no, + address=address, + client_id=client_id, + admin_first_name=first_name, + admin_last_name=last_name, + admin_phone_no1=phone_no1, + admin_phone_no2=phone_no2, + admin_company_email=company_email, + admin_designation=designation, + admin_department=admin_department, + admin_location=admin_location + ) + job_details.save() + admin_id = request.GET.get('admin_id', None) + print(admin_id) + return JsonResponse({'status': 'success', 'message': 'Client saved successfully.'}) + else: + return HttpResponse('Invalid request method') + + +@csrf_exempt +def save_details_subcompany(request): + print("00came") + if request.method == 'POST': + # Extract data from the first form + parent_company = request.POST.get('ParentCompany', '') + location = request.POST.get('Location', '') + department = request.POST.get('Department', '') + gst_no = request.POST.get('GSTNo', '') + address = request.POST.get('Address', '') + sub_company = request.POST.get('SubCompany', '') + + # Extract data from the second form + first_name = request.POST.get('Admin_FirstName', '') + last_name = request.POST.get('Admin_LastName', '') + phone_no1 = request.POST.get('Admin_PhoneNo1', '') + phone_no2 = request.POST.get('Admin_PhoneNo2', '') + company_email = request.POST.get('Admin_CompanyEmail', '') + designation = request.POST.get('Admin_Designation', '') + admin_department = request.POST.get('Admin_Department', '') + admin_location = request.POST.get('Admin_Location', '') + print(admin_location) + client_id = generate_client_id(parent_company) + + # Save data into the database + job_details = SubcompanyDetails( + parent_company=parent_company, + sub_company=sub_company, + location=location, + department=department, + gst_no=gst_no, + address=address, + client_id=client_id, + admin_first_name=first_name, + admin_last_name=last_name, + admin_phone_no1=phone_no1, + admin_phone_no2=phone_no2, + admin_company_email=company_email, + admin_designation=designation, + admin_department=admin_department, + admin_location=admin_location + ) + job_details.save() + admin_id = request.GET.get('admin_id', None) + return JsonResponse({'status': 'success', 'message': 'subclient saved successfully.'}) + + + else: + return JsonResponse({'status': 'error', 'message': 'Invalid request method'}, status=400) + + +def get_combined_details(request): + parent_company = request.GET.get('parent_company') + location = request.GET.get('location') + + # Fetch data from ClientDetails and SubcompanyDetails tables based on filters + client_details = ClientDetails.objects.filter(parent_company=parent_company, location=location) + subcompany_details = SubcompanyDetails.objects.filter(parent_company=parent_company, location=location) + + # Combine data from both tables + combined_data = [] + + # Add client details to combined_data + for detail in client_details: + combined_data.append({ + 'parent_company': detail.parent_company, + 'location': detail.location, + 'department': detail.department, + 'gst_no': detail.gst_no, + 'address': detail.address, + 'client_id': detail.client_id, + 'admin_first_name': detail.admin_first_name, + 'admin_last_name': detail.admin_last_name, + 'admin_phone_no1': detail.admin_phone_no1, + 'admin_phone_no2': detail.admin_phone_no2, + 'admin_company_email': detail.admin_company_email, + 'admin_designation': detail.admin_designation, + 'admin_department': detail.admin_department, + 'admin_location': detail.admin_location, + # Add contacts data if needed + }) + + # Add subcompany details to combined_data + for detail in subcompany_details: + combined_data.append({ + 'parent_company': detail.parent_company, + 'sub_company': detail.sub_company, + 'location': detail.location, + 'department': detail.department, + 'gst_no': detail.gst_no, + 'address': detail.address, + 'client_id': detail.client_id, + 'admin_first_name': detail.admin_first_name, + 'admin_last_name': detail.admin_last_name, + 'admin_phone_no1': detail.admin_phone_no1, + 'admin_phone_no2': detail.admin_phone_no2, + 'admin_company_email': detail.admin_company_email, + 'admin_designation': detail.admin_designation, + 'admin_department': detail.admin_department, + 'admin_location': detail.admin_location, + # Add contacts data if needed + }) + print(combined_data) + return JsonResponse(combined_data, safe=False) + + +def get_locations(request): + print(0) + if request.method == 'GET' and 'parent_company' in request.GET: + print(1) + parent_company = request.GET.get('parent_company') + locations = SubcompanyDetails.objects.filter(parent_company=parent_company).values_list('location', flat=True) + serialized_data = json.dumps(list(locations), cls=DjangoJSONEncoder) + return JsonResponse(serialized_data, safe=False) + else: + return JsonResponse({'error': 'Invalid request'}) + + +def generate_client_id(parent_company): + # Extract first 4 letters from parent_company and convert to uppercase + prefix = parent_company[:4].upper() + # Generate 4 random integers + suffix = ''.join(random.choices(string.digits, k=4)) + # Concatenate prefix and suffix to form the client_id + client_id = prefix + suffix + return client_id + + +def get_contacts(request): + client_id = request.GET.get('client_id') + department = request.GET.get('department') + client_details = ClientDetails.objects.filter(client_id=client_id).first() + + if department == 'hiring_managers': + contacts = client_details.hiring_manager_contacts.all() + elif department == 'accounts': + contacts = client_details.accounts_contacts.all() + elif department == 'human_resources': + contacts = client_details.hr_contacts.all() + elif department == 'administration': + contacts = client_details.admin_contacts.all() + else: + contacts = [] + + contacts_data = [{ + "name": f"{contact.first_name} {contact.last_name}", + "designation": contact.designation, + "department": contact.department, + "phone": contact.phone_no1, + "email": contact.company_email, + "location": contact.client_id.location, # Adjust based on your model relationships + } for contact in contacts] + + return JsonResponse({"contacts": contacts_data}) diff --git a/skyonnweb/skyonnweb/__init__.py b/skyonnweb/skyonnweb/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/skyonnweb/skyonnweb/asgi.py b/skyonnweb/skyonnweb/asgi.py new file mode 100644 index 0000000..2ee8d66 --- /dev/null +++ b/skyonnweb/skyonnweb/asgi.py @@ -0,0 +1,16 @@ +""" +ASGI config for skyonnweb project. + +It exposes the ASGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/ +""" + +import os + +from django.core.asgi import get_asgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'skyonnweb.settings') + +application = get_asgi_application() diff --git a/skyonnweb/skyonnweb/settings.py b/skyonnweb/skyonnweb/settings.py new file mode 100644 index 0000000..17435cf --- /dev/null +++ b/skyonnweb/skyonnweb/settings.py @@ -0,0 +1,138 @@ +""" +Django settings for skyonnweb project. + +Generated by 'django-admin startproject' using Django 4.2.11. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/topics/settings/ + +For the full list of settings and their values, see +https://docs.djangoproject.com/en/4.2/ref/settings/ +""" +import os +from pathlib import Path + +# Build paths inside the project like this: BASE_DIR / 'subdir'. +BASE_DIR = Path(__file__).resolve().parent.parent + + +# Quick-start development settings - unsuitable for production +# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'django-insecure-r*y737z-@#o&lm&hfylvv4*h$8c_288g2m_y=e3gz%_-ig!i^_' + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG = True + +ALLOWED_HOSTS = [] + + +# Application definition + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + 'user', + 'skyonnadmin' +] + +MIDDLEWARE = [ + 'django.middleware.security.SecurityMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', +] + +ROOT_URLCONF = 'skyonnweb.urls' + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [os.path.join(BASE_DIR, 'templates')], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + 'django.template.context_processors.media', + ], + }, + }, +] +WSGI_APPLICATION = 'skyonnweb.wsgi.application' + + +# Database +# https://docs.djangoproject.com/en/4.2/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.mysql', + 'NAME': 'skyonn', + 'USER': 'root', + 'PASSWORD': '', + 'HOST': 'localhost', + 'PORT': '3306', + 'OPTIONS': { + 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'", + }, + } +} + + +# Password validation +# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators + +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] + + +# Internationalization +# https://docs.djangoproject.com/en/4.2/topics/i18n/ + +LANGUAGE_CODE = 'en-us' + +TIME_ZONE = 'UTC' + +USE_I18N = True + +USE_TZ = True + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/4.2/howto/static-files/ + +STATIC_URL = 'static/' + +# Default primary key field type +# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + +AUTHENTICATION_BACKENDS = [ + 'user.backend.PhoneAuthenticationBackend', + 'django.contrib.auth.backends.ModelBackend', # Keep the default backend as a fallback +] diff --git a/skyonnweb/skyonnweb/urls.py b/skyonnweb/skyonnweb/urls.py new file mode 100644 index 0000000..5ece3c2 --- /dev/null +++ b/skyonnweb/skyonnweb/urls.py @@ -0,0 +1,10 @@ +from django.contrib import admin +from django.urls import path +from django.contrib import admin +from django.urls import path, include # Make sure to import include here + +urlpatterns = [ + path('admin/', admin.site.urls), + path('', include('user.urls')), # Include your users app URLs + path('skyonnadmin/', include('skyonnadmin.urls')), +] \ No newline at end of file diff --git a/skyonnweb/skyonnweb/wsgi.py b/skyonnweb/skyonnweb/wsgi.py new file mode 100644 index 0000000..e2c4e98 --- /dev/null +++ b/skyonnweb/skyonnweb/wsgi.py @@ -0,0 +1,16 @@ +""" +WSGI config for skyonnweb project. + +It exposes the WSGI callable as a module-level variable named ``application``. + +For more information on this file, see +https://docs.djangoproject.com/en/4.2/howto/deployment/wsgi/ +""" + +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'skyonnweb.settings') + +application = get_wsgi_application() diff --git a/skyonnweb/templates/recruiter/recruiter_dashboard.html b/skyonnweb/templates/recruiter/recruiter_dashboard.html new file mode 100644 index 0000000..92b8ded --- /dev/null +++ b/skyonnweb/templates/recruiter/recruiter_dashboard.html @@ -0,0 +1 @@ +

hiiiiiii {{first_name}}

\ No newline at end of file diff --git a/skyonnweb/templates/skyonnadmin/add_client.html b/skyonnweb/templates/skyonnadmin/add_client.html new file mode 100644 index 0000000..08ce1e2 --- /dev/null +++ b/skyonnweb/templates/skyonnadmin/add_client.html @@ -0,0 +1,352 @@ + + + + + + + New Job Posting + + + + + +
+
+
+ {% csrf_token %} +
+
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+ +

Admin Department Contact person Name for the Above office location*

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ +
+ + +
+
+ + + + diff --git a/skyonnweb/templates/skyonnadmin/add_subclient.html b/skyonnweb/templates/skyonnadmin/add_subclient.html new file mode 100644 index 0000000..2a92ae0 --- /dev/null +++ b/skyonnweb/templates/skyonnadmin/add_subclient.html @@ -0,0 +1,257 @@ + + + + + + Document + + + +
+
+
+ {% csrf_token %} +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+

Admin Department Contact person Name for the Above office location*

+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/skyonnweb/templates/skyonnadmin/admin_dashboard.html b/skyonnweb/templates/skyonnadmin/admin_dashboard.html new file mode 100644 index 0000000..5ce330c --- /dev/null +++ b/skyonnweb/templates/skyonnadmin/admin_dashboard.html @@ -0,0 +1,562 @@ + + + + + + + + + + + Admin Dashboard + + +
+

Home

+

Admin Dashboard

+
+ +
+
+ +
+
+ +
+

{{first_name}}

+LogOut +
+
+ + + +
+ + +
+ + + + \ No newline at end of file diff --git a/skyonnweb/templates/skyonnadmin/client_details.html b/skyonnweb/templates/skyonnadmin/client_details.html new file mode 100644 index 0000000..656f898 --- /dev/null +++ b/skyonnweb/templates/skyonnadmin/client_details.html @@ -0,0 +1,399 @@ + + + + + + Client Details + + + + +

Client Details

+
Client Details
+ +
Existing Client
+
Add New Client
+
Add Sub Clients/Locations
+ +
+

Existing Client

+
+ + + + + + + +
+ +
+ +
+

Add New Client

+
+ {% csrf_token %} +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+
+

Admin Department Contact person Name for the Above office location*

+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
+
+ +
+

Add Sub Clients/Locations

+
+ {% csrf_token %} +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+
+

Department Contact person Name for the Above office location*

+
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
+
+ + + + diff --git a/skyonnweb/templates/skyonnadmin/existing_client.html b/skyonnweb/templates/skyonnadmin/existing_client.html new file mode 100644 index 0000000..19d1ba2 --- /dev/null +++ b/skyonnweb/templates/skyonnadmin/existing_client.html @@ -0,0 +1,255 @@ + + + + + + + New Job Posting + + + + + +
+
+
+ + + + + + +
+
+ +

+
+ + + + + + + + + + + + + + + +
NameDesignationDepartmentPhoneEmailLocationAction
+
+ + + + + diff --git a/skyonnweb/templates/skyonnadmin/home.html b/skyonnweb/templates/skyonnadmin/home.html new file mode 100644 index 0000000..3ae8cf3 --- /dev/null +++ b/skyonnweb/templates/skyonnadmin/home.html @@ -0,0 +1,164 @@ + + + + + Skyonn Admin Portal + + + + +
+

Skyonn Admin Portal

+ +
+
+ {% csrf_token %} +
+ +
+
+ +
+ +
+
+

New user? Sign Up

+
+
+ + +
+ + + diff --git a/skyonnweb/templates/skyonnadmin/test.html b/skyonnweb/templates/skyonnadmin/test.html new file mode 100644 index 0000000..8c9e50d --- /dev/null +++ b/skyonnweb/templates/skyonnadmin/test.html @@ -0,0 +1,224 @@ + + + + + + + + + + + Admin Dashboard + + +
+

Home

+

Admin Dashboard

+
+ +
+
+ +
+
+ +
+

Laxmi

+ LogOut +
+
+ + + + +
+ + diff --git a/skyonnweb/templates/user/add_recruiter.html b/skyonnweb/templates/user/add_recruiter.html new file mode 100644 index 0000000..814c124 --- /dev/null +++ b/skyonnweb/templates/user/add_recruiter.html @@ -0,0 +1,218 @@ + + + + + + + Sign Up Page + + + +
+

Add Recruiter

+
+
+ {% csrf_token %} +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+ +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
+
+
+
+
+ + + + + + \ No newline at end of file diff --git a/skyonnweb/templates/user/all_job_postings.html b/skyonnweb/templates/user/all_job_postings.html new file mode 100644 index 0000000..6784759 --- /dev/null +++ b/skyonnweb/templates/user/all_job_postings.html @@ -0,0 +1,140 @@ + + + + + + + Job/Project Table + + + + + +
+
+

All Job Posting:

+ +
+
+ + + + + + + + + + + + + + {% for posting in job_postings %} + + + + + + + + + + + + + + {% endfor %} +
ClientJobIdSubjectSPOCStart DateEnd DateLocationOpeningsBudgetComments
{{ posting.client }}{{ posting.job_id }}{{ posting.job_description }}{{ posting.spoc }}{{ posting.start_date }}{{ posting.close_date }}{{ posting.location }}{{ posting.no_of_posting }}{{ posting.budget_max }} to {{ posting.budget_max }}{{ posting.special_instructions }}
+ + + + + + + diff --git a/skyonnweb/templates/user/dashboard.html b/skyonnweb/templates/user/dashboard.html new file mode 100644 index 0000000..adc57f8 --- /dev/null +++ b/skyonnweb/templates/user/dashboard.html @@ -0,0 +1,307 @@ + + + + + + + + + + + Dashboard + + +
+ +
+ +
+
+ +
+
+ +
+
+
+
+
+ +
+ + + \ No newline at end of file diff --git a/skyonnweb/templates/user/home.html b/skyonnweb/templates/user/home.html new file mode 100644 index 0000000..1ee105f --- /dev/null +++ b/skyonnweb/templates/user/home.html @@ -0,0 +1,170 @@ + + + + + Skyonn Recruiting Portal + + + + +
+

Skyonn Recruiting Portal

+ +
+
+ {% csrf_token %} +
+ +
+
+ +
+ +
+
+

New user? Sign Up

+
+
+ + +
+ + + diff --git a/skyonnweb/templates/user/new_job_posting.html b/skyonnweb/templates/user/new_job_posting.html new file mode 100644 index 0000000..49c9f4b --- /dev/null +++ b/skyonnweb/templates/user/new_job_posting.html @@ -0,0 +1,280 @@ + + + + + + + New Job Posting + + + +
+

New Job Posting

+
+ {% csrf_token %} +
+ + +
+
+
+
+
+ + +
+
+ + +
+
+ + + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+ + + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+
+ + +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/skyonnweb/templates/user/success_url.html b/skyonnweb/templates/user/success_url.html new file mode 100644 index 0000000..9630c45 --- /dev/null +++ b/skyonnweb/templates/user/success_url.html @@ -0,0 +1 @@ +

success

\ No newline at end of file diff --git a/skyonnweb/templates/user/test.html b/skyonnweb/templates/user/test.html new file mode 100644 index 0000000..a15eab9 --- /dev/null +++ b/skyonnweb/templates/user/test.html @@ -0,0 +1,396 @@ + + + + + + + + + + + Dashboard + + +
+ +
+ +
+
+ +
+
+ +
+
+
+
+
+ +
+
+ + + \ No newline at end of file diff --git a/skyonnweb/user/__init__.py b/skyonnweb/user/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/skyonnweb/user/admin.py b/skyonnweb/user/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/skyonnweb/user/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/skyonnweb/user/apps.py b/skyonnweb/user/apps.py new file mode 100644 index 0000000..36cce4c --- /dev/null +++ b/skyonnweb/user/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class UserConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'user' diff --git a/skyonnweb/user/backend.py b/skyonnweb/user/backend.py new file mode 100644 index 0000000..b19887a --- /dev/null +++ b/skyonnweb/user/backend.py @@ -0,0 +1,15 @@ +from django.contrib.auth.backends import ModelBackend +from django.core.exceptions import MultipleObjectsReturned +from .models import CustomUser + + +class PhoneAuthenticationBackend(ModelBackend): + def authenticate(self, request, phone=None, password=None, **kwargs): + try: + user = CustomUser.objects.get(phone=phone) + if user.check_password(password): + return user + except CustomUser.DoesNotExist: + return None + except MultipleObjectsReturned: + return None diff --git a/skyonnweb/user/migrations/0001_initial.py b/skyonnweb/user/migrations/0001_initial.py new file mode 100644 index 0000000..621500f --- /dev/null +++ b/skyonnweb/user/migrations/0001_initial.py @@ -0,0 +1,40 @@ +# Generated by Django 4.2.11 on 2024-03-13 06:29 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='CustomUser', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('first_name', models.CharField(max_length=50)), + ('last_name', models.CharField(max_length=50)), + ('phone', models.CharField(max_length=15, unique=True)), + ('phone2', models.CharField(blank=True, max_length=15, null=True)), + ('company_email', models.EmailField(max_length=254, null=True)), + ('personal_email', models.EmailField(max_length=254, null=True)), + ('address', models.TextField(null=True)), + ('work_location', models.CharField(max_length=100, null=True)), + ('picture', models.ImageField(null=True, upload_to='profile_pics/')), + ('role', models.CharField(max_length=20)), + ('user_id', models.CharField(max_length=10, unique=True)), + ('is_active', models.BooleanField(default=True)), + ('is_staff', models.BooleanField(default=False)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/skyonnweb/user/migrations/0002_jobposting.py b/skyonnweb/user/migrations/0002_jobposting.py new file mode 100644 index 0000000..894dd2e --- /dev/null +++ b/skyonnweb/user/migrations/0002_jobposting.py @@ -0,0 +1,33 @@ +# Generated by Django 4.2.11 on 2024-03-14 18:50 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('user', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='JobPosting', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('client', models.CharField(max_length=100)), + ('spoc', models.CharField(blank=True, max_length=100, null=True)), + ('start_date', models.DateField()), + ('budget_max', models.DecimalField(decimal_places=2, max_digits=10)), + ('job_description', models.TextField()), + ('special_instructions', models.CharField(blank=True, max_length=200, null=True)), + ('job_id', models.CharField(max_length=20)), + ('spoc_2', models.CharField(blank=True, max_length=100, null=True)), + ('close_date', models.DateField()), + ('location', models.CharField(max_length=100)), + ('no_of_posting', models.IntegerField()), + ('job_type', models.CharField(max_length=20)), + ('header', models.CharField(max_length=200)), + ('experience_in_years', models.IntegerField()), + ], + ), + ] diff --git a/skyonnweb/user/migrations/0003_customuser_manager_assigned.py b/skyonnweb/user/migrations/0003_customuser_manager_assigned.py new file mode 100644 index 0000000..39059e8 --- /dev/null +++ b/skyonnweb/user/migrations/0003_customuser_manager_assigned.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.11 on 2024-03-15 06:46 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('user', '0002_jobposting'), + ] + + operations = [ + migrations.AddField( + model_name='customuser', + name='manager_assigned', + field=models.CharField(max_length=100, null=True), + ), + ] diff --git a/skyonnweb/user/migrations/0004_jobposting_budget_min_alter_jobposting_budget_max.py b/skyonnweb/user/migrations/0004_jobposting_budget_min_alter_jobposting_budget_max.py new file mode 100644 index 0000000..158803a --- /dev/null +++ b/skyonnweb/user/migrations/0004_jobposting_budget_min_alter_jobposting_budget_max.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.11 on 2024-03-18 07:10 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('user', '0003_customuser_manager_assigned'), + ] + + operations = [ + migrations.AddField( + model_name='jobposting', + name='budget_min', + field=models.DecimalField(decimal_places=2, max_digits=10, null=True), + ), + migrations.AlterField( + model_name='jobposting', + name='budget_max', + field=models.DecimalField(decimal_places=2, max_digits=10, null=True), + ), + ] diff --git a/skyonnweb/user/migrations/__init__.py b/skyonnweb/user/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/skyonnweb/user/models.py b/skyonnweb/user/models.py new file mode 100644 index 0000000..6c5f6d2 --- /dev/null +++ b/skyonnweb/user/models.py @@ -0,0 +1,77 @@ +from django.db import models +from django.contrib.auth.models import AbstractBaseUser, BaseUserManager +from django.contrib.auth.models import User + + +class CustomUserManager(BaseUserManager): + def create_user(self, phone, password=None, **extra_fields): + if not phone: + raise ValueError('The Phone number must be set') + user = self.model(phone=phone, **extra_fields) + user.set_password(password) + user.save(using=self._db) + return user + + def create_superuser(self, phone, password=None, **extra_fields): + extra_fields.setdefault('is_staff', True) + extra_fields.setdefault('is_superuser', True) + return self.create_user(phone, password, **extra_fields) + + +class CustomUser(AbstractBaseUser): + first_name = models.CharField(max_length=50) + last_name = models.CharField(max_length=50) + phone = models.CharField(max_length=15, unique=True) + phone2 = models.CharField(max_length=15, blank=True, null=True) + company_email = models.EmailField(null=True) + personal_email = models.EmailField(null=True) + address = models.TextField(null=True) + work_location = models.CharField(max_length=100, null=True) + picture = models.ImageField(upload_to='profile_pics/', null=True) + role = models.CharField(max_length=20) + user_id = models.CharField(max_length=10, unique=True) + is_active = models.BooleanField(default=True) + is_staff = models.BooleanField(default=False) + manager_assigned = models.CharField(max_length=100, null=True) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + objects = CustomUserManager() + + USERNAME_FIELD = 'phone' + + +class JobPosting(models.Model): + client = models.CharField(max_length=100) + spoc = models.CharField(max_length=100, blank=True, null=True) + start_date = models.DateField() + budget_max = models.DecimalField(max_digits=10, decimal_places=2, null=True) + budget_min = models.DecimalField(max_digits=10, decimal_places=2, null=True) + job_description = models.TextField() + special_instructions = models.CharField(max_length=200, blank=True, null=True) + job_id = models.CharField(max_length=20) + spoc_2 = models.CharField(max_length=100, blank=True, null=True) + close_date = models.DateField() + location = models.CharField(max_length=100) + no_of_posting = models.IntegerField() + job_type = models.CharField(max_length=20) + header = models.CharField(max_length=200) + experience_in_years = models.IntegerField() + + def __str__(self): + return self.job_id + + +class Message(models.Model): + sender = models.ForeignKey(User, related_name='sent_messages', on_delete=models.CASCADE) + recipient = models.ForeignKey(User, related_name='received_messages', on_delete=models.CASCADE) + subject = models.CharField(max_length=255) + body = models.TextField() + is_read = models.BooleanField(default=False) + sent_at = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return f'Message from {self.sender} to {self.recipient} - {self.subject}' + + class Meta: + ordering = ['-sent_at'] diff --git a/skyonnweb/user/tests.py b/skyonnweb/user/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/skyonnweb/user/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/skyonnweb/user/urls.py b/skyonnweb/user/urls.py new file mode 100644 index 0000000..a964d1c --- /dev/null +++ b/skyonnweb/user/urls.py @@ -0,0 +1,17 @@ +from django.urls import path +from . import views + +urlpatterns = [ + path('', views.home, name='home'), + path('create_user/', views.create_user, name='create_user'), # URL for creating user + path('user_login/', views.user_login, name='user_login'), # URL for login + path('user/dashboard//', views.dashboard, name='dashboard'), + path('new_job_postings/', views.new_job_posting, name='new_job_postings'), + path('logout/', views.logout_view, name='logout'), + path('save-job-posting/', views.save_job_posting, name='save_job_posting'), + path('add_recruiter/', views.add_recruiter, name='add_recruiter'), + path('create_recruiter/', views.create_recruiter, name='create_recruiter'), + path('all_job_postings/', views.all_job_posting, name='all_job_postings'), + path('send//', views.send_message, name='send_message'), + path('read//', views.mark_as_read, name='mark_as_read'), +] diff --git a/skyonnweb/user/views.py b/skyonnweb/user/views.py new file mode 100644 index 0000000..2041b4b --- /dev/null +++ b/skyonnweb/user/views.py @@ -0,0 +1,237 @@ +from django.shortcuts import render, redirect, get_object_or_404 +from django.contrib.auth import authenticate, login as auth_login, logout +from .models import CustomUser, JobPosting +from skyonnadmin.models import ClientDetails +from django.contrib import messages +from django.http import JsonResponse +from django.db.models import Q +from .models import Message +from django.contrib.auth.models import User +from django.http import HttpResponseRedirect + + + +def home(request): + return render(request, 'user/home.html') + + +def create_user(request): + if request.method == 'POST': + # Handle signup form submission + first_name = request.POST.get('first_name') + last_name = request.POST.get('last_name') + phone = request.POST.get('phone') + phone2 = request.POST.get('phone_2') + company_email = request.POST.get('company_email') + personal_email = request.POST.get('personal_email') + address = request.POST.get('address') + work_location = request.POST.get('work_location') + role = request.POST.get('role') + password = request.POST.get('password') + picture = request.FILES.get('picture') + + # Create user_id based on role + role_prefix = role[0].upper() + user_count = CustomUser.objects.filter(role=role).count() + 1 + user_id = f"{role_prefix}{first_name[:3].upper()}{user_count:03}" + + # Create the CustomUser object + user = CustomUser.objects.create( + first_name=first_name, + last_name=last_name, + phone=phone, + phone2=phone2, + company_email=company_email, + personal_email=personal_email, + address=address, + work_location=work_location, + role=role, + user_id=user_id + ) + user.set_password(password) + user.picture = picture + user.save() + user.backend = 'user.backend.PhoneAuthenticationBackend' + auth_login(request, user) + + return redirect('dashboard', user_id=user.user_id) + else: + return render(request, 'user/home.html') + + +def user_login(request): + if request.method == 'POST': + phone = request.POST.get('phone') + password = request.POST.get('password') + + user = authenticate(request, phone=phone, password=password) + print(phone, password, user) + if user is not None: + auth_login(request, user) + user = CustomUser.objects.filter(phone=phone).first() + if user: + print(user.user_id) + return redirect('dashboard', user_id=user.user_id) + else: + messages.error(request, 'No user found for the provided phone number.') + else: + messages.error(request, 'Invalid phone number or password.') + + return render(request, 'user/home.html') + + +def dashboard(request, user_id): + # Retrieve the manager object using manager_id + user = get_object_or_404(CustomUser, user_id=user_id) + + # Get the manager's first name + first_name = user.first_name.capitalize() + full_name = f"{first_name}'s" + print(full_name) + if user.role == 'manager': + print("hiii") + # Redirect to manager dashboard + return render(request, 'user/test.html', {'first_name': full_name, 'user_id': user_id}) + if user.role == 'recruiter': + # Redirect to manager dashboard + return render(request, 'recruiter/recruiter_dashboard.html', {'first_name': full_name, 'user_id': user_id}) + + +def new_job_posting(request): + clients = ClientDetails.objects.all() + return render(request, 'user/new_job_posting.html', {'clients': clients}) + + +def add_recruiter(request): + user_id = request.GET.get('user_id', None) + print(user_id) + context = {'user_id': user_id} + return render(request, 'user/add_recruiter.html', context) + + +def logout_view(request): + logout(request) + return redirect('home') + + +def save_job_posting(request): + if request.method == 'POST': + client = request.POST.get('Client') + spoc = request.POST.get('SPOC') + start_date = request.POST.get('StartDate') + budget_max = request.POST.get('BudgetMax') + budget_min = request.POST.get('BudgetMin') + job_description = request.POST.get('JobDescription') + special_instructions = request.POST.get('SpecialInstructions') + job_id = request.POST.get('JobID') + spoc_2 = request.POST.get('SPOC2') + close_date = request.POST.get('CloseDate') + location = request.POST.get('Location') + no_of_posting = request.POST.get('NoOfPosting') + job_type = request.POST.get('Type') + header = request.POST.get('Header') + experience_in_years = request.POST.get('Experience_in_Yrs') + print(location) + job_posting = JobPosting( + client=client, + spoc=spoc, + budget_min=budget_min, + start_date=start_date, + budget_max=budget_max, + job_description=job_description, + special_instructions=special_instructions, + job_id=job_id, + spoc_2=spoc_2, + close_date=close_date, + location=location, + no_of_posting=no_of_posting, + job_type=job_type, + header=header, + experience_in_years=experience_in_years + ) + job_posting.save() + return JsonResponse({'status': 'success', 'message': 'Job posting saved successfully.'}) + + return redirect('error_url') + + +def create_recruiter(request): + if request.method == 'POST': + # Handle signup form submission + # print(request.post) + first_name = request.POST.get('first_name') + last_name = request.POST.get('last_name') + phone = request.POST.get('phone') + phone2 = request.POST.get('phone_2') + company_email = request.POST.get('company_email') + personal_email = request.POST.get('personal_email') + address = request.POST.get('address') + work_location = request.POST.get('work_location') + role = "recruiter" # request.POST.get('role') + password = request.POST.get('password') + picture = request.FILES.get('picture') + manager_assigned = request.POST.get('manager_assigned', None) + print(manager_assigned, 1) + # Create user_id based on role + role_prefix = role[0].upper() + user_count = CustomUser.objects.filter(role=role).count() + 1 + user_id = f"{role_prefix}{first_name[:3].upper()}{user_count:03}" + + # Create the CustomUser object + user = CustomUser.objects.create( + first_name=first_name, + last_name=last_name, + phone=phone, + phone2=phone2, + company_email=company_email, + personal_email=personal_email, + address=address, + work_location=work_location, + role=role, + user_id=user_id, + manager_assigned=manager_assigned + ) + user.set_password(password) + user.picture = picture + user.save() + return redirect('dashboard', user_id=manager_assigned) + # return JsonResponse({'success': True, 'message': 'Recruiter added successfully!'}) + + else: + messages.success(request, 'Data saved successfully.') + + # Instead of redirecting, render the same form page again + return render(request, 'user/add_recruiter.html') + + +def all_job_posting(request): + query = request.GET.get('query', '') # Get the query parameter if it exists + + if query: + job_postings = JobPosting.objects.filter( + job_id__icontains=query) | JobPosting.objects.filter( + spoc__icontains=query) | JobPosting.objects.filter( + client__icontains=query + ) + print(query) + else: + job_postings = JobPosting.objects.all() + + return render(request, 'user/all_job_postings.html', {'job_postings': job_postings}) + + +def send_message(request, recipient_id): + recipient = get_object_or_404(User, pk=recipient_id) + if request.method == 'POST': + subject = request.POST.get('subject') + body = request.POST.get('body') + message = Message.objects.create(sender=request.user, recipient=recipient, subject=subject, body=body) + return redirect('messages') + return render(request, 'send_message.html', {'recipient': recipient}) + + +def mark_as_read(request, message_id): + message = get_object_or_404(Message, pk=message_id, recipient=request.user) + message.is_read = True + message.save() + return redirect('messages')