@ -0,0 +1,3 @@
|
|||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
@ -0,0 +1,6 @@
|
|||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<settings>
|
||||||
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
|
<version value="1.0" />
|
||||||
|
</settings>
|
||||||
|
</component>
|
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.9 (skyonnweb)" project-jdk-type="Python SDK" />
|
||||||
|
<component name="PyCharmProfessionalAdvertiser">
|
||||||
|
<option name="shown" value="true" />
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/skyonnweb.iml" filepath="$PROJECT_DIR$/.idea/skyonnweb.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PYTHON_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
@ -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/
|
@ -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()
|
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 260 KiB |
After Width: | Height: | Size: 260 KiB |
After Width: | Height: | Size: 260 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 58 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 89 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 88 KiB |
After Width: | Height: | Size: 214 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 71 KiB |
After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 139 KiB |
@ -0,0 +1,3 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
@ -0,0 +1,6 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class SkyonnadminConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'skyonnadmin'
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
@ -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')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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}"
|
@ -0,0 +1,3 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
@ -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/<str:admin_id>/', 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'),
|
||||||
|
|
||||||
|
]
|
@ -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})
|
@ -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()
|
@ -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
|
||||||
|
]
|
@ -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')),
|
||||||
|
]
|
@ -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()
|
@ -0,0 +1 @@
|
|||||||
|
<h1>hiiiiiii {{first_name}}</h1>
|
@ -0,0 +1,352 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>New Job Posting</title>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||||
|
<style>
|
||||||
|
.Admin_client{
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
width: 45rem;
|
||||||
|
margin: auto;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.two-col {
|
||||||
|
display: flex;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.three-col .col1,
|
||||||
|
.three-col .col2 {
|
||||||
|
flex: 0 0 22%;
|
||||||
|
}
|
||||||
|
.two-col .form-group {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
.two-col input,
|
||||||
|
.two-col select {
|
||||||
|
width: calc(100% - 50px);
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
label.required::after {
|
||||||
|
content: "*";
|
||||||
|
color: red;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.form-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.form-group label {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
#Address {
|
||||||
|
margin-left: 40px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-left: 300px;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
float:left;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-left: -10px;
|
||||||
|
}
|
||||||
|
li a {
|
||||||
|
display: block;
|
||||||
|
color: black;
|
||||||
|
text-align: center;
|
||||||
|
padding: 1px;
|
||||||
|
text-decoration: underline;
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-left: 60px;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color:red;
|
||||||
|
}
|
||||||
|
.container1 {
|
||||||
|
margin-left: 500px;
|
||||||
|
width: 900px;
|
||||||
|
}
|
||||||
|
.add p {
|
||||||
|
margin-left: 470px;
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
.add a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.container1 input[type="text"] {
|
||||||
|
width: calc(100% - 20px);
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.add span {
|
||||||
|
display: inline-block;
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
border: 2px solid black; /* Add border property */
|
||||||
|
border-radius: 50%;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 30px;
|
||||||
|
margin-left: 530px;
|
||||||
|
color: black;
|
||||||
|
}}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="Admin_client">
|
||||||
|
<div class="container">
|
||||||
|
<form id="addClientForm" action="{% url 'save_details' %}?admin_id={{ admin_id }}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="two-col">
|
||||||
|
<div class="col1">
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="ParentCompany" name="ParentCompany" required placeholder="Eg. Oracle in India" tabindex="1">
|
||||||
|
<label for="ParentCompany" class="required" style="width: 200px;" >Parent Company</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Location" name="Location" required placeholder="Eg. Hyderabad" tabindex="3">
|
||||||
|
<label for="Location" class="required" style="margin-left: 70px;" >Location</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Department" name="Department" required placeholder="" tabindex="5">
|
||||||
|
<label for="Department" class="required" style="margin-left: 47px;" >Department</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col2">
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="GSTNo" name="GSTNo" required placeholder="Eg. LSB009876L1" tabindex="2">
|
||||||
|
<label for="GSTNo" class="" style="margin-left: 10px;" >GST No.</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<textarea id="Address" rows="2" cols="30" name="Address" required style="margin-left:5px; height: 70px; padding: 5px;" tabindex="4" ></textarea>
|
||||||
|
<label for="Address" class="required" >Address</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3 id="subLocationHeader" style="text-align: center;">Admin Department Contact person Name for the Above office location*</h3>
|
||||||
|
<div class="two-col" style="margin-left: 150px;">
|
||||||
|
<div class="col1">
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_FirstName" name="Admin_FirstName" required placeholder="First Name*" width="300px" class="required" tabindex="6">
|
||||||
|
<label for="FirstName"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_PhoneNo1" name="Admin_PhoneNo1" required placeholder="Phone No1*" class="required" tabindex="8">
|
||||||
|
<label for="Admin_PhoneNo1"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="email" id="Admin_CompanyEmail" name="Admin_CompanyEmail" required placeholder="Company Email*" class="required" tabindex="10">
|
||||||
|
<label for="Admin_CompanyEmail"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_Designation" name="Admin_Designation" required placeholder="Designation*" class="required" tabindex="12">
|
||||||
|
<label for="Admin_Designation"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col2">
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_LastName" name="Admin_LastName" required placeholder="Last Name*" class="required" tabindex="7">
|
||||||
|
<label for="Admin_LastName"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_PhoneNo2" name="Admin_PhoneNo2" required placeholder="Phone No2" tabindex="9">
|
||||||
|
<label for="Admin_PhoneNo2"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_Location" name="Admin_Location" required placeholder="Location*" class="required" tabindex="11">
|
||||||
|
<label for="Admin_Location"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_Department" name="Admin_Department" required placeholder="Department*" class="required" tabindex="13">
|
||||||
|
<label for="Admin_Department"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="button" onclick="saveClient()" style="border-radius: 5px; background-color:lightgreen; width: 100px; margin-left:310px; margin-top: -20px; padding: 5px;"> Save</button>
|
||||||
|
</form>
|
||||||
|
<div class="add" id="addSubLocation">
|
||||||
|
<a href="#" onclick="toggleaddSubLocation()">
|
||||||
|
<span class="circle"><i class="fas fa-plus" style="margin-top: -10px;"></i></span>
|
||||||
|
<p>Add New sub location</p>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div id="subClientsLocationsForm" style="display: none;">
|
||||||
|
<form id="addSubClientForm" action="{% url 'save-details-subcompany' %}?admin_id={{ admin_id }}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="two-col">
|
||||||
|
<div class="col1">
|
||||||
|
<div class="form-group">
|
||||||
|
<select id="ParentCompany" name="ParentCompany" required tabindex="1">
|
||||||
|
<option value=""tabindex="1" >Select Client</option>
|
||||||
|
|
||||||
|
{% for client in clients %}
|
||||||
|
<option value="{{ client.parent_company}}">{{ client.parent_company }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<label for="ParentCompany" class="required" style="width: 200px;">Parent Company:</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="SubCompany" name="SubCompany" required placeholder="Eg. oracle India" tabindex="3">
|
||||||
|
<label for="SubCompany" class="required" style="margin-left: 28px;">Sub Company:</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Location" name="Location" required placeholder="Eg. bangalore"tabindex="5" >
|
||||||
|
<label for="Location" class="required" style="margin-left: 70px;">Location:</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Department" name="Department" required placeholder="Eg. Billing or Accouts or Hiring" tabindex="6">
|
||||||
|
<label for="Department" class="required" style="margin-left: 47px;">Department:</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col2">
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="GSTNo" name="GSTNo" required placeholder="Eg.234567H23LS" tabindex="2">
|
||||||
|
<label for="GSTNo" class="required" style="margin-left: 10px;">GST No.</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<textarea id="Address" rows="2" cols="30" name="Address" required style="margin-left:5px; height: 70px; padding: 5px;" tabindex="4"></textarea>
|
||||||
|
<label for="Address" class="required">Address</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h3 id="subLocationHeader" style="text-align: center;">Admin Department Contact person Name for the Above office location*</h3>
|
||||||
|
<div class="two-col" style="margin-left: 170px;">
|
||||||
|
<div class="col1">
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_FirstName" name="Admin_FirstName" required placeholder="First Name*" width="200px" class="required" tabindex="7">
|
||||||
|
<label for="Admin_FirstName"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_PhoneNo1" name="Admin_PhoneNo1" required placeholder="Phone No1*" class="required" tabindex="9">
|
||||||
|
<label for="Admin_PhoneNo1"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="email" id="Admin_CompanyEmail" name="Admin_CompanyEmail" required placeholder="Company Email*" class="required" tabindex="11">
|
||||||
|
<label for="Admin_CompanyEmail"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_Designation" name="Admin_Designation" required placeholder="Designation*" class="required" tabindex="13">
|
||||||
|
<label for="Admin_Designation"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col2">
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_LastName" name="Admin_LastName" required placeholder="Last Name*" class="required" tabindex="8">
|
||||||
|
<label for="Admin_LastName"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_PhoneNo2" name="Admin_PhoneNo2" required placeholder="Phone No2" tabindex="10">
|
||||||
|
<label for="Admin_PhoneNo2"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_Location" name="Admin_Location" required placeholder="Location*" class="required" tabindex="12">
|
||||||
|
<label for="Admin_Location"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_Department" name="Admin_Department" required placeholder="Department*" class="required" tabindex="14">
|
||||||
|
<label for="Admin_Department"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="button" onclick="saveSubClient()" style="border-radius: 5px; background-color:lightgreen; width: 100px; margin-left:330px; margin-top: -20px; padding: 5px;"> Save</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function toggleaddSubLocation() {
|
||||||
|
var mainForm = document.getElementById("addClientForm");
|
||||||
|
var subForm = document.getElementById("subClientsLocationsForm");
|
||||||
|
var addButton = document.getElementById("addSubLocation");
|
||||||
|
|
||||||
|
mainForm.style.display = "none";
|
||||||
|
subForm.style.display = "block";
|
||||||
|
addButton.style.display = "none";
|
||||||
|
}
|
||||||
|
function saveClient() {
|
||||||
|
const form = document.getElementById('addClientForm');
|
||||||
|
const formData = new FormData(form);
|
||||||
|
// Ensure this retrieves the correct URL
|
||||||
|
const url = form.getAttribute('action');
|
||||||
|
console.log('CSRF Token:', '{{ csrf_token }}');
|
||||||
|
console.log('Form action URL:', url);
|
||||||
|
|
||||||
|
fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData,
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': '{{ csrf_token }}', // Assuming you have CSRF token available
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
console.log('Success:', data);
|
||||||
|
alert('Client saved successfully.');
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
alert('An error occurred while saving the job posting.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function saveSubClient() {
|
||||||
|
const form = document.getElementById('addSubClientForm');
|
||||||
|
const formData = new FormData(form);
|
||||||
|
// Ensure this retrieves the correct URL
|
||||||
|
const url = form.getAttribute('action');
|
||||||
|
console.log('CSRF Token:', '{{ csrf_token }}');
|
||||||
|
console.log('Form action URL:', url);
|
||||||
|
|
||||||
|
fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData,
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': '{{ csrf_token }}', // Assuming you have CSRF token available
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
console.log('Success:', data);
|
||||||
|
alert('Client saved successfully.');
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
alert('An error occurred while saving the job posting.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,257 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Document</title>
|
||||||
|
</head>
|
||||||
|
<style>
|
||||||
|
.addSubclient{
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
width: 45rem;
|
||||||
|
margin: auto;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.two-col {
|
||||||
|
display: flex;
|
||||||
|
white-space: nowrap;
|
||||||
|
margin-left: 100px;
|
||||||
|
}
|
||||||
|
.three-col .col1,
|
||||||
|
.three-col .col2 {
|
||||||
|
flex: 0 0 22%;
|
||||||
|
}
|
||||||
|
.two-col .form-group {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
.two-col input,
|
||||||
|
.two-col select {
|
||||||
|
width: calc(100% - 50px);
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
label.required::after {
|
||||||
|
content: "*";
|
||||||
|
color: red;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
.form-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.form-group label {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
#Address {
|
||||||
|
margin-left: 40px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-left: 300px;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
float:left;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-left: -10px;
|
||||||
|
}
|
||||||
|
li a {
|
||||||
|
display: block;
|
||||||
|
color: black;
|
||||||
|
text-align: center;
|
||||||
|
padding: 1px;
|
||||||
|
text-decoration: underline;
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-left: 60px;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color:red;
|
||||||
|
}
|
||||||
|
.container1 {
|
||||||
|
margin-left: 500px;
|
||||||
|
width: 900px;
|
||||||
|
}
|
||||||
|
.add p {
|
||||||
|
margin-left: 370px;
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
.add a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.container1 input[type="text"] {
|
||||||
|
width: calc(100% - 20px);
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.add span {
|
||||||
|
display: inline-block;
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
border: 2px solid black;
|
||||||
|
border-radius: 50%;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 30px;
|
||||||
|
margin-left: 430px;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
#jobPostingForm1{
|
||||||
|
margin-left: -130px;
|
||||||
|
}
|
||||||
|
#jobPostingForm{
|
||||||
|
margin-left: -130px;
|
||||||
|
}
|
||||||
|
.container1 .col2 {
|
||||||
|
margin-top: -1px;
|
||||||
|
}}
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
<div class="addSubclient">
|
||||||
|
<div class="container">
|
||||||
|
<form id="addSubClientForm" action="{% url 'save-details-subcompany' %}?admin_id={{ admin_id }}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="two-col">
|
||||||
|
<div class="col1">
|
||||||
|
<div class="form-group">
|
||||||
|
<select id="ParentCompany" name="ParentCompany" required tabindex="1">
|
||||||
|
<option value="" tabindex="1">Select Client</option>
|
||||||
|
|
||||||
|
{% for client in clients %}
|
||||||
|
<option value="{{ client.parent_company }}">{{ client.parent_company }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
<label for="ParentCompany" class="required" style="width: 200px;">Parent Company:</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="SubCompany" name="SubCompany" required placeholder="Eg. oracle India" tabindex="3">
|
||||||
|
<label for="SubCompany" class="required" style="margin-left: 28px;">Sub Company:</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Location" name="Location" required placeholder="Eg. bangalore" tabindex="5">
|
||||||
|
<label for="Location" class="required" style="margin-left: 70px;">Location:</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Department" name="Department" required placeholder="Eg. Billing or Accouts or Hiring" tabindex="6">
|
||||||
|
<label for="Department" class="required" style="margin-left: 47px;">Department:</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col2">
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="GSTNo" name="GSTNo" required placeholder="Eg.234567H23LS" tabindex="2">
|
||||||
|
<label for="GSTNo" class="required" style="margin-left: 10px;">GST No.</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<textarea id="Address" rows="2" cols="30" name="Address" required style="margin-left:5px; height: 70px; padding: 5px;" tabindex="4"></textarea>
|
||||||
|
<label for="Address" class="required">Address</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h3 id="subLocationHeader" style="text-align: center;">Admin Department Contact person Name for the Above office location*</h3>
|
||||||
|
<div class="two-col" style="margin-left: 170px;">
|
||||||
|
<div class="col1">
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_FirstName" name="Admin_FirstName" required placeholder="First Name*" width="200px" class="required" tabindex="7">
|
||||||
|
<label for="Admin_FirstName"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_PhoneNo1" name="Admin_PhoneNo1" required placeholder="Phone No1*" class="required" tabindex="9">
|
||||||
|
<label for="Admin_PhoneNo1"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="email" id="Admin_CompanyEmail" name="Admin_CompanyEmail" required placeholder="Company Email*" class="required" tabindex="11">
|
||||||
|
<label for="Admin_CompanyEmail"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_Designation" name="Admin_Designation" required placeholder="Designation*" class="required" tabindex="13">
|
||||||
|
<label for="Admin_Designation"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col2">
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_LastName" name="Admin_LastName" required placeholder="Last Name*" class="required" tabindex="8">
|
||||||
|
<label for="Admin_LastName"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_PhoneNo2" name="Admin_PhoneNo2" required placeholder="Phone No2" tabindex="10">
|
||||||
|
<label for="Admin_PhoneNo2"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_Location" name="Admin_Location" required placeholder="Location*" class="required" tabindex="12">
|
||||||
|
<label for="Admin_Location"></label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="text" id="Admin_Department" name="Admin_Department" required placeholder="Department*" class="required" tabindex="14">
|
||||||
|
<label for="Admin_Department"></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="button" onclick="saveSubClient()" style="border-radius: 5px; background-color:lightgreen; width: 100px; margin-left:330px; margin-top: -20px; padding: 5px; ma"> Save</button> </form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
var form = document.getElementById('secondForm');
|
||||||
|
form.addEventListener('submit', function(e) {
|
||||||
|
e.preventDefault(); // Prevent the default form submission
|
||||||
|
|
||||||
|
var formData = new FormData(form);
|
||||||
|
|
||||||
|
// AJAX request to the server
|
||||||
|
fetch("{% url 'save-details-subcompany' %}", {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData,
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': formData.get('csrfmiddlewaretoken') // Include CSRF token
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
console.log(data.message); // Log the success message
|
||||||
|
document.getElementById('successMessage').style.display = 'block'; // Show success message
|
||||||
|
form.reset(); // Reset the form fields
|
||||||
|
})
|
||||||
|
.catch(error => console.error('Error:', error));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function saveSubClient() {
|
||||||
|
const form = document.getElementById('addSubClientForm');
|
||||||
|
const formData = new FormData(form);
|
||||||
|
// Ensure this retrieves the correct URL
|
||||||
|
const url = form.getAttribute('action');
|
||||||
|
console.log('CSRF Token:', '{{ csrf_token }}');
|
||||||
|
console.log('Form action URL:', url);
|
||||||
|
|
||||||
|
fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData,
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': '{{ csrf_token }}', // Assuming you have CSRF token available
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
console.log('Success:', data);
|
||||||
|
alert('Client saved successfully.');
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
alert('An error occurred while saving the job posting.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,562 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||||
|
<style>
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap');
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
height: 60px;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
}
|
||||||
|
h2{
|
||||||
|
color: red;
|
||||||
|
margin-left:400px ;
|
||||||
|
white-space: nowrap;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.search--notification--profile {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: calc(100% - 100px);
|
||||||
|
padding: 0 40px;
|
||||||
|
margin-left: -10px;
|
||||||
|
}
|
||||||
|
.search {
|
||||||
|
width: 300px;
|
||||||
|
padding: 5px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.search-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border: 1px solid black;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
.search input {
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
text-indent: 15px;
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
.search button {
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.main {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
min-height: calc(100vh - 60px);
|
||||||
|
}
|
||||||
|
.sidebar {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 250px;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
border-right: 1px solid black;
|
||||||
|
}
|
||||||
|
.sidebar.active {
|
||||||
|
width: 103px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.sidebar.active .sidebar--item {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.sidebar--items a,
|
||||||
|
.sidebar--bottom-items a {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color:blue;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.sidebar--items a:hover,
|
||||||
|
.sidebar--bottom-items a:hover {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
#clientDetailsContainer{
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
width: 45rem;
|
||||||
|
margin: auto;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.two-col {
|
||||||
|
display: flex;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
}
|
||||||
|
.three-col .col1,
|
||||||
|
.three-col .col2 {
|
||||||
|
flex: 0 0 22%;
|
||||||
|
}
|
||||||
|
.two-col .form-group {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
.two-col input,
|
||||||
|
.two-col select {
|
||||||
|
width: calc(100% - 50px);
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
label.required::after {
|
||||||
|
content: "*";
|
||||||
|
color: red;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-left: 300px;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
float:left;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-left: -10px;
|
||||||
|
}
|
||||||
|
li a {
|
||||||
|
display: block;
|
||||||
|
color: black;
|
||||||
|
text-align: center;
|
||||||
|
padding: 1px;
|
||||||
|
text-decoration: underline;
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-left: 60px;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color:red;
|
||||||
|
}
|
||||||
|
.container1 {
|
||||||
|
margin-left: 100px;
|
||||||
|
width: 900px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<title> Admin Dashboard</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<section class="header">
|
||||||
|
<h1 style="color: lightskyblue; margin-top: 10px; margin-left: 50px; text-decoration: underline;">Home</h1>
|
||||||
|
<h2>Admin <span>Dashboard</span></h2>
|
||||||
|
<div class="search--notification--profile">
|
||||||
|
<div class="search">
|
||||||
|
<div class="search-container">
|
||||||
|
<input type="text" placeholder="Search">
|
||||||
|
<button><i class="ri-search-2-line"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bell" style="margin-right: 40px;">
|
||||||
|
<i class="fa-solid fa-bell"></i>
|
||||||
|
</div>
|
||||||
|
<div class="profile" style="margin-right: 40px;">
|
||||||
|
<i class="fa-solid fa-user"></i>
|
||||||
|
</div>
|
||||||
|
<h3 style="margin-right: 40px;">{{first_name}}</h3>
|
||||||
|
<a href="{% url 'admin_logout' %}" style="margin-right: 350px; color: blue; font-size: larger; text-decoration: underline;">LogOut</a>
|
||||||
|
</section>
|
||||||
|
<section class="main">
|
||||||
|
<div class="sidebar">
|
||||||
|
<ul class="sidebar--items">
|
||||||
|
<li><a href="#" onclick="showClientDetails()">Existing Client</a></li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="sidebar-link" onclick="activateLink(this)">
|
||||||
|
<span class="sidebar--item">Team Details</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="sidebar-link" onclick="loadPage('/new_job_postings/')">
|
||||||
|
<span class="sidebar--item">New Job Postings</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'all_job_postings' %}" class="sidebar-link" onclick="activateLink(this)">
|
||||||
|
<span class="sidebar--item">All Jobs Postings</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="sidebar-link" onclick="activateLink(this)">
|
||||||
|
<span class="sidebar--item">Messages</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="sidebar-link" onclick="activateLink(this)">
|
||||||
|
<span class="sidebar--item">Pending Process</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="sidebar-link" onclick="activateLink(this)">
|
||||||
|
<span class="sidebar--item">Submitted Resumes</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="sidebar-link" onclick="activateLink(this)">
|
||||||
|
<span class="sidebar--item">Add a New SPOC</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="sidebar-link" onclick="activateLink(this)">
|
||||||
|
<span class="sidebar--item">Client Details</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="sidebar-link" onclick="activateLink(this)">
|
||||||
|
<span class="sidebar--item">Activity Report</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div id="clientDetailsContainer" style="display: none;">
|
||||||
|
<ul>
|
||||||
|
<div class="nav">
|
||||||
|
<!-- <li><a href="#" class="btn" onclick="#">Client Details</a></li>-->
|
||||||
|
<li><a href="#" class="btn" onclick="loadPage('/skyonnadmin/existing_client/','{{admin_id}}')">Existing Client</a></li>
|
||||||
|
<li><a href="#" class="btn" onclick="loadPage('/skyonnadmin/add_client/','{{admin_id}}')">Add New Client</a></li>
|
||||||
|
<li><a href="#" class="btn" onclick="loadPage('/skyonnadmin/add_subclient/','{{admin_id}}')">Add Sub Clients/Locations</a></li>
|
||||||
|
</div>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="dynamicContentContainer"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function loadPage(pageName, adminId) {
|
||||||
|
var urlWithAdminId = pageName + "?admin_id=" + adminId; // Append admin_id as query parameter
|
||||||
|
var xhttp = new XMLHttpRequest();
|
||||||
|
xhttp.onreadystatechange = function() {
|
||||||
|
if (this.readyState == 4 && this.status == 200) {
|
||||||
|
document.getElementById("dynamicContentContainer").innerHTML = this.responseText;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhttp.open("GET", urlWithAdminId, true);
|
||||||
|
xhttp.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function activateLink(link) {
|
||||||
|
var links = document.querySelectorAll('.sidebar-link');
|
||||||
|
links.forEach(function(item) {
|
||||||
|
item.classList.remove('active');
|
||||||
|
});
|
||||||
|
link.classList.add('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
function showClientDetails() {
|
||||||
|
var clientDetailsContainer = document.getElementById('clientDetailsContainer');
|
||||||
|
clientDetailsContainer.style.display = 'block';
|
||||||
|
document.getElementById('dynamicContentContainer').innerHTML = ''; // Clear any existing content
|
||||||
|
}
|
||||||
|
function editEmployee(button) {
|
||||||
|
var row = button.closest('tr');
|
||||||
|
Array.from(row.cells).forEach(cell => cell.contentEditable = true);
|
||||||
|
button.textContent = 'Save';
|
||||||
|
button.onclick = function() { saveEmployee(this); };
|
||||||
|
}
|
||||||
|
function saveEmployee(button) {
|
||||||
|
var row = button.closest('tr');
|
||||||
|
Array.from(row.cells).forEach(cell => cell.contentEditable = false);
|
||||||
|
button.textContent = 'Edit';
|
||||||
|
button.onclick = function() { editEmployee(this); };
|
||||||
|
}
|
||||||
|
function deleteEmployee(button) {
|
||||||
|
var row = button.closest('tr');
|
||||||
|
row.parentNode.removeChild(row);
|
||||||
|
}
|
||||||
|
function addActionButtons(row) {
|
||||||
|
var actionCell = row.insertCell();
|
||||||
|
var editButton = createButton('Edit', editEmployee);
|
||||||
|
var deleteButton = createButton('Delete', deleteEmployee);
|
||||||
|
actionCell.append(editButton,deleteButton);
|
||||||
|
var space = document.createElement('span');
|
||||||
|
space.innerHTML = ' ';
|
||||||
|
actionCell.append(editButton, space, deleteButton); }
|
||||||
|
function createButton(text, onclickFunction) {
|
||||||
|
var button = document.createElement('button');
|
||||||
|
button.textContent = text;
|
||||||
|
button.onclick = function() { onclickFunction(this); };
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
function addRowToOriginalTable(data) {
|
||||||
|
var table = document.getElementById('originalEmployeeTable').getElementsByTagName('tbody')[0];
|
||||||
|
var row = table.insertRow();
|
||||||
|
data.forEach(item => row.insertCell().textContent = item);
|
||||||
|
addActionButtons(row);
|
||||||
|
}
|
||||||
|
var isNewTableAdded = false;
|
||||||
|
function addNewTable() {
|
||||||
|
if (!isNewTableAdded) {
|
||||||
|
var originalTableParent = document.querySelector('.original-table');
|
||||||
|
var newTable = document.createElement('table');
|
||||||
|
newTable.id = 'newEmployeeTable';
|
||||||
|
newTable.style.width = '60%';
|
||||||
|
newTable.style.Color = 'white';
|
||||||
|
newTable.style.marginLeft = '350px';
|
||||||
|
newTable.style.borderCollapse = 'collapse';
|
||||||
|
newTable.style.marginBottom = '20px';
|
||||||
|
newTable.style.borderBottom = 'none';
|
||||||
|
var originalTableHeader = originalTableParent.querySelector('thead').cloneNode(true);
|
||||||
|
newTable.appendChild(originalTableHeader);
|
||||||
|
var newRow = newTable.insertRow();
|
||||||
|
var columns = originalTableHeader.querySelectorAll('th').length;
|
||||||
|
for (var i = 0; i < columns - 1; i++) {
|
||||||
|
newRow.insertCell().contentEditable = true;
|
||||||
|
}
|
||||||
|
newRow.insertCell().innerHTML = '<button onclick="saveNewTable()">Save</button>';
|
||||||
|
originalTableParent.appendChild(newTable);
|
||||||
|
isNewTableAdded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function saveNewTable() {
|
||||||
|
var confirmation = confirm("Are you sure you want to save the details?");
|
||||||
|
if (confirmation) {
|
||||||
|
var originalTable = document.getElementById('originalEmployeeTable');
|
||||||
|
var originalTBody = originalTable.getElementsByTagName('tbody')[0];
|
||||||
|
var newTable = document.getElementById('newEmployeeTable');
|
||||||
|
var newRows = newTable.getElementsByTagName('tr');
|
||||||
|
for (var i = 1; i < newRows.length; i++) {
|
||||||
|
var newData = Array.from(newRows[i].cells).slice(0, -1).map(cell => cell.innerText);
|
||||||
|
var newRow = originalTBody.insertRow();
|
||||||
|
newData.forEach(item => newRow.insertCell().textContent = item);
|
||||||
|
addActionButtons(newRow);
|
||||||
|
}
|
||||||
|
newTable.remove();
|
||||||
|
isNewTableAdded = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function toggleaddSubLocation() {
|
||||||
|
var mainForm = document.getElementById("addClientForm");
|
||||||
|
var subForm = document.getElementById("subClientsLocationsForm");
|
||||||
|
var addButton = document.getElementById("addSubLocation");
|
||||||
|
|
||||||
|
mainForm.style.display = "none";
|
||||||
|
subForm.style.display = "block";
|
||||||
|
addButton.style.display = "none";
|
||||||
|
}
|
||||||
|
function saveForm() {
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
|
||||||
|
var formData = new FormData(document.getElementById('jobPostingForm'));
|
||||||
|
|
||||||
|
|
||||||
|
if (!validateForm(formData)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('POST', 'url/to/submit/form', true);
|
||||||
|
xhr.onload = function () {
|
||||||
|
if (xhr.status >= 200 && xhr.status < 300) {
|
||||||
|
|
||||||
|
console.log(xhr.responseText);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
console.error(xhr.statusText);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.onerror = function () {
|
||||||
|
|
||||||
|
console.error(xhr.statusText);
|
||||||
|
|
||||||
|
};
|
||||||
|
xhr.send(formData);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateForm(formData) {
|
||||||
|
|
||||||
|
var requiredFields = ['ParentCompany', 'SubCompany', 'Location', 'Department', 'GSTNo', 'Address', 'FirstName', 'PhoneNo1', 'CompanyEmail', 'Designation', 'LastName', 'Location', 'Designation'];
|
||||||
|
for (var i = 0; i < requiredFields.length; i++) {
|
||||||
|
var field = requiredFields[i];
|
||||||
|
if (!formData.get(field)) {
|
||||||
|
alert("Please fill in all the required fields.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
function showPopup() {
|
||||||
|
document.getElementById('popup').style.display = 'block';
|
||||||
|
}
|
||||||
|
function hidePopup() {
|
||||||
|
document.getElementById('popup').style.display = 'none';
|
||||||
|
}
|
||||||
|
function saveForm() {
|
||||||
|
if (validateForm()) {
|
||||||
|
document.getElementById('jobPostingForm').submit();
|
||||||
|
hidePopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function validateForm() {
|
||||||
|
var requiredFields = document.querySelectorAll('input[required], select[required], textarea[required]');
|
||||||
|
var isValid = true;
|
||||||
|
requiredFields.forEach(function(field) {
|
||||||
|
if (!field.value.trim()) {
|
||||||
|
isValid = false;
|
||||||
|
field.style.border = '2px solid red';
|
||||||
|
} else {
|
||||||
|
field.style.border = '1px solid #ccc';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!isValid) {
|
||||||
|
alert('Please fill in all required fields.');
|
||||||
|
}
|
||||||
|
return isValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveJobPosting() {
|
||||||
|
const form = document.getElementById('jobPostingForm');
|
||||||
|
const formData = new FormData(form);
|
||||||
|
// Ensure this retrieves the correct URL
|
||||||
|
const url = form.getAttribute('action');
|
||||||
|
console.log('CSRF Token:', '{{ csrf_token }}');
|
||||||
|
console.log('Form action URL:', url);
|
||||||
|
|
||||||
|
fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData,
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': '{{ csrf_token }}', // Assuming you have CSRF token available
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
console.log('Success:', data);
|
||||||
|
alert('Job posting saved successfully.');
|
||||||
|
form.reset();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
alert('An error occurred while saving the job posting.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveClient() {
|
||||||
|
const form = document.getElementById('addClientForm');
|
||||||
|
const formData = new FormData(form);
|
||||||
|
// Ensure this retrieves the correct URL
|
||||||
|
const url = form.getAttribute('action');
|
||||||
|
console.log('CSRF Token:', '{{ csrf_token }}');
|
||||||
|
console.log('Form action URL:', url);
|
||||||
|
|
||||||
|
fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData,
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': '{{ csrf_token }}', // Assuming you have CSRF token available
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
console.log('Success:', data);
|
||||||
|
alert('Client saved successfully.');
|
||||||
|
form.reset();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
alert('An error occurred while saving the job posting.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function saveSubClient() {
|
||||||
|
const form = document.getElementById('addSubClientForm');
|
||||||
|
const formData = new FormData(form);
|
||||||
|
// Ensure this retrieves the correct URL
|
||||||
|
const url = form.getAttribute('action');
|
||||||
|
console.log('CSRF Token:', '{{ csrf_token }}');
|
||||||
|
console.log('Form action URL:', url);
|
||||||
|
|
||||||
|
fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData,
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': '{{ csrf_token }}', // Assuming you have CSRF token available
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
console.log('Success:', data);
|
||||||
|
alert('Sub Client saved successfully.');
|
||||||
|
form.reset();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
alert('An error occurred while saving the job posting.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,399 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Client Details</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
text-align: center; /* Center align the heading */
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
margin-top: 20px; /* Add some top margin to the heading */
|
||||||
|
}
|
||||||
|
.tab {
|
||||||
|
float: left;
|
||||||
|
width: 25%;
|
||||||
|
height: 50px;
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
border-right: 1px solid #ccc;
|
||||||
|
box-sizing: border-box;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 50px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.tab:last-child {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
.tabcontent {
|
||||||
|
display: none;
|
||||||
|
padding: 20px;
|
||||||
|
clear: both;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.two-col {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.col1, .col2 {
|
||||||
|
flex: 0 0 48%;
|
||||||
|
}
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
input[type="text"], select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
button[type="submit"] {
|
||||||
|
margin-left: 16%;
|
||||||
|
width: 100px;
|
||||||
|
padding: 8px;
|
||||||
|
color: black;
|
||||||
|
background-color: lightblue;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.add {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.circle {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
background-color: lightblue;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 30px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.add a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
.search-fields {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-fields label {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-fields select {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-fields button {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h2>Client Details</h2> <!-- Heading centered above the tabs -->
|
||||||
|
<div class="tab" onclick="openTab('existingClient')">Client Details</div>
|
||||||
|
|
||||||
|
<div class="tab" onclick="openTab('existingClient')">Existing Client</div>
|
||||||
|
<div class="tab" onclick="openTab('addNewClient')">Add New Client</div>
|
||||||
|
<div class="tab" onclick="openTab('addSubClients')">Add Sub Clients/Locations</div>
|
||||||
|
|
||||||
|
<div id="existingClient" class="tabcontent">
|
||||||
|
<h3>Existing Client</h3>
|
||||||
|
<div class="search-fields">
|
||||||
|
<label for="parentCompanyDropdown">Parent Company</label>
|
||||||
|
<select id="parentCompanyDropdown" name="parentCompany" required>
|
||||||
|
<option value="" disabled selected>Select Parent Company</option>
|
||||||
|
<option value="Oracle India">Oracle India</option>
|
||||||
|
<option value="Persistent Systems">Persistent Systems</option>
|
||||||
|
<option value="Tech Mahendra">Tech Mahendra</option>
|
||||||
|
<option value="GS Labs">GS Labs</option>
|
||||||
|
<!-- Add other options here -->
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<label for="Location">Location</label>
|
||||||
|
<select id="Location" name="Location" required>
|
||||||
|
<option value="" disabled selected>Select Location</option>
|
||||||
|
<option value="all">All</option>
|
||||||
|
<option value="hyderabad">Hyderabad</option>
|
||||||
|
<option value="bangalore">Bangalore</option>
|
||||||
|
<option value="pune">Pune</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<button onclick="fetchAndDisplayData()">Submit</button>
|
||||||
|
</div>
|
||||||
|
<iframe id="combinedDataIframe" style="width: 100%; height: 400px;"></iframe>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="addNewClient" class="tabcontent">
|
||||||
|
<h3>Add New Client</h3>
|
||||||
|
<form id="addClientForm" action="{% url 'save_details' %}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="two-col">
|
||||||
|
<div class="col1">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="ParentCompany">Parent Company</label>
|
||||||
|
<select id="ParentCompany" name="ParentCompany" required>
|
||||||
|
<option value="" disabled selected>Select Parent Company</option>
|
||||||
|
<option value="Oracle India">Oracle India</option>
|
||||||
|
<option value="Persistent Systems">Persistent Systems</option>
|
||||||
|
<option value="Tech Mahendra">Tech Mahendra</option>
|
||||||
|
<!-- Add other options here -->
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Location">Location</label>
|
||||||
|
<input type="text" id="Location" name="Location" required placeholder="Location">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Department">Department</label>
|
||||||
|
<input type="text" id="Department" name="Department" required placeholder="Department">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="GSTNo">GST No.</label>
|
||||||
|
<input type="text" id="GSTNo" name="GSTNo" required placeholder="GST No.">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Address">Address</label>
|
||||||
|
<input type="text" id="Address" name="Address" required placeholder="Address">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h3 style="text-align: center; margin-bottom: 20px;">Admin Department Contact person Name for the Above office location*</h3>
|
||||||
|
<div class="container1">
|
||||||
|
<div class="two-col">
|
||||||
|
<div class="col1">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Admin_FirstName">First Name</label>
|
||||||
|
<input type="text" id="Admin_FirstName" name="Admin_FirstName" required placeholder="First Name">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Admin_PhoneNo1">Phone No1</label>
|
||||||
|
<input type="text" id="Admin_PhoneNo1" name="Admin_PhoneNo1" required placeholder="Phone No1">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Admin_CompanyEmail">Company Email</label>
|
||||||
|
<input type="text" id="Admin_CompanyEmail" name="Admin_CompanyEmail" required placeholder="Company Email">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Admin_Designation">Designation</label>
|
||||||
|
<input type="text" id="Admin_Designation" name="Admin_Designation" required placeholder="Designation">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Admin_LastName">Last Name</label>
|
||||||
|
<input type="text" id="Admin_LastName" name="Admin_LastName" required placeholder="Last Name">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Admin_PhoneNo2">Phone No2</label>
|
||||||
|
<input type="text" id="Admin_PhoneNo2" name="Admin_PhoneNo2" required placeholder="Phone No2">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Admin_Location">Location</label>
|
||||||
|
<input type="text" id="Admin_Location" name="Admin_Location" required placeholder="Location">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Admin_Department">Department</label>
|
||||||
|
<input type="text" id="Admin_Department" name="Admin_Department" required placeholder="Department">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="submit" id="saveButton">Save</button>
|
||||||
|
<div class="add">
|
||||||
|
<a href="{% url 'client-details' %}">
|
||||||
|
<span class="circle">+</span>
|
||||||
|
<p>Add New sub location</p>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="addSubClients" class="tabcontent">
|
||||||
|
<h3>Add Sub Clients/Locations</h3>
|
||||||
|
<form id="addSubClientForm" action="{% url 'save-details-subcompany' %}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="two-col">
|
||||||
|
<div class="col1">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="ParentCompany">Parent Company</label>
|
||||||
|
<select id="ParentCompany" name="ParentCompany" required>
|
||||||
|
<option value="" disabled selected>Select Parent Company</option>
|
||||||
|
<option value="Oracle India">Oracle India</option>
|
||||||
|
<option value="Persistent Systems">Persistent Systems</option>
|
||||||
|
<option value="Tech Mahendra">Tech Mahendra</option>
|
||||||
|
<!-- Add other options here -->
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Location">Location</label>
|
||||||
|
<input type="text" id="Location" name="Location" required placeholder="Location">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Department">Department</label>
|
||||||
|
<input type="text" id="Department" name="Department" required placeholder="Department">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="GSTNo">GST No.</label>
|
||||||
|
<input type="text" id="GSTNo" name="GSTNo" required placeholder="GST No.">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="SubCompany">Sub Company</label>
|
||||||
|
<input type="text" id="SubCompany" name="SubCompany" required placeholder="Sub Company">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Address">Address</label>
|
||||||
|
<input type="text" id="Address" name="Address" required placeholder="Address">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h3 style="text-align: center; margin-bottom: 20px;">Department Contact person Name for the Above office location*</h3>
|
||||||
|
<div class="container1">
|
||||||
|
<div class="two-col">
|
||||||
|
<div class="col1">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Admin_FirstName">First Name</label>
|
||||||
|
<input type="text" id="Admin_FirstName" name="Admin_FirstName" required placeholder="First Name">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Admin_PhoneNo1">Phone No1</label>
|
||||||
|
<input type="text" id="Admin_PhoneNo1" name="Admin_PhoneNo1" required placeholder="Phone No1">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Admin_CompanyEmail">Company Email</label>
|
||||||
|
<input type="text" id="Admin_CompanyEmail" name="Admin_CompanyEmail" required placeholder="Company Email">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Admin_Designation">Designation</label>
|
||||||
|
<input type="text" id="Admin_Designation" name="Admin_Designation" required placeholder="Designation">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Admin_LastName">Last Name</label>
|
||||||
|
<input type="text" id="Admin_LastName" name="Admin_LastName" required placeholder="Last Name">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Admin_PhoneNo2">Phone No2</label>
|
||||||
|
<input type="text" id="Admin_PhoneNo2" name="Admin_PhoneNo2" required placeholder="Phone No2">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Admin_Location">Location</label>
|
||||||
|
<input type="text" id="Admin_Location" name="Admin_Location" required placeholder="Location">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Admin_Department">Department</label>
|
||||||
|
<input type="text" id="Admin_Department" name="Admin_Department" required placeholder="Department">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="submit" id="saveButton">Save</button>
|
||||||
|
<div class="add">
|
||||||
|
<a href="{% url 'client-details' %}">
|
||||||
|
<span class="circle">+</span>
|
||||||
|
<p>Add New sub location</p>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function openTab(tabName) {
|
||||||
|
var i, tabcontent;
|
||||||
|
tabcontent = document.getElementsByClassName("tabcontent");
|
||||||
|
for (i = 0; i < tabcontent.length; i++) {
|
||||||
|
tabcontent[i].style.display = "none";
|
||||||
|
}
|
||||||
|
document.getElementById(tabName).style.display = "block";
|
||||||
|
}
|
||||||
|
function fetchAndDisplayData() {
|
||||||
|
const parentCompany = document.getElementById('parentCompanyDropdown').value;
|
||||||
|
const location = document.getElementById('Location').value;
|
||||||
|
|
||||||
|
fetchCombinedDetails(parentCompany, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchCombinedDetails(parentCompany, location) {
|
||||||
|
fetch(`/skyonnadmin/get_subcompany_details/?parent_company=${parentCompany}&location=${location}`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
// Update the iframe with the combined data
|
||||||
|
const iframe = document.getElementById('combinedDataIframe');
|
||||||
|
const htmlContent = generateHTML(data);
|
||||||
|
iframe.contentWindow.document.open();
|
||||||
|
iframe.contentWindow.document.write(htmlContent);
|
||||||
|
iframe.contentWindow.document.close();
|
||||||
|
})
|
||||||
|
.catch(error => console.error('Error fetching combined details:', error));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function generateHTML(data) {
|
||||||
|
let html = '<html><head><title>Combined Data</title></head><body>';
|
||||||
|
html += '<h2>Combined Data</h2>';
|
||||||
|
html += '<table border="1"><tr>';
|
||||||
|
|
||||||
|
// Add table headers
|
||||||
|
const columns = Object.keys(data[0]);
|
||||||
|
columns.forEach(column => {
|
||||||
|
if (column !== 'sub_company') { // Ignore 'sub_company' field here
|
||||||
|
html += `<th>${column}</th>`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Add separate column for 'sub_company'
|
||||||
|
html += '<th>Sub Company</th>';
|
||||||
|
|
||||||
|
html += '</tr>';
|
||||||
|
|
||||||
|
// Add data rows
|
||||||
|
data.forEach(detail => {
|
||||||
|
html += '<tr>';
|
||||||
|
columns.forEach(column => {
|
||||||
|
if (column !== 'sub_company') { // Ignore 'sub_company' field here
|
||||||
|
html += `<td>${detail[column]}</td>`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Add value for 'sub_company' column or empty if it doesn't exist
|
||||||
|
html += `<td>${detail.sub_company || ''}</td>`;
|
||||||
|
html += '</tr>';
|
||||||
|
});
|
||||||
|
|
||||||
|
html += '</table></body></html>';
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('parentCompanyDropdown').addEventListener('change', function() {
|
||||||
|
const selectedParentCompany = this.value;
|
||||||
|
const selectedLocation = document.getElementById('Location').value;
|
||||||
|
fetchCombinedDetails(selectedParentCompany, selectedLocation);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('Location').addEventListener('change', function() {
|
||||||
|
const selectedLocation = this.value;
|
||||||
|
const selectedParentCompany = document.getElementById('parentCompanyDropdown').value;
|
||||||
|
fetchCombinedDetails(selectedParentCompany, selectedLocation);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,255 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>New Job Posting</title>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||||
|
<style>
|
||||||
|
.Existing_client {
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
}
|
||||||
|
label.required::after {
|
||||||
|
content: "*";
|
||||||
|
color: black;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
.form-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.form-group label {
|
||||||
|
margin-right: 1px;
|
||||||
|
width: 150px;
|
||||||
|
}
|
||||||
|
.form-group select,
|
||||||
|
.form-group input {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-left: 300px;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
float: left;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
margin-left: -10px;
|
||||||
|
}
|
||||||
|
li a {
|
||||||
|
display: block;
|
||||||
|
color: black;
|
||||||
|
text-align: center;
|
||||||
|
padding: 1px;
|
||||||
|
text-decoration: underline;
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-left: 60px;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
width: 60%; /* Adjusted width */
|
||||||
|
margin: auto;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-left: 300px; /* Adjusted margin */
|
||||||
|
}
|
||||||
|
.form-group button {
|
||||||
|
margin-left: auto;
|
||||||
|
margin-top: 10px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
width: 60%; /* Adjusted width */
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-bottom: 50px;
|
||||||
|
margin-left: 350px;
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
th, td {
|
||||||
|
border: 1px solid #DDDDDD;
|
||||||
|
padding: 8px;
|
||||||
|
text-align: left;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
background-color: #336699;
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
color: black;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
.add-button {
|
||||||
|
margin-top: 20px;
|
||||||
|
text-align: right;
|
||||||
|
margin-right: 270px;
|
||||||
|
}
|
||||||
|
.save-button {
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
.add a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.add p {
|
||||||
|
margin-left: 1180px;
|
||||||
|
margin-top: 3px;
|
||||||
|
}
|
||||||
|
.add span {
|
||||||
|
display: inline-block;
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
border: 2px solid black; /* Add border property */
|
||||||
|
border-radius: 50%;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 30px;
|
||||||
|
margin-left: 1200px;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="Existing_client">
|
||||||
|
<div class="container">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="ClientDropdown" class="required">Client:</label>
|
||||||
|
<select id="ClientDropdown" name="Client" required style="margin-left: -80px; height: 30px;">
|
||||||
|
|
||||||
|
<option value="">Select Client</option>
|
||||||
|
<option value="oracle">Oracle</option>
|
||||||
|
<option value="skyonn">Skyonn</option>
|
||||||
|
<option value="capgemini">Capgemini</option>
|
||||||
|
</select>
|
||||||
|
<label for="SubClientDropdown" class="required">Sub Client:</label>
|
||||||
|
<select id="SubClientDropdown" name="SubClient" required style="margin-left: -50px; height: 30px;">
|
||||||
|
|
||||||
|
<option value="">Select Sub Client</option>
|
||||||
|
<option value="vr heights">VR Heights</option>
|
||||||
|
<option value="sky tower">Sky Tower</option>
|
||||||
|
<option value="tech park">Tech Park</option>
|
||||||
|
</select>
|
||||||
|
<button id="getDetailsButton" type="button" style="margin-left: 30px;margin-top: 0px; background-color: #77C3EC; color: white; height: 30px;">Get Details</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul style="margin-top: -25px;">
|
||||||
|
<li><a href="javascript:void(0);" class="department-link" data-department="hiring_managers">HIRING MANAGERS</a></li>
|
||||||
|
<li><a href="javascript:void(0);" class="department-link" data-department="accounts">ACCOUNT DEPARTMENT</a></li>
|
||||||
|
<li><a href="javascript:void(0);" class="department-link" data-department="human_resources">HUMAN RESOURCES</a></li>
|
||||||
|
<li><a href="javascript:void(0);" class="department-link" data-department="administration">ADMINISTRATION AND LEGAL</a></li>
|
||||||
|
</ul>
|
||||||
|
<br><br>
|
||||||
|
<div class="original-table">
|
||||||
|
<table id="originalEmployeeTable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Designation</th>
|
||||||
|
<th>Department</th>
|
||||||
|
<th>Phone</th>
|
||||||
|
<th>Email</th>
|
||||||
|
<th>Location</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<!-- Rows will be added here dynamically -->
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="add">
|
||||||
|
<a href="#" onclick="addNewTable()">
|
||||||
|
<span class="circle"><i class="fas fa-plus" style="margin-top: -10px;"></i></span>
|
||||||
|
<p>Add New</p>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
<!--document.addEventListener('DOMContentLoaded', function () {-->
|
||||||
|
<!-- const getDetailsButton = document.getElementById('getDetailsButton');-->
|
||||||
|
<!-- if (getDetailsButton) {-->
|
||||||
|
<!-- console.log('Button found, adding event listener.'); // This should print if the button is successfully found-->
|
||||||
|
<!-- getDetailsButton.addEventListener('click', function() {-->
|
||||||
|
<!-- console.log('Get Details clicked'); // This should print when the button is clicked-->
|
||||||
|
<!-- const clientId = document.getElementById('ClientDropdown').value;-->
|
||||||
|
<!-- const department = 'hiring_managers'; // Example, adjust as necessary-->
|
||||||
|
<!-- fetchContacts(clientId, department);-->
|
||||||
|
<!-- });-->
|
||||||
|
<!-- } else {-->
|
||||||
|
<!-- console.log('Get Details button not found.'); // This helps identify if there's a problem in finding the button-->
|
||||||
|
<!-- }-->
|
||||||
|
<!--});-->
|
||||||
|
|
||||||
|
<!-- // Initialize with hiring managers data-->
|
||||||
|
<!-- fetchContacts(clientDropdown.value, currentDepartment);-->
|
||||||
|
|
||||||
|
<!-- // Event listener for "Get Details" button-->
|
||||||
|
<!-- getDetailsButton.addEventListener('click', () => {-->
|
||||||
|
<!-- fetchContacts(clientDropdown.value, currentDepartment);-->
|
||||||
|
<!-- });-->
|
||||||
|
|
||||||
|
<!-- // Event listeners for department links-->
|
||||||
|
<!-- departmentLinks.forEach(link => {-->
|
||||||
|
<!-- link.addEventListener('click', (e) => {-->
|
||||||
|
<!-- e.preventDefault();-->
|
||||||
|
<!-- currentDepartment = e.target.getAttribute('data-department');-->
|
||||||
|
<!-- fetchContacts(clientDropdown.value, currentDepartment);-->
|
||||||
|
<!-- // Update active class-->
|
||||||
|
<!-- departmentLinks.forEach(lnk => lnk.classList.remove('active'));-->
|
||||||
|
<!-- e.target.classList.add('active');-->
|
||||||
|
<!-- });-->
|
||||||
|
<!-- });-->
|
||||||
|
|
||||||
|
<!-- const updateContactsDisplay = (contacts) => {-->
|
||||||
|
<!-- const tableBody = document.querySelector('#originalEmployeeTable tbody');-->
|
||||||
|
<!-- tableBody.innerHTML = ''; // Clear existing rows-->
|
||||||
|
<!-- contacts.forEach(contact => {-->
|
||||||
|
<!-- const row = tableBody.insertRow();-->
|
||||||
|
<!-- Object.values(contact).forEach(text => {-->
|
||||||
|
<!-- const cell = row.insertCell();-->
|
||||||
|
<!-- cell.textContent = text;-->
|
||||||
|
<!-- });-->
|
||||||
|
<!-- // Add action buttons if needed-->
|
||||||
|
<!-- });-->
|
||||||
|
|
||||||
|
<!-- // Show a message if no contacts found-->
|
||||||
|
<!-- if (contacts.length === 0) {-->
|
||||||
|
<!-- const row = tableBody.insertRow();-->
|
||||||
|
<!-- const cell = row.insertCell();-->
|
||||||
|
<!-- cell.textContent = "No data available";-->
|
||||||
|
<!-- cell.colSpan = 7;-->
|
||||||
|
<!-- }-->
|
||||||
|
<!-- };-->
|
||||||
|
<!--});-->
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
// Console log to confirm the script is running
|
||||||
|
console.log('Script is running');
|
||||||
|
|
||||||
|
// Function to be called when the button is clicked
|
||||||
|
function buttonClicked() {
|
||||||
|
console.log('Get Details button was clicked');
|
||||||
|
// You can place your fetchContacts logic here
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attach the event listener to the button
|
||||||
|
const getDetailsButton = document.getElementById('getDetailsButton');
|
||||||
|
if (getDetailsButton) {
|
||||||
|
getDetailsButton.addEventListener('click', buttonClicked);
|
||||||
|
} else {
|
||||||
|
console.log('Get Details button not found');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,164 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Skyonn Admin Portal</title>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
width: 20rem;
|
||||||
|
margin: auto;
|
||||||
|
border: 1px solid black;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-top: 50px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input[type="text"],
|
||||||
|
.input-group input[type="password"],
|
||||||
|
.input-group input[type="email"],
|
||||||
|
.input-group select {
|
||||||
|
width: calc(100% - 22px);
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background-color: white;
|
||||||
|
color: black;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin: 3px 0;
|
||||||
|
width: 100%;
|
||||||
|
font-size: 15px;
|
||||||
|
background-color:#66D3FA;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: black;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: -5px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-form {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-form a {
|
||||||
|
color: #3C99DC;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-text {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
color: #3C99DC;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h2>Skyonn Admin Portal</h2>
|
||||||
|
|
||||||
|
<div id="login-form">
|
||||||
|
<form id="login-form" action="{% url 'admin-login' %}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" placeholder="Phone" name="phone" required>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="password" placeholder="Password" name="password" required>
|
||||||
|
</div>
|
||||||
|
<button type="submit" name="login-form">Login</button>
|
||||||
|
</form>
|
||||||
|
<div class="toggle-form">
|
||||||
|
<p>New user? <a href="#" onclick="toggleForms('signup-form')">Sign Up</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="signup-form" style="display: none;">
|
||||||
|
<form method="post" action="{% url 'create_admin' %}" enctype="multipart/form-data">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="first_name">First Name*:</label>
|
||||||
|
<input type="text" id="first_name" name="first_name" required>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="last_name">Last Name*:</label>
|
||||||
|
<input type="text" id="last_name" name="last_name" required>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="phone">Phone no.*:</label>
|
||||||
|
<input type="text" id="phone" name="phone" required>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="phone_2">Phone no. 2:</label>
|
||||||
|
<input type="text" id="phone_2" name="phone_2">
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="company_email">Company Email*:</label>
|
||||||
|
<input type="email" id="company_email" name="company_email" required>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="personal_email">Personal Email*:</label>
|
||||||
|
<input type="email" id="personal_email" name="personal_email" required>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="address">Address*:</label>
|
||||||
|
<input type="text" id="address" name="address" required>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="work_location">Work Location*:</label>
|
||||||
|
<input type="text" id="work_location" name="work_location" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="password">Password*:</label>
|
||||||
|
<input type="password" id="password" name="password" required>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="picture">Upload Picture *</label>
|
||||||
|
<input type="file" id="picture" name="picture">
|
||||||
|
</div>
|
||||||
|
<input type="submit" value="Create Account" name="signup-form">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="toggle-form">
|
||||||
|
<p>Already have an account? <a href="#" onclick="toggleForms('login-form')">Login</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function toggleForms(formId) {
|
||||||
|
var signupForm = document.getElementById('signup-form');
|
||||||
|
var loginForm = document.getElementById('login-form');
|
||||||
|
|
||||||
|
if (formId === 'signup-form') {
|
||||||
|
signupForm.style.display = 'block';
|
||||||
|
loginForm.style.display = 'none';
|
||||||
|
} else {
|
||||||
|
signupForm.style.display = 'none';
|
||||||
|
loginForm.style.display = 'block';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,224 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||||
|
<style>
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap');
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
height: 60px;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1px solid black;
|
||||||
|
}
|
||||||
|
h2{
|
||||||
|
color: red;
|
||||||
|
margin-left: 400px ;
|
||||||
|
white-space: nowrap;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.search--notification--profile {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: calc(100% - 100px);
|
||||||
|
padding: 0 40px;
|
||||||
|
margin-left: -10px;
|
||||||
|
}
|
||||||
|
.search {
|
||||||
|
width: 300px;
|
||||||
|
padding: 5px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.search-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border: 1px solid black;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
.search input {
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
text-indent: 15px;
|
||||||
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
.search button {
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.main {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
min-height: calc(100vh - 60px);
|
||||||
|
}
|
||||||
|
.sidebar {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 250px;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
border-right: 1px solid black;
|
||||||
|
}
|
||||||
|
.sidebar.active {
|
||||||
|
width: 103px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.sidebar.active .sidebar--item {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.sidebar--items a,
|
||||||
|
.sidebar--bottom-items a {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: blue;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.sidebar--items a:hover,
|
||||||
|
.sidebar--bottom-items a:hover {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<title>Admin Dashboard</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<section class="header">
|
||||||
|
<h1 style="color: lightskyblue; margin-top: 10px; margin-left: 50px; text-decoration: underline;">Home</h1>
|
||||||
|
<h2>Admin <span>Dashboard</span></h2>
|
||||||
|
<div class="search--notification--profile">
|
||||||
|
<div class="search">
|
||||||
|
<div class="search-container">
|
||||||
|
<input type="text" placeholder="Search">
|
||||||
|
<button><i class="ri-search-2-line"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bell" style="margin-right: 40px;">
|
||||||
|
<i class="fa-solid fa-bell"></i>
|
||||||
|
</div>
|
||||||
|
<div class="profile" style="margin-right: 40px;">
|
||||||
|
<i class="fa-solid fa-user"></i>
|
||||||
|
</div>
|
||||||
|
<h3 style="margin-right: 40px;">Laxmi</h3>
|
||||||
|
<a href="#" style="margin-right: 350px; color: blue; font-size: larger; text-decoration: underline;">LogOut</a>
|
||||||
|
</section>
|
||||||
|
<section class="main">
|
||||||
|
<div class="sidebar">
|
||||||
|
<ul class="sidebar--items">
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'client-details' %}" class="sidebar-link" onclick="activateLink(this)">
|
||||||
|
<span class="sidebar--item">Client Details</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="sidebar-link" onclick="activateLink(this)">
|
||||||
|
<span class="sidebar--item">Team Details</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="sidebar-link" onclick="activateLink(this)">
|
||||||
|
<span class="sidebar--item">New Job Postings</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="sidebar-link" onclick="activateLink(this)">
|
||||||
|
<span class="sidebar--item">All Jobs Postings</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="sidebar-link" onclick="activateLink(this)">
|
||||||
|
<span class="sidebar--item">Messages</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="sidebar-link" onclick="activateLink(this)">
|
||||||
|
<span class="sidebar--item">Pending Process</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="sidebar-link" onclick="activateLink(this)">
|
||||||
|
<span class="sidebar--item">Submitted Resumes</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="sidebar-link" onclick="activateLink(this)">
|
||||||
|
<span class="sidebar--item">Add a New SPOC</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="sidebar-link" onclick="activateLink(this)">
|
||||||
|
<span class="sidebar--item">Client Details</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#" class="sidebar-link" onclick="activateLink(this)">
|
||||||
|
<span class="sidebar--item">Activity Report</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div id="clientDetailsContainer" style="display: none;">
|
||||||
|
<ul>
|
||||||
|
<div class="nav">
|
||||||
|
<li><a href="#" class="btn" onclick="loadPage('Admin_client2.html')">Client Details:</a></li>
|
||||||
|
<li><a href="#" class="btn" onclick="loadPage('Existing_client.html')">Existing Client</a></li>
|
||||||
|
<li><a href="#" class="btn" onclick="loadPage('Admin_client.html')">Add New Client</a></li>
|
||||||
|
<li><a href="#" class="btn" onclick="loadPage('page4.html')">Add Sub Clients/Locations</a></li>
|
||||||
|
</div>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<iframe id="contentFrame" style="width: 100%; height: 80vh; border: none; display: none;"></iframe>
|
||||||
|
<script>
|
||||||
|
function loadPage(pageName) {
|
||||||
|
var iframe = document.getElementById('contentFrame');
|
||||||
|
iframe.src = pageName;
|
||||||
|
iframe.style.display = 'block'; // Show the iframe
|
||||||
|
}
|
||||||
|
function activateLink(link) {
|
||||||
|
var links = document.querySelectorAll('.sidebar-link');
|
||||||
|
links.forEach(function(item) {
|
||||||
|
item.classList.remove('active');
|
||||||
|
});
|
||||||
|
link.classList.add('active');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</section>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,218 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Sign Up Page</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
width: 45rem;
|
||||||
|
margin: auto;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.two-col {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
.two-col .col1,
|
||||||
|
.two-col .col2 {
|
||||||
|
flex: 0 0 48%;
|
||||||
|
}
|
||||||
|
.two-col .col1 label,
|
||||||
|
.two-col .col2 label {
|
||||||
|
display: block;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.two-col .col1 .form-group,
|
||||||
|
.two-col .col2 .form-group {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
.two-col .col1 input,
|
||||||
|
.two-col .col2 input,
|
||||||
|
.two-col .col1 select,
|
||||||
|
.two-col .col2 select {
|
||||||
|
width: 80%;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
button[type="submit"] {
|
||||||
|
background-color: #66D3FA;
|
||||||
|
color: black;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 20%;
|
||||||
|
margin-left: 300px;
|
||||||
|
}
|
||||||
|
.add input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 25px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
label.required::after {
|
||||||
|
content: "*";
|
||||||
|
color: red;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
h1{
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.p1 {
|
||||||
|
text-align: left;
|
||||||
|
margin-top: 20px;
|
||||||
|
color: green
|
||||||
|
}
|
||||||
|
.p2 {
|
||||||
|
text-align: right;
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-top: 60px;
|
||||||
|
}
|
||||||
|
#Address {
|
||||||
|
width: 83%;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>Add Recruiter</h1>
|
||||||
|
<div id="responseMessage"></div>
|
||||||
|
<form id="addRecruiterForm" method="post" action="{% url 'create_recruiter' %}" enctype="multipart/form-data">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="two-col">
|
||||||
|
<div class="col1">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="firstName" class="required">First Name:</label>
|
||||||
|
<input type="text" id="firstName" name="first_name" required placeholder="">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="lastName" class="required">Last Name:</label>
|
||||||
|
<input type="text" id="lastName" name="last_name" required placeholder="">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password">Password*:</label>
|
||||||
|
<input type="password" id="password" name="password" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="companyEmail" class="required">Company Email:</label>
|
||||||
|
<input type="email" id="companyEmail" name="company_email" required placeholder="">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="workLocation" class="required">Work Location:</label>
|
||||||
|
<input type="text" id="workLocation" name="work_location" required placeholder="">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="picture" class="required">Upload File:</label>
|
||||||
|
<input type="file" id="picture" name="picture" accept="image/*" required placeholder="">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<input type="hidden" name="manager_assigned" value="{{ user_id }}">
|
||||||
|
<div class="col2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="PhoneNo" class="required">Phone No:</label>
|
||||||
|
<input type="number" id="PhoneNo" name="phone" required placeholder="">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="PhoneNo2">Phone No 2:</label>
|
||||||
|
<input type="number" id="PhoneNo2" name="phone_2" required placeholder="">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="email" class="required">Personal Email:</label>
|
||||||
|
<input type="email" id="email" name="personal_email" required placeholder="">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="add">
|
||||||
|
<label for="Address" class="required" style="border-radius: 50px;">Address:</label>
|
||||||
|
<textarea id="Address" rows="2" cols="30" name="address" required style="margin-left:5px; height: 70px; padding: 5px;" ></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="button" onclick="saveRecruiter()" style="border-radius: 5px; background-color:lightgreen; width: 70px; margin-top: -20px; padding: 5px;"> Save</button> </form>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<p class="p1" style="margin-left: 380px;">Skyonn Requirements and Submission Portal</p>
|
||||||
|
<p class="p2" style="margin-right: 100px; margin-top: 20px;">Powered by Skyonn Careers</p>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const form = document.getElementById('addRecruiterForm');
|
||||||
|
form.addEventListener('submit', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const formData = new FormData(this);
|
||||||
|
|
||||||
|
fetch(form.action, {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData,
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
document.getElementById('responseMessage').innerText = data.message;
|
||||||
|
if (data.success) {
|
||||||
|
form.reset(); // Reset the form fields
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
document.getElementById('responseMessage').innerText = 'An error occurred. Please try again.';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function saveRecruiter() {
|
||||||
|
const form = document.getElementById('addRecruiterForm');
|
||||||
|
const formData = new FormData(form);
|
||||||
|
// Ensure this retrieves the correct URL
|
||||||
|
const url = form.getAttribute('action');
|
||||||
|
console.log('CSRF Token:', '{{ csrf_token }}');
|
||||||
|
console.log('Form action URL:', url);
|
||||||
|
|
||||||
|
fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData,
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': '{{ csrf_token }}', // Assuming you have CSRF token available
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
console.log('Success:', data);
|
||||||
|
alert('Client saved successfully.');
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
alert('An error occurred while saving the job posting.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,140 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Job/Project Table</title>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
width: 75%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-left:330px;
|
||||||
|
}
|
||||||
|
th, td {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
padding: 8px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
background-color: #F2F2F2;
|
||||||
|
}
|
||||||
|
tr:nth-child(even) {
|
||||||
|
background-color: #F2F2F2;
|
||||||
|
}
|
||||||
|
a{
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.search-container {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.search-container input[type="text"] {
|
||||||
|
border-radius: 5px;
|
||||||
|
height: 20px;
|
||||||
|
width: 250px; /* Adjusted width */
|
||||||
|
padding-left: 30px; /* Space for the search icon */
|
||||||
|
}
|
||||||
|
.search-container .fa-magnifying-glass {
|
||||||
|
position: absolute;
|
||||||
|
left: 10px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
.head{
|
||||||
|
margin-left: 330px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div style="position: relative;">
|
||||||
|
<div class="head">
|
||||||
|
<h2 style="display: inline-block; margin-right: 10px;">All Job Posting:</h2>
|
||||||
|
<div class="search" style="display: inline-block;">
|
||||||
|
<div class="search-container">
|
||||||
|
<i class="fa-solid fa-magnifying-glass" style="position: absolute; left: 210px; top: 58%; transform: translateY(-50%); color: black;"></i>
|
||||||
|
<input type="text" placeholder="Search by JobId/SPOC/Client" style=" height: 20px; width: 130%; height: 30px;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Client</th>
|
||||||
|
<th>JobId</th>
|
||||||
|
<th>Subject</th>
|
||||||
|
<th>SPOC</th>
|
||||||
|
<th>Start Date</th>
|
||||||
|
<th>End Date</th>
|
||||||
|
<th>Location</th>
|
||||||
|
<th>Openings</th>
|
||||||
|
<th>Budget</th>
|
||||||
|
<th>Comments</th>
|
||||||
|
</tr>
|
||||||
|
{% for posting in job_postings %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ posting.client }}</td>
|
||||||
|
<td><a href="#">{{ posting.job_id }}</a></td>
|
||||||
|
|
||||||
|
<td>{{ posting.job_description }}</td>
|
||||||
|
<td>{{ posting.spoc }}</td>
|
||||||
|
<td>{{ posting.start_date }}</td>
|
||||||
|
<td>{{ posting.close_date }}</td>
|
||||||
|
<td>{{ posting.location }}</td>
|
||||||
|
<td>{{ posting.no_of_posting }}</td>
|
||||||
|
<td>{{ posting.budget_max }} to {{ posting.budget_max }}</td>
|
||||||
|
<td>{{ posting.special_instructions }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const searchInput = document.querySelector("input[type='text']");
|
||||||
|
searchInput.addEventListener("input", debounce(function() {
|
||||||
|
const query = this.value.trim();
|
||||||
|
|
||||||
|
// Modify the URL in the address bar without reloading the page
|
||||||
|
const newUrl = `${window.location.origin}${window.location.pathname}?query=${encodeURIComponent(query)}`;
|
||||||
|
history.pushState({ path: newUrl }, '', newUrl);
|
||||||
|
|
||||||
|
fetch(`./?query=${encodeURIComponent(query)}`) // Adjusted to relative path
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(html => {
|
||||||
|
const parser = new DOMParser();
|
||||||
|
const doc = parser.parseFromString(html, "text/html");
|
||||||
|
const newBody = doc.querySelector("tbody");
|
||||||
|
const oldBody = document.querySelector("table tbody");
|
||||||
|
if (oldBody && newBody) {
|
||||||
|
oldBody.parentNode.replaceChild(newBody, oldBody);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => console.error('Error fetching filtered job postings:', error));
|
||||||
|
}, 500));
|
||||||
|
});
|
||||||
|
|
||||||
|
function debounce(func, wait, immediate) {
|
||||||
|
var timeout;
|
||||||
|
return function() {
|
||||||
|
var context = this, args = arguments;
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(function() {
|
||||||
|
timeout = null;
|
||||||
|
if (!immediate) func.apply(context, args);
|
||||||
|
}, wait);
|
||||||
|
if (immediate && !timeout) func.apply(context, args);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,307 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||||
|
<style>
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap');
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
height: 60px;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 2px solid #F1F1F1;
|
||||||
|
}
|
||||||
|
.logo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 300px;
|
||||||
|
padding-left: 40px;
|
||||||
|
}
|
||||||
|
.logo span {
|
||||||
|
color: #5073FB;
|
||||||
|
}
|
||||||
|
.search--notification--profile {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: calc(100% - 300px);
|
||||||
|
padding: 0 40px;
|
||||||
|
}
|
||||||
|
.search {
|
||||||
|
background-color: #F1F4F8;
|
||||||
|
border-radius: 50px;
|
||||||
|
width: 400px;
|
||||||
|
padding: 5px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.search input {
|
||||||
|
background-color: transparent;
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
text-indent: 15px;
|
||||||
|
width: 85%;
|
||||||
|
}
|
||||||
|
.search button {
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 8px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.search button i {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #5073FB;
|
||||||
|
}
|
||||||
|
.notification--profile {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.picon {
|
||||||
|
margin-left: 20px;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
.lock {
|
||||||
|
color: #5073FB;
|
||||||
|
background-color: rgba(80, 115, 251, .2);
|
||||||
|
}
|
||||||
|
.bell {
|
||||||
|
color: #F1D243;
|
||||||
|
background-color: rgba(241, 210, 67, .2);
|
||||||
|
}
|
||||||
|
.chat {
|
||||||
|
color: #70D7A5;
|
||||||
|
background-color: rgba(112, 215, 165, .2);
|
||||||
|
}
|
||||||
|
.profile {
|
||||||
|
position: relative;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.main {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
min-height: calc(100vh - 60px);
|
||||||
|
}
|
||||||
|
.sidebar {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 300px;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
border-right: 2px solid #F1F1F1;
|
||||||
|
transition: .3s;
|
||||||
|
}
|
||||||
|
.sidebar.active {
|
||||||
|
width: 103px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.sidebar.active .sidebar--item {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.sidebar--items a,
|
||||||
|
.sidebar--bottom-items a {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #000;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.sidebar--items a:hover,
|
||||||
|
.sidebar--bottom-items a:hover {
|
||||||
|
background-color: #5073FB;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
#active--link {
|
||||||
|
background-color: #5073FB;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.sidebar--bottom-items li:last-child a {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 20px;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
}
|
||||||
|
.icon-0 {
|
||||||
|
color: #5073FB;
|
||||||
|
}
|
||||||
|
.icon-1 {
|
||||||
|
color: #C5BC58;
|
||||||
|
}
|
||||||
|
.icon-2 {
|
||||||
|
color: #A280E9;
|
||||||
|
}
|
||||||
|
.icon-3 {
|
||||||
|
color: #85ADE3;
|
||||||
|
}
|
||||||
|
.icon-4 {
|
||||||
|
color: #E36AC8;
|
||||||
|
}
|
||||||
|
.icon-5 {
|
||||||
|
color: #70D7A5;
|
||||||
|
}
|
||||||
|
.icon-6 {
|
||||||
|
color: #5F5CE0;
|
||||||
|
}
|
||||||
|
.icon-7 {
|
||||||
|
color: #E86786;
|
||||||
|
}
|
||||||
|
.icon-8 {
|
||||||
|
color: #F1D243;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<title>Dashboard</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<section class="header">
|
||||||
|
<div class="logo">
|
||||||
|
<i class="ri-menu-line icon icon-0 menu"></i>
|
||||||
|
<h2>{{ first_name }} Dashboard</h2>
|
||||||
|
</div>
|
||||||
|
<div class="search--notification--profile">
|
||||||
|
<div class="search">
|
||||||
|
<input type="text" placeholder="Search">
|
||||||
|
<button><i class="ri-search-2-line"></i></button>
|
||||||
|
</div>
|
||||||
|
<div class="notification--profile">
|
||||||
|
<div class="picon bell">
|
||||||
|
<i class="ri-notification-2-line"></i>
|
||||||
|
</div>
|
||||||
|
<div class="picon chat">
|
||||||
|
<i class="ri-wechat-2-line"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="main">
|
||||||
|
<div class="sidebar">
|
||||||
|
<ul class="sidebar--items">
|
||||||
|
<li>
|
||||||
|
<a href="#" id="active--link">
|
||||||
|
<span class="icon icon-0"><i class="fas fa-tachometer-alt"></i></span>
|
||||||
|
<span class="sidebar--item">Dashboard</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#">
|
||||||
|
<span class="icon icon-3"><i class="far fa-calendar-alt"></i></span>
|
||||||
|
<span class="sidebar--item" style="white-space: nowrap;">New Jobs Postings</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#">
|
||||||
|
<span class="icon icon-4"><i class="fa-solid fa-address-card"></i></span>
|
||||||
|
<span class="sidebar--item"> Add Recruiter</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#">
|
||||||
|
<span class="icon icon-4"><i class="fa-solid fa-person"></i></span>
|
||||||
|
<span class="sidebar--item">Recruiter List</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#">
|
||||||
|
<span class="icon icon-2"><i class="far fa-calendar-alt"></i></span>
|
||||||
|
<span class="sidebar--item">All Jobs Postings</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#">
|
||||||
|
<span class="icon icon-4"><i class="fas fa-envelope"></i></span>
|
||||||
|
<span class="sidebar--item">Messages</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#">
|
||||||
|
<span class="icon icon-4"><i class="fa-regular fa-clock"></i></span>
|
||||||
|
<span class="sidebar--item">Pending Process</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#">
|
||||||
|
<span class="icon icon-5"><i class="fa fa-paper-plane"></i></span>
|
||||||
|
<span class="sidebar--item">Submitted Resumes</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#">
|
||||||
|
<span class="icon icon-6"><i class="fa-solid fa-person"></i></span>
|
||||||
|
<span class="sidebar--item">Client Details</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#">
|
||||||
|
<span class="icon icon-6"><i class="fas fa-chart-bar"></i></span>
|
||||||
|
<span class="sidebar--item">Activity Report</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="sidebar--bottom-items">
|
||||||
|
<li>
|
||||||
|
<a href="#">
|
||||||
|
<span class="icon icon-7"><i class="fas fa-cog"></i></span>
|
||||||
|
<span class="sidebar--item">Settings</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'logout' %}">
|
||||||
|
<span class="icon icon-8"><i class="fas fa-sign-out-alt"></i></span>
|
||||||
|
<span class="sidebar--item">Logout</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<script>
|
||||||
|
let menu = document.querySelector('.menu')
|
||||||
|
let sidebar = document.querySelector('.sidebar')
|
||||||
|
let mainContent = document.querySelector('.main--content')
|
||||||
|
menu.onclick = function() {
|
||||||
|
sidebar.classList.toggle('active')
|
||||||
|
mainContent.classList.toggle('active')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,170 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Skyonn Recruiting Portal</title>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
width: 20rem;
|
||||||
|
margin: auto;
|
||||||
|
border: 1px solid black;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
margin-top: 50px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group input[type="text"],
|
||||||
|
.input-group input[type="password"],
|
||||||
|
.input-group input[type="email"],
|
||||||
|
.input-group select {
|
||||||
|
width: calc(100% - 22px);
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
background-color: white;
|
||||||
|
color: black;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin: 3px 0;
|
||||||
|
width: 100%;
|
||||||
|
font-size: 15px;
|
||||||
|
background-color:#66D3FA;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: black;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: -5px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-form {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toggle-form a {
|
||||||
|
color: #3C99DC;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-text {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
color: #3C99DC;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h2>Skyonn Recruiting Portal</h2>
|
||||||
|
|
||||||
|
<div id="login-form">
|
||||||
|
<form id="login-form" action="{% url 'user_login' %}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="text" placeholder="Phone" name="phone" required>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<input type="password" placeholder="Password" name="password" required>
|
||||||
|
</div>
|
||||||
|
<button type="submit" name="login-form">Login</button>
|
||||||
|
</form>
|
||||||
|
<div class="toggle-form">
|
||||||
|
<p>New user? <a href="#" onclick="toggleForms('signup-form')">Sign Up</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="signup-form" style="display: none;">
|
||||||
|
<form method="post" action="{% url 'create_user' %}" enctype="multipart/form-data">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="first_name">First Name*:</label>
|
||||||
|
<input type="text" id="first_name" name="first_name" required>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="last_name">Last Name*:</label>
|
||||||
|
<input type="text" id="last_name" name="last_name" required>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="phone">Phone no.*:</label>
|
||||||
|
<input type="text" id="phone" name="phone" required>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="phone_2">Phone no. 2:</label>
|
||||||
|
<input type="text" id="phone_2" name="phone_2">
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="company_email">Company Email*:</label>
|
||||||
|
<input type="email" id="company_email" name="company_email" required>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="personal_email">Personal Email*:</label>
|
||||||
|
<input type="email" id="personal_email" name="personal_email" required>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="address">Address*:</label>
|
||||||
|
<input type="text" id="address" name="address" required>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="work_location">Work Location*:</label>
|
||||||
|
<input type="text" id="work_location" name="work_location" required>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="role">Role*:</label>
|
||||||
|
<select id="role" name="role" required>
|
||||||
|
<option value="recruiter">Recruiter</option>
|
||||||
|
<option value="manager">Manager</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="password">Password*:</label>
|
||||||
|
<input type="password" id="password" name="password" required>
|
||||||
|
</div>
|
||||||
|
<div class="input-group">
|
||||||
|
<label for="picture">Upload Picture *</label>
|
||||||
|
<input type="file" id="picture" name="picture">
|
||||||
|
</div>
|
||||||
|
<input type="submit" value="Create Account" name="signup-form">
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="toggle-form">
|
||||||
|
<p>Already have an account? <a href="#" onclick="toggleForms('login-form')">Login</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function toggleForms(formId) {
|
||||||
|
var signupForm = document.getElementById('signup-form');
|
||||||
|
var loginForm = document.getElementById('login-form');
|
||||||
|
|
||||||
|
if (formId === 'signup-form') {
|
||||||
|
signupForm.style.display = 'block';
|
||||||
|
loginForm.style.display = 'none';
|
||||||
|
} else {
|
||||||
|
signupForm.style.display = 'none';
|
||||||
|
loginForm.style.display = 'block';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,280 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>New Job Posting</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
width: 55rem;
|
||||||
|
margin: auto;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.three-col {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 0;
|
||||||
|
}
|
||||||
|
.three-col .col1,
|
||||||
|
.three-col .col2,
|
||||||
|
.three-col .col3,
|
||||||
|
.three-col .col4 {
|
||||||
|
flex: 0 0 22%;
|
||||||
|
}
|
||||||
|
.three-col .form-group {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
.three-col input,
|
||||||
|
.three-col select {
|
||||||
|
width: calc(100% - 30px);
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
label.required::after {
|
||||||
|
content: "*";
|
||||||
|
color: red;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
margin-left: 180px;
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
#JobDescription {
|
||||||
|
width:380%;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 15px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
height: 70px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
#SpecialInstructions {
|
||||||
|
width:380%;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 5px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
#popup {
|
||||||
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
#popup-content {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
background-color: white;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.col4 .form-group {
|
||||||
|
margin-top: 165px;
|
||||||
|
margin-left: -40px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>New Job Posting</h1>
|
||||||
|
<form id="jobPostingForm" action="{% url 'save_job_posting' %}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="JD" class="required">Upload JD:</label>
|
||||||
|
<input type="file" id="JD" name="JD" required accept=".pdf,.doc,.docx">
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="three-col">
|
||||||
|
<div class="col1">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Client" class="required">Client:</label>
|
||||||
|
<select id="Client" name="Client" required style="width: 90%;" tabindex="1">
|
||||||
|
<option value="">Select Client</option>
|
||||||
|
{% for client in clients %}
|
||||||
|
<option value="{{ client.parent_company }}">{{ client.parent_company }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="SPOC">SPOC:</label>
|
||||||
|
<select id="SPOC" name="SPOC" style="width: 90%;" tabindex="4">
|
||||||
|
<option value="" >Select SPOC</option>
|
||||||
|
<option value="spoc1">SPOC 1</option>
|
||||||
|
<option value="spoc2">SPOC 2</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="StartDate" class="required">Start Date:</label>
|
||||||
|
<!-- <input type="date" id="StartDate" name="StartDate" required placeholder="" style="width: 80%;">-->
|
||||||
|
<input type="date" id="StartDate" name="StartDate" required tabindex="7">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="BudgetMin" class="required">Budget Min Rs:</label>
|
||||||
|
<input type="number" id="BudgetMin" name="BudgetMin" required placeholder="" style="width: 80%;" tabindex="11">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="JobDescription" class="required">Job Description:</label>
|
||||||
|
<textarea id="JobDescription" name="JobDescription" required placeholder="" style="margin-top: -0px;" tabindex="14"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="SpecialInstructions" style="white-space: nowrap;">Special Instructions If any:</label>
|
||||||
|
<input type="text" id="SpecialInstructions" name="SpecialInstructions" placeholder="" style="width: 380%;" tabindex="15">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col2">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="JobID" class="required" style="margin-left: -10px; " >Job ID:</label>
|
||||||
|
<input type="text" id="JobID" name="JobID" required placeholder="" style="width: 90%; margin-left: -10px;" tabindex="2">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="SPOC 2" style="margin-left: 10px;">SPOC 2:</label>
|
||||||
|
<select id="SPOC 2" name="SPOC2" style="width: 90%;" tabindex="5">
|
||||||
|
<option value="">Select SPOC 2</option>
|
||||||
|
<option value="spoc1">SPOC 1</option>
|
||||||
|
<option value="spoc2">SPOC 2</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="CloseDate" class="required" >Close Date:</label>
|
||||||
|
<!-- <input type="date" id="CloseDate" name="CloseDate" required placeholder="" style="width: 85%;">-->
|
||||||
|
<input type="date" id="CloseDate" name="CloseDate" required tabindex="8">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="BudgetMax" class="required">Budget Max Rs:</label>
|
||||||
|
<input type="number" id="BudgetMax" name="BudgetMax" required placeholder="" style="width: 80%;" tabindex="12">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col3">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Location" class="required" style="margin-left: 10px;">Location:</label>
|
||||||
|
<select id="Location" name="Location" required style="width: 90%; height: 40px;" tabindex="3">
|
||||||
|
<option value="">Select State</option>
|
||||||
|
<option value="Telangana">Telangana</option>
|
||||||
|
<option value="Andhra Pradesh">Andhra Pradesh</option>
|
||||||
|
<option value="Gujarat">Gujarat</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="NoOfPosting" class="required" style="margin-left: 1px;">No of Posting:</label>
|
||||||
|
<input type="number" id="NoOfPosting" name="NoOfPosting" required placeholder="Ex. 5" style="width: 75%; margin-left: 1px;" tabindex="6">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Type" class="required">Type:</label>
|
||||||
|
<select id="Type" name="Type" required style="width: 85%;" tabindex="9">
|
||||||
|
<option value="">Select</option>
|
||||||
|
<option value="Full-Time">Full-Time</option>
|
||||||
|
<option value="Part-Time">Part-Time</option>
|
||||||
|
<option value="Contract">Contract</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Header" class="required">Header:</label>
|
||||||
|
<input type="text" id="BudgetMin" name="Header" required placeholder="Ex.oracle Technical developer" style="width: 180%;" tabindex="13">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col4">
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="Experience" class="required">Experience in Yrs:</label>
|
||||||
|
<input type="text" id="Experience" name="Experience_in_Yrs" required placeholder="" style="width:15%;" tabindex="10">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<button type="button" onclick="saveJobPosting()" style="border-radius: 5px; background-color:lightgreen; width: 70px; margin-top: -20px; padding: 5px;">Save</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div id="popup">
|
||||||
|
<div id="popup-content">
|
||||||
|
<p>Are you sure you want to save?</p>
|
||||||
|
<button onclick="saveForm()">Yes</button>
|
||||||
|
<button onclick="hidePopup()">No</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
function showPopup() {
|
||||||
|
document.getElementById('popup').style.display = 'block';
|
||||||
|
}
|
||||||
|
function hidePopup() {
|
||||||
|
document.getElementById('popup').style.display = 'none';
|
||||||
|
}
|
||||||
|
function saveForm() {
|
||||||
|
if (validateForm()) {
|
||||||
|
document.getElementById('jobPostingForm').submit();
|
||||||
|
hidePopup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function validateForm() {
|
||||||
|
var requiredFields = document.querySelectorAll('input[required], select[required], textarea[required]');
|
||||||
|
var isValid = true;
|
||||||
|
requiredFields.forEach(function(field) {
|
||||||
|
if (!field.value.trim()) {
|
||||||
|
isValid = false;
|
||||||
|
field.style.border = '2px solid red';
|
||||||
|
} else {
|
||||||
|
field.style.border = '1px solid #ccc';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!isValid) {
|
||||||
|
alert('Please fill in all required fields.');
|
||||||
|
}
|
||||||
|
return isValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveJobPosting() {
|
||||||
|
const form = document.getElementById('jobPostingForm');
|
||||||
|
const formData = new FormData(form);
|
||||||
|
// Ensure this retrieves the correct URL
|
||||||
|
const url = form.getAttribute('action');
|
||||||
|
console.log('CSRF Token:', '{{ csrf_token }}');
|
||||||
|
console.log('Form action URL:', url);
|
||||||
|
|
||||||
|
fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData,
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': '{{ csrf_token }}', // Assuming you have CSRF token available
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
console.log('Success:', data);
|
||||||
|
alert('Job posting saved successfully.');
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
alert('An error occurred while saving the job posting.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1 @@
|
|||||||
|
<h1>success</h1>
|
@ -0,0 +1,396 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||||
|
<style>
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;500;700&display=swap');
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
height: 60px;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 2px solid #F1F1F1;
|
||||||
|
}
|
||||||
|
.logo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 300px;
|
||||||
|
padding-left: 40px;
|
||||||
|
}
|
||||||
|
.logo span {
|
||||||
|
color: #5073FB;
|
||||||
|
}
|
||||||
|
.search--notification--profile {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: calc(100% - 300px);
|
||||||
|
padding: 0 40px;
|
||||||
|
}
|
||||||
|
.search {
|
||||||
|
background-color: #F1F4F8;
|
||||||
|
border-radius: 50px;
|
||||||
|
width: 400px;
|
||||||
|
padding: 5px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.search input {
|
||||||
|
background-color: transparent;
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
text-indent: 15px;
|
||||||
|
width: 85%;
|
||||||
|
}
|
||||||
|
.search button {
|
||||||
|
outline: none;
|
||||||
|
border: none;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 8px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.search button i {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #5073FB;
|
||||||
|
}
|
||||||
|
.notification--profile {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.picon {
|
||||||
|
margin-left: 20px;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
.lock {
|
||||||
|
color: #5073FB;
|
||||||
|
background-color: rgba(80, 115, 251, .2);
|
||||||
|
}
|
||||||
|
.bell {
|
||||||
|
color: #F1D243;
|
||||||
|
background-color: rgba(241, 210, 67, .2);
|
||||||
|
}
|
||||||
|
.chat {
|
||||||
|
color: #70D7A5;
|
||||||
|
background-color: rgba(112, 215, 165, .2);
|
||||||
|
}
|
||||||
|
.profile {
|
||||||
|
position: relative;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.main {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
min-height: calc(100vh - 60px);
|
||||||
|
}
|
||||||
|
.sidebar {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 300px;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
border-right: 2px solid #F1F1F1;
|
||||||
|
transition: .3s;
|
||||||
|
}
|
||||||
|
.sidebar.active {
|
||||||
|
width: 103px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.sidebar.active .sidebar--item {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.sidebar--items a,
|
||||||
|
.sidebar--bottom-items a {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
color: #000;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.sidebar--items a:hover,
|
||||||
|
.sidebar--bottom-items a:hover {
|
||||||
|
background-color: #5073FB;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
#active--link {
|
||||||
|
background-color: #5073FB;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.sidebar--bottom-items li:last-child a {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 20px;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
}
|
||||||
|
.icon-0 {
|
||||||
|
color: #5073FB;
|
||||||
|
}
|
||||||
|
.icon-1 {
|
||||||
|
color: #C5BC58;
|
||||||
|
}
|
||||||
|
.icon-2 {
|
||||||
|
color: #A280E9;
|
||||||
|
}
|
||||||
|
.icon-3 {
|
||||||
|
color: #85ADE3;
|
||||||
|
}
|
||||||
|
.icon-4 {
|
||||||
|
color: #E36AC8;
|
||||||
|
}
|
||||||
|
.icon-5 {
|
||||||
|
color: #70D7A5;
|
||||||
|
}
|
||||||
|
.icon-6 {
|
||||||
|
color: #5F5CE0;
|
||||||
|
}
|
||||||
|
.icon-7 {
|
||||||
|
color: #E86786;
|
||||||
|
}
|
||||||
|
.icon-8 {
|
||||||
|
color: #F1D243;
|
||||||
|
}
|
||||||
|
iframe#contentFrame {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
.main--content {
|
||||||
|
overflow-y: auto; /* or overflow-y: scroll; */
|
||||||
|
height: 100%; /* or a specific height */
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<title>Dashboard</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<section class="header">
|
||||||
|
<div class="logo">
|
||||||
|
<i class="ri-menu-line icon icon-0 menu"></i>
|
||||||
|
<h2>{{first_name}} <span>Dashboard</span></h2>
|
||||||
|
</div>
|
||||||
|
<div class="search--notification--profile">
|
||||||
|
<div class="search">
|
||||||
|
<input type="text" placeholder="Search">
|
||||||
|
<button><i class="ri-search-2-line"></i></button>
|
||||||
|
</div>
|
||||||
|
<div class="notification--profile">
|
||||||
|
<div class="picon bell">
|
||||||
|
<i class="ri-notification-2-line"></i>
|
||||||
|
</div>
|
||||||
|
<div class="picon chat">
|
||||||
|
<i class="ri-wechat-2-line"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="main">
|
||||||
|
<div class="sidebar">
|
||||||
|
<ul class="sidebar--items">
|
||||||
|
<li>
|
||||||
|
<a href="#" id="active--link">
|
||||||
|
<span class="icon icon-0"><i class="fas fa-tachometer-alt"></i></span>
|
||||||
|
<span class="sidebar--item">Dashboard</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li> <a href="#" class="btn" onclick="loadPage('/new_job_postings/')">
|
||||||
|
<span class="icon icon-3"><i class="fa
|
||||||
|
r fa-calendar-alt"></i></span>
|
||||||
|
<span class="sidebar--item" style="white-space: nowrap;">New Jobs Postings</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li> <a href="#" class="btn" onclick="loadPage('/add_recruiter/','{{user_id}}')">
|
||||||
|
<span class="icon icon-4"><i class="fa-solid fa-address-card"></i></span>
|
||||||
|
<span class="sidebar--item">Add Recruiter</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#">
|
||||||
|
<span class="icon icon-4"><i class="fa-solid fa-person"></i></span>
|
||||||
|
<span class="sidebar--item">Recruiter List</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'all_job_postings' %}">
|
||||||
|
<span class="icon icon-2"><i class="far fa-calendar-alt"></i></span>
|
||||||
|
<span class="sidebar--item">All Jobs Postings</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#">
|
||||||
|
<span class="icon icon-4"><i class="fas fa-envelope"></i></span>
|
||||||
|
<span class="sidebar--item">Messages</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#">
|
||||||
|
<span class="icon icon-4"><i class="fa-regular fa-clock"></i></span>
|
||||||
|
<span class="sidebar--item">Pending Process</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#">
|
||||||
|
<span class="icon icon-5"><i class="fa fa-paper-plane"></i></span>
|
||||||
|
<span class="sidebar--item">Submitted Resumes</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#">
|
||||||
|
<span class="icon icon-6"><i class="fa-solid fa-person"></i></span>
|
||||||
|
<span class="sidebar--item">Client Details</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#">
|
||||||
|
<span class="icon icon-6"><i class="fas fa-chart-bar"></i></span>
|
||||||
|
<span class="sidebar--item">Activity Report</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<ul class="sidebar--bottom-items">
|
||||||
|
<li>
|
||||||
|
<a href="#">
|
||||||
|
<span class="icon icon-7"><i class="fas fa-cog"></i></span>
|
||||||
|
<span class="sidebar--item">Settings</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{% url 'logout' %}">
|
||||||
|
<span class="icon icon-8"><i class="fas fa-sign-out-alt"></i></span>
|
||||||
|
<span class="sidebar--item">Logout</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div id="content"></div>
|
||||||
|
</section>
|
||||||
|
<script>
|
||||||
|
function loadPage(pageName, userId) {
|
||||||
|
var url = userId ? `${pageName}?user_id=${userId}` : pageName;
|
||||||
|
var xhttp = new XMLHttpRequest();
|
||||||
|
xhttp.onreadystatechange = function() {
|
||||||
|
if (this.readyState == 4 && this.status == 200) {
|
||||||
|
document.getElementById("content").innerHTML = this.responseText;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhttp.open("GET", url, true);
|
||||||
|
xhttp.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
let menu = document.querySelector('.menu');
|
||||||
|
let sidebar = document.querySelector('.sidebar');
|
||||||
|
let mainContent = document.querySelector('.main--content');
|
||||||
|
menu.onclick = function() {
|
||||||
|
sidebar.classList.toggle('active');
|
||||||
|
mainContent.classList.toggle('active');
|
||||||
|
};
|
||||||
|
function saveJobPosting() {
|
||||||
|
const form = document.getElementById('jobPostingForm');
|
||||||
|
const formData = new FormData(form);
|
||||||
|
// Ensure this retrieves the correct URL
|
||||||
|
const url = form.getAttribute('action');
|
||||||
|
console.log('CSRF Token:', '{{ csrf_token }}');
|
||||||
|
console.log('Form action URL:', url);
|
||||||
|
|
||||||
|
fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData,
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': '{{ csrf_token }}', // Assuming you have CSRF token available
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
console.log('Success:', data);
|
||||||
|
alert('Job posting saved successfully.');
|
||||||
|
form.reset();
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
alert('An error occurred while saving the job posting.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveRecruiter() {
|
||||||
|
const form = document.getElementById('addRecruiterForm');
|
||||||
|
const formData = new FormData(form);
|
||||||
|
// Ensure this retrieves the correct URL
|
||||||
|
const url = form.getAttribute('action');
|
||||||
|
console.log('CSRF Token:', '{{ csrf_token }}');
|
||||||
|
console.log('Form action URL:', url);
|
||||||
|
|
||||||
|
fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData,
|
||||||
|
headers: {
|
||||||
|
'X-CSRFToken': '{{ csrf_token }}', // Assuming you have CSRF token available
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
console.log('Success:', data);
|
||||||
|
alert('recruiter saved successfully.');
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
alert('recruiter saved successfully.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,3 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
@ -0,0 +1,6 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class UserConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'user'
|
@ -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
|
@ -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,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
@ -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()),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
@ -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),
|
||||||
|
),
|
||||||
|
]
|
@ -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),
|
||||||
|
),
|
||||||
|
]
|
@ -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']
|
@ -0,0 +1,3 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
@ -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/<str:user_id>/', 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/<int:recipient_id>/', views.send_message, name='send_message'),
|
||||||
|
path('read/<int:message_id>/', views.mark_as_read, name='mark_as_read'),
|
||||||
|
]
|
@ -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')
|