ckeditor added #9
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -5,7 +5,7 @@ from django.utils import timezone
|
||||
from .models import (
|
||||
JobPosting, Candidate, TrainingMaterial, ZoomMeeting,
|
||||
FormTemplate, FormStage, FormField, FormSubmission, FieldResponse,
|
||||
SharedFormTemplate, Source, HiringAgency, IntegrationLog,InterviewSchedule,Profile
|
||||
SharedFormTemplate, Source, HiringAgency, IntegrationLog,InterviewSchedule,Profile,JobPostingImage
|
||||
)
|
||||
|
||||
class FormFieldInline(admin.TabularInline):
|
||||
@ -263,3 +263,6 @@ admin.site.register(FieldResponse)
|
||||
admin.site.register(InterviewSchedule)
|
||||
admin.site.register(Profile)
|
||||
# admin.site.register(HiringAgency)
|
||||
|
||||
|
||||
admin.site.register(JobPostingImage)
|
||||
@ -5,7 +5,10 @@ from django.forms.formsets import formset_factory
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from crispy_forms.helper import FormHelper
|
||||
from crispy_forms.layout import Layout, Submit, Row, Column, Field, Div
|
||||
from .models import ZoomMeeting, Candidate,TrainingMaterial,JobPosting,FormTemplate,InterviewSchedule,BreakTime
|
||||
from .models import (
|
||||
ZoomMeeting, Candidate,TrainingMaterial,JobPosting,
|
||||
FormTemplate,InterviewSchedule,BreakTime,JobPostingImage
|
||||
)
|
||||
# from django_summernote.widgets import SummernoteWidget
|
||||
from django_ckeditor_5.widgets import CKEditor5Widget
|
||||
|
||||
@ -192,8 +195,8 @@ class JobPostingForm(forms.ModelForm):
|
||||
fields = [
|
||||
'title', 'department', 'job_type', 'workplace_type',
|
||||
'location_city', 'location_state', 'location_country',
|
||||
'description', 'qualifications', 'salary_range', 'benefits',
|
||||
'application_url', 'application_deadline', 'application_instructions',
|
||||
'description', 'qualifications', 'salary_range', 'benefits'
|
||||
,'application_deadline', 'application_instructions',
|
||||
'position_number', 'reporting_to', 'start_date', 'status',
|
||||
'created_by','open_positions','hash_tags'
|
||||
]
|
||||
@ -239,11 +242,11 @@ class JobPostingForm(forms.ModelForm):
|
||||
|
||||
|
||||
# Application Information
|
||||
'application_url': forms.URLInput(attrs={
|
||||
'class': 'form-control',
|
||||
'placeholder': 'https://university.edu/careers/job123',
|
||||
'required': True
|
||||
}),
|
||||
# 'application_url': forms.URLInput(attrs={
|
||||
# 'class': 'form-control',
|
||||
# 'placeholder': 'https://university.edu/careers/job123',
|
||||
# 'required': True
|
||||
# }),
|
||||
'application_deadline': forms.DateInput(attrs={
|
||||
'class': 'form-control',
|
||||
'type': 'date'
|
||||
@ -356,6 +359,10 @@ class JobPostingForm(forms.ModelForm):
|
||||
|
||||
return cleaned_data
|
||||
|
||||
class JobPostingImageForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model=JobPostingImage
|
||||
fields=['post_image']
|
||||
|
||||
class FormTemplateForm(forms.ModelForm):
|
||||
"""Form for creating form templates"""
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
# Generated by Django 5.2.6 on 2025-10-09 10:10
|
||||
# Generated by Django 5.2.7 on 2025-10-11 11:04
|
||||
|
||||
import django.core.validators
|
||||
import django.db.models.deletion
|
||||
import django_ckeditor_5.fields
|
||||
import django_countries.fields
|
||||
import django_extensions.db.fields
|
||||
import recruitment.validators
|
||||
@ -183,7 +184,7 @@ class Migration(migrations.Migration):
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('name', models.CharField(help_text='Name of the form template', max_length=200)),
|
||||
('description', models.TextField(blank=True, help_text='Description of the form template')),
|
||||
('is_active', models.BooleanField(default=True, help_text='Whether this template is active')),
|
||||
('is_active', models.BooleanField(default=False, help_text='Whether this template is active')),
|
||||
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='form_templates', to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
@ -215,6 +216,7 @@ class Migration(migrations.Migration):
|
||||
('phone', models.CharField(max_length=20, verbose_name='Phone')),
|
||||
('address', models.TextField(max_length=200, verbose_name='Address')),
|
||||
('resume', models.FileField(upload_to='resumes/', verbose_name='Resume')),
|
||||
('is_resume_parsed', models.BooleanField(default=False, verbose_name='Resume Parsed')),
|
||||
('parsed_summary', models.TextField(blank=True, verbose_name='Parsed Summary')),
|
||||
('applied', models.BooleanField(default=False, verbose_name='Applied')),
|
||||
('stage', models.CharField(choices=[('Applied', 'Applied'), ('Exam', 'Exam'), ('Interview', 'Interview'), ('Offer', 'Offer')], default='Applied', max_length=100, verbose_name='Stage')),
|
||||
@ -249,16 +251,16 @@ class Migration(migrations.Migration):
|
||||
('location_city', models.CharField(blank=True, max_length=100)),
|
||||
('location_state', models.CharField(blank=True, max_length=100)),
|
||||
('location_country', models.CharField(default='Saudia Arabia', max_length=100)),
|
||||
('description', models.TextField(help_text='Full job description including responsibilities and requirements')),
|
||||
('qualifications', models.TextField(blank=True, help_text='Required qualifications and skills')),
|
||||
('description', django_ckeditor_5.fields.CKEditor5Field(verbose_name='Description')),
|
||||
('qualifications', django_ckeditor_5.fields.CKEditor5Field(blank=True, null=True)),
|
||||
('salary_range', models.CharField(blank=True, help_text='e.g., $60,000 - $80,000', max_length=200)),
|
||||
('benefits', models.TextField(blank=True, help_text='Benefits offered')),
|
||||
('benefits', django_ckeditor_5.fields.CKEditor5Field(blank=True, null=True)),
|
||||
('application_url', models.URLField(blank=True, help_text='URL where candidates apply', null=True, validators=[django.core.validators.URLValidator()])),
|
||||
('application_deadline', models.DateField(blank=True, null=True)),
|
||||
('application_instructions', models.TextField(blank=True, help_text='Special instructions for applicants')),
|
||||
('application_instructions', django_ckeditor_5.fields.CKEditor5Field(blank=True, null=True)),
|
||||
('internal_job_id', models.CharField(editable=False, max_length=50, primary_key=True, serialize=False)),
|
||||
('created_by', models.CharField(blank=True, help_text='Name of person who created this job', max_length=100)),
|
||||
('status', models.CharField(blank=True, choices=[('DRAFT', 'Draft'), ('PUBLISHED', 'Published'), ('CLOSED', 'Closed'), ('ARCHIVED', 'Archived')], default='DRAFT', max_length=20, null=True)),
|
||||
('status', models.CharField(blank=True, choices=[('DRAFT', 'Draft'), ('ACTIVE', 'Active'), ('CLOSED', 'Closed'), ('CANCELLED', 'Cancelled'), ('ARCHIVED', 'Archived')], default='DRAFT', max_length=20, null=True)),
|
||||
('hash_tags', models.CharField(blank=True, help_text='Comma-separated hashtags for linkedin post like #hiring,#jobopening', max_length=200, validators=[recruitment.validators.validate_hash_tags])),
|
||||
('linkedin_post_id', models.CharField(blank=True, help_text='LinkedIn post ID after posting', max_length=200)),
|
||||
('linkedin_post_url', models.URLField(blank=True, help_text='Direct URL to LinkedIn post')),
|
||||
@ -270,6 +272,9 @@ class Migration(migrations.Migration):
|
||||
('reporting_to', models.CharField(blank=True, help_text='Who this position reports to', max_length=100)),
|
||||
('start_date', models.DateField(blank=True, help_text='Desired start date', null=True)),
|
||||
('open_positions', models.PositiveIntegerField(default=1, help_text='Number of open positions for this job')),
|
||||
('cancel_reason', models.TextField(blank=True, help_text='Reason for canceling the job posting', verbose_name='Cancel Reason')),
|
||||
('cancelled_by', models.CharField(blank=True, help_text='Name of person who cancelled this job', max_length=100, verbose_name='Cancelled By')),
|
||||
('cancelled_at', models.DateTimeField(blank=True, null=True)),
|
||||
('hiring_agency', models.ManyToManyField(blank=True, help_text='External agency responsible for sourcing candidates for this role', related_name='jobs', to='recruitment.hiringagency', verbose_name='Hiring Agency')),
|
||||
('source', models.ForeignKey(blank=True, help_text='The system or channel from which this job posting originated or was first published.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='job_postings', to='recruitment.source')),
|
||||
],
|
||||
@ -312,6 +317,16 @@ class Migration(migrations.Migration):
|
||||
name='job',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='candidates', to='recruitment.jobposting', verbose_name='Job'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='JobPostingImage',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('post_image', models.ImageField(height_field='photo_height', upload_to='post/', width_field='photo_width')),
|
||||
('post_image_height', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('post_image_width', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('job', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='post_images', to='recruitment.jobposting')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Profile',
|
||||
fields=[
|
||||
@ -369,7 +384,7 @@ class Migration(migrations.Migration):
|
||||
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')),
|
||||
('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')),
|
||||
('title', models.CharField(max_length=255, verbose_name='Title')),
|
||||
('content', models.TextField(blank=True, verbose_name='Content')),
|
||||
('content', django_ckeditor_5.fields.CKEditor5Field(blank=True, verbose_name='Content')),
|
||||
('video_link', models.URLField(blank=True, verbose_name='Video Link')),
|
||||
('file', models.FileField(blank=True, upload_to='training_materials/', verbose_name='File')),
|
||||
('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Created by')),
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
# Generated by Django 5.2.6 on 2025-10-09 10:33
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('recruitment', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='jobposting',
|
||||
name='cancel_reason',
|
||||
field=models.TextField(blank=True, help_text='Reason for canceling the job posting', verbose_name='Cancel Reason'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='jobposting',
|
||||
name='cancelled_at',
|
||||
field=models.DateTimeField(blank=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='jobposting',
|
||||
name='cancelled_by',
|
||||
field=models.CharField(blank=True, help_text='Name of person who cancelled this job', max_length=100, verbose_name='Cancelled By'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='jobposting',
|
||||
name='status',
|
||||
field=models.CharField(blank=True, choices=[('DRAFT', 'Draft'), ('ACTIVE', 'Active'), ('CLOSED', 'Closed'), ('CANCELLED', 'Cancelled'), ('ARCHIVED', 'Archived')], default='DRAFT', max_length=20, null=True),
|
||||
),
|
||||
]
|
||||
@ -0,0 +1,26 @@
|
||||
# Generated by Django 5.2.7 on 2025-10-11 12:38
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('recruitment', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='jobpostingimage',
|
||||
name='post_image_height',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='jobpostingimage',
|
||||
name='post_image_width',
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='jobpostingimage',
|
||||
name='post_image',
|
||||
field=models.ImageField(upload_to='post/'),
|
||||
),
|
||||
]
|
||||
@ -1,23 +0,0 @@
|
||||
# Generated by Django 5.2.6 on 2025-10-09 12:59
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('recruitment', '0002_jobposting_cancel_reason_jobposting_cancelled_at_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='candidate',
|
||||
name='is_resume_parsed',
|
||||
field=models.BooleanField(default=False, verbose_name='Resume Parsed'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='formtemplate',
|
||||
name='is_active',
|
||||
field=models.BooleanField(default=False, help_text='Whether this template is active'),
|
||||
),
|
||||
]
|
||||
@ -1,30 +0,0 @@
|
||||
# Generated by Django 5.2.7 on 2025-10-10 10:35
|
||||
|
||||
import django.db.models.deletion
|
||||
import django_ckeditor_5.fields
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('recruitment', '0003_candidate_is_resume_parsed_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='jobposting',
|
||||
name='description',
|
||||
field=django_ckeditor_5.fields.CKEditor5Field(help_text='Full job description including responsibilities and requirements'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='JobPostingImage',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('post_image', models.ImageField(height_field='photo_height', upload_to='post/', width_field='photo_width')),
|
||||
('post_image_height', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('post_image_width', models.PositiveIntegerField(blank=True, null=True)),
|
||||
('job', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='post_images', to='recruitment.jobposting')),
|
||||
],
|
||||
),
|
||||
]
|
||||
@ -1,19 +0,0 @@
|
||||
# Generated by Django 5.2.7 on 2025-10-10 10:56
|
||||
|
||||
import django_ckeditor_5.fields
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('recruitment', '0004_alter_jobposting_description_jobpostingimage'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='jobposting',
|
||||
name='description',
|
||||
field=django_ckeditor_5.fields.CKEditor5Field(verbose_name='Description'),
|
||||
),
|
||||
]
|
||||
@ -1,19 +0,0 @@
|
||||
# Generated by Django 5.2.7 on 2025-10-10 11:10
|
||||
|
||||
import django_ckeditor_5.fields
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('recruitment', '0005_alter_jobposting_description'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='jobposting',
|
||||
name='qualifications',
|
||||
field=django_ckeditor_5.fields.CKEditor5Field(blank=True, help_text='Required qualifications and skills'),
|
||||
),
|
||||
]
|
||||
@ -91,7 +91,7 @@ class JobPosting(Base):
|
||||
)
|
||||
benefits = CKEditor5Field(blank=True,null=True,config_name='extends')
|
||||
|
||||
# Application Information
|
||||
# Application Information ---job detail apply link for the candidates
|
||||
application_url = models.URLField(
|
||||
validators=[URLValidator()],
|
||||
help_text="URL where candidates apply",
|
||||
@ -249,11 +249,8 @@ class JobPosting(Base):
|
||||
|
||||
class JobPostingImage(models.Model):
|
||||
job=models.ForeignKey('JobPosting',on_delete=models.CASCADE,related_name='post_images')
|
||||
post_image = models.ImageField(upload_to='post/',
|
||||
height_field='photo_height',
|
||||
width_field='photo_width')
|
||||
post_image_height = models.PositiveIntegerField(null=True, blank=True)
|
||||
post_image_width = models.PositiveIntegerField(null=True, blank=True)
|
||||
post_image = models.ImageField(upload_to='post/')
|
||||
|
||||
|
||||
class Candidate(Base):
|
||||
class Stage(models.TextChoices):
|
||||
@ -409,6 +406,7 @@ class Candidate(Base):
|
||||
return self.STAGE_SEQUENCE.get(old_stage, [])
|
||||
|
||||
@property
|
||||
|
||||
def submission(self):
|
||||
return FormSubmission.objects.filter(template__job=self.job).first()
|
||||
@property
|
||||
|
||||
@ -9,6 +9,7 @@ urlpatterns = [
|
||||
# Job URLs (using JobPosting model)
|
||||
path('jobs/', views_frontend.JobListView.as_view(), name='job_list'),
|
||||
path('jobs/create/', views.create_job, name='job_create'),
|
||||
path('job/<slug:slug>/upload_image_simple/', views.job_image_upload, name='job_image_upload'),
|
||||
path('jobs/<slug:slug>/update/', views.edit_job, name='job_update'),
|
||||
# path('jobs/<slug:slug>/delete/', views., name='job_delete'),
|
||||
path('jobs/<slug:slug>/', views.job_detail, name='job_detail'),
|
||||
@ -66,7 +67,7 @@ urlpatterns = [
|
||||
|
||||
# path('forms/form/<int:template_id>/submit/', views.submit_form, name='submit_form'),
|
||||
# path('forms/form/<int:template_id>/', views.form_wizard_view, name='form_wizard'),
|
||||
path('forms/<int:form_id>/submissions/<int:slug>/', views.form_submission_details, name='form_submission_details'),
|
||||
path('forms/<int:form_id>/submissions/<int:submission_id>/', views.form_submission_details, name='form_submission_details'),
|
||||
path('forms/template/<slug:slug>/submissions/', views.form_template_submissions_list, name='form_template_submissions_list'),
|
||||
|
||||
# path('forms/<int:form_id>/', views.form_preview, name='form_preview'),
|
||||
|
||||
@ -17,6 +17,7 @@ from .forms import (
|
||||
FormTemplateForm,
|
||||
InterviewScheduleForm,JobPostingStatusForm,
|
||||
BreakTimeFormSet,
|
||||
JobPostingImageForm
|
||||
)
|
||||
from rest_framework import viewsets
|
||||
from django.contrib import messages
|
||||
@ -215,6 +216,11 @@ def create_job(request):
|
||||
job.created_by = request.POST.get("created_by", "").strip()
|
||||
if not job.created_by:
|
||||
job.created_by = "University Administrator"
|
||||
|
||||
job.save()
|
||||
job_apply_url_relative=reverse('job_detail_candidate',kwargs={'slug':job.slug})
|
||||
job_apply_url_absolute=request.build_absolute_uri(job_apply_url_relative)
|
||||
job.application_url=job_apply_url_absolute
|
||||
job.save()
|
||||
messages.success(request, f'Job "{job.title}" created successfully!')
|
||||
return redirect("job_list")
|
||||
@ -279,6 +285,7 @@ def job_detail(request, slug):
|
||||
offer_count = candidates.filter(stage="Offer").count()
|
||||
|
||||
status_form = JobPostingStatusForm(instance=job)
|
||||
image_upload_form=JobPostingImageForm(instance=job)
|
||||
|
||||
# 2. Check for POST request (Status Update Submission)
|
||||
if request.method == 'POST':
|
||||
@ -306,10 +313,32 @@ def job_detail(request, slug):
|
||||
"applied_count": applied_count,
|
||||
"interview_count": interview_count,
|
||||
"offer_count": offer_count,
|
||||
'status_form':status_form
|
||||
'status_form':status_form,
|
||||
'image_upload_form':image_upload_form
|
||||
}
|
||||
return render(request, "jobs/job_detail.html", context)
|
||||
|
||||
def job_image_upload(request, slug):
|
||||
#only for handling the post request
|
||||
job=get_object_or_404(JobPosting,slug=slug)
|
||||
if request.method=='POST':
|
||||
image_upload_form=JobPostingImageForm(request.POST,request.FILES)
|
||||
if image_upload_form.is_valid():
|
||||
image_upload_form = image_upload_form.save(commit=False)
|
||||
|
||||
image_upload_form.job = job
|
||||
image_upload_form.save()
|
||||
messages.success(request, f"Image uploaded successfully for {job.title}.")
|
||||
return redirect('job_detail', slug=job.slug)
|
||||
else:
|
||||
|
||||
messages.error(request, "Image upload failed: Please ensure a valid image file was selected.")
|
||||
|
||||
return redirect('job_detail', slug=job.slug)
|
||||
return redirect('job_detail', slug=job.slug)
|
||||
|
||||
|
||||
|
||||
|
||||
# job detail facing the candidate:
|
||||
def job_detail_candidate(request, slug):
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 23 KiB |
@ -364,14 +364,14 @@
|
||||
.add-option {
|
||||
color: var(--primary);
|
||||
cursor: pointer;
|
||||
font-size: 0.9rem;
|
||||
font-size: 1rem;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.add-option:hover {
|
||||
text-decoration: underline;
|
||||
text-decoration: none;
|
||||
}
|
||||
/* File Upload Specific Styles */
|
||||
.file-upload-area {
|
||||
@ -685,12 +685,10 @@
|
||||
<div class="container">
|
||||
<!-- Sidebar with form elements -->
|
||||
<div class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<a class="" href="{% url 'form_templates_list' %}">
|
||||
<img src="{% static 'image/kaauh.jpeg' %}" style="height:100px; width:100px;">
|
||||
|
||||
<div class="sidebar-header" style="display: flex; flex-direction: column; align-items: center; justify-content: center;">
|
||||
<a href="{% url 'form_templates_list' %}">
|
||||
<img src="{% static 'image/kaauh.jpeg' %}" style="height:100px; width:100px; display: block; margin: 0 auto;">
|
||||
</a>
|
||||
|
||||
</div>
|
||||
<div class="field-categories">
|
||||
<div class="field-category">
|
||||
|
||||
@ -231,10 +231,10 @@
|
||||
<td>{{ submission.applicant_email|default:"N/A" }}</td>
|
||||
<td>{{ submission.submitted_at|date:"M d, Y H:i" }}</td>
|
||||
<td class="text-end">
|
||||
<a href="{% url 'form_submission_details' template_id=template.id submission_id=submission.id %}" class="btn btn-sm btn-outline-primary">
|
||||
<a href="{% url 'form_submission_details' template_id=template.id submission_id=submission.id %}" class="btn btn-sm btn-outline-primary">
|
||||
<i class="fas fa-eye me-1"></i> {% trans "View Details" %}
|
||||
</a>
|
||||
</td>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
||||
@ -505,7 +505,7 @@
|
||||
<body>
|
||||
<nav
|
||||
id="topNavbar"
|
||||
class="navbar navbar-expand-lg sticky-top"
|
||||
class="navbar navbar-expand-lg"
|
||||
style="background-color: white; z-index: 1030"
|
||||
>
|
||||
<div class="container-fluid">
|
||||
|
||||
@ -193,14 +193,14 @@
|
||||
{% if form.salary_range.errors %}<div class="text-danger small mt-1">{{ form.salary_range.errors }}</div>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{% comment %} <div class="col-md-6">
|
||||
<div>
|
||||
<label for="{{ form.application_url.id_for_label }}" class="form-label">{% trans "Application URL" %} <span class="text-danger">*</span></label>
|
||||
{{ form.application_url }}
|
||||
{% if form.application_url.errors %}<div class="text-danger small mt-1">{{ form.application_url.errors }}</div>{% endif %}
|
||||
<div class="form-text">{% trans "Full URL where candidates will apply" %}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> {% endcomment %}
|
||||
|
||||
<div class="col-12">
|
||||
<div>
|
||||
|
||||
@ -199,14 +199,14 @@
|
||||
{% if form.salary_range.errors %}<div class="text-danger small mt-1">{{ form.salary_range.errors }}</div>{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{% comment %} <div class="col-md-6">
|
||||
<div>
|
||||
<label for="{{ form.application_url.id_for_label }}" class="form-label">{% trans "Application URL" %} <span class="text-danger">*</span></label>
|
||||
{{ form.application_url }}
|
||||
{% if form.application_url.errors %}<div class="text-danger small mt-1">{{ form.application_url.errors }}</div>{% endif %}
|
||||
<div class="form-text">{% trans "Full URL where candidates will apply" %}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> {% endcomment %}
|
||||
|
||||
<div class="col-12">
|
||||
<div>
|
||||
|
||||
@ -409,11 +409,11 @@
|
||||
<i class="fas fa-edit"></i> {% trans "Edit Job" %}
|
||||
</a>
|
||||
|
||||
{% if job.application_url %}
|
||||
|
||||
<button type="button" class="btn btn-outline-secondary" data-bs-toggle="modal" data-bs-target="#myModalForm">
|
||||
<i class="fas fa-image me-1"></i> {% trans "Upload Image for Post" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -590,7 +590,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">{% trans "Cancel" %}</button>
|
||||
<button type="button" class="btn btn-outline-secondary btn-lg" data-bs-dismiss="modal">{% trans "Cancel" %}</button>
|
||||
<button type="submit" class="btn btn-main-action">{% trans "Save Changes" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@ -246,7 +246,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{job.form_template}}
|
||||
|
||||
<div class="mobile-fixed-apply-bar d-lg-none">
|
||||
{% if job.form_template %}
|
||||
<a href="{% url 'form_wizard' job.form_template.pk %}" class="btn btn-main-action btn-lg w-100">
|
||||
|
||||
@ -1,17 +1,22 @@
|
||||
<div class="modal fade" id="myModalForm" tabindex="-1" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal fade mt-4" id="myModalForm" tabindex="-1" aria-labelledby="myModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="myModalLabel">Add New Image</h5>
|
||||
<h5 class="modal-title" id="myModalLabel">Add New Image for the Post</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form method="post" action="{% url 'job_detail' job.slug %}">
|
||||
<form method="post" action="{% url 'job_image_upload' job.slug %}" enctype="multipart/form-data" >
|
||||
{% csrf_token %}
|
||||
{{ image_form }}
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="submit" class="btn btn-primary">Save changes</button>
|
||||
{{ image_upload_form.as_p}}
|
||||
|
||||
{% if image_upload_form.instance.post_image %}
|
||||
<p>Current Image:</p>
|
||||
<img src="{{ image_upload_form.instance.post_image.url }}" alt="Post Image" style="max-width: 200px;">
|
||||
{% endif %}
|
||||
<div class="modal-footer mt-2">
|
||||
<button type="button" class="btn btn-lg btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="submit" class="btn btn-main-action ">Save changes</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user