lot of updates

This commit is contained in:
ismail 2025-10-21 19:24:42 +03:00
parent ef8616c088
commit 3086b38a23
18 changed files with 93 additions and 53 deletions

View File

@ -22,13 +22,13 @@ urlpatterns = [
# path('', include('recruitment.urls')), # path('', include('recruitment.urls')),
path("ckeditor5/", include('django_ckeditor_5.urls')), path("ckeditor5/", include('django_ckeditor_5.urls')),
path('<int:template_id>/', views.form_wizard_view, name='form_wizard'), path('<slug:template_slug>/', views.form_wizard_view, name='form_wizard'),
path('<int:template_id>/submit/', views.submit_form, name='submit_form'), path('<slug:template_slug>/submit/', views.submit_form, name='submit_form'),
path('api/templates/', views.list_form_templates, name='list_form_templates'), path('api/templates/', views.list_form_templates, name='list_form_templates'),
path('api/templates/save/', views.save_form_template, name='save_form_template'), path('api/templates/save/', views.save_form_template, name='save_form_template'),
path('api/templates/<int:template_id>/', views.load_form_template, name='load_form_template'), path('api/templates/<slug:template_slug>/', views.load_form_template, name='load_form_template'),
path('api/templates/<int:template_id>/delete/', views.delete_form_template, name='delete_form_template'), path('api/templates/<slug:template_slug>/delete/', views.delete_form_template, name='delete_form_template'),
path('api/webhook/',views.zoom_webhook_view,name='zoom_webhook_view') path('api/webhook/',views.zoom_webhook_view,name='zoom_webhook_view')
] ]

View File

@ -82,14 +82,14 @@ def create_default_stages(sender, instance, created, **kwargs):
order=4, order=4,
is_predefined=True is_predefined=True
) )
# FormField.objects.create( FormField.objects.create(
# stage=contact_stage, stage=contact_stage,
# label='National ID / Iqama Number', label='National ID / Iqama Number',
# field_type='text', field_type='text',
# required=False, required=False,
# order=5, order=5,
# is_predefined=True is_predefined=True
# ) )
FormField.objects.create( FormField.objects.create(
stage=contact_stage, stage=contact_stage,
label='Resume Upload', label='Resume Upload',

View File

@ -96,10 +96,10 @@ urlpatterns = [
# path('api/forms/save/', views.save_form_builder, name='save_form_builder'), # path('api/forms/save/', views.save_form_builder, name='save_form_builder'),
# path('api/forms/<int:form_id>/load/', views.load_form, name='load_form'), # path('api/forms/<int:form_id>/load/', views.load_form, name='load_form'),
# path('api/forms/<int:form_id>/update/', views.update_form_builder, name='update_form_builder'), # path('api/forms/<int:form_id>/update/', views.update_form_builder, name='update_form_builder'),
path('api/templates/', views.list_form_templates, name='list_form_templates'), # path('api/templates/', views.list_form_templates, name='list_form_templates'),
path('api/templates/save/', views.save_form_template, name='save_form_template'), # path('api/templates/save/', views.save_form_template, name='save_form_template'),
path('api/templates/<int:template_id>/', views.load_form_template, name='load_form_template'), # path('api/templates/<slug:template_slug>/', views.load_form_template, name='load_form_template'),
path('api/templates/<int:template_id>/delete/', views.delete_form_template, name='delete_form_template'), # path('api/templates/<slug:template_slug>/delete/', views.delete_form_template, name='delete_form_template'),
path('jobs/<slug:slug>/calendar/', views.interview_calendar_view, name='interview_calendar'), path('jobs/<slug:slug>/calendar/', views.interview_calendar_view, name='interview_calendar'),

View File

@ -637,10 +637,10 @@ def form_builder(request, template_slug=None):
context = {} context = {}
if template_slug: if template_slug:
template = get_object_or_404( template = get_object_or_404(
FormTemplate, slug=template_slug, created_by=request.user FormTemplate, slug=template_slug
) )
context['template']=template context['template']=template
context["template_id"] = template.id context["template_slug"] = template.slug
context["template_name"] = template.name context["template_name"] = template.name
return render(request, "forms/form_builder.html", context) return render(request, "forms/form_builder.html", context)
@ -653,12 +653,12 @@ def save_form_template(request):
data = json.loads(request.body) data = json.loads(request.body)
template_name = data.get("name", "Untitled Form") template_name = data.get("name", "Untitled Form")
stages_data = data.get("stages", []) stages_data = data.get("stages", [])
template_id = data.get("template_id") template_slug = data.get("template_slug")
if template_id: if template_slug:
# Update existing template # Update existing template
template = get_object_or_404( template = get_object_or_404(
FormTemplate, id=template_id, created_by=request.user FormTemplate, slug=template_slug
) )
template.name = template_name template.name = template_name
template.save() template.save()
@ -667,7 +667,7 @@ def save_form_template(request):
else: else:
# Create new template # Create new template
template = FormTemplate.objects.create( template = FormTemplate.objects.create(
name=template_name, created_by=request.user name=template_name
) )
# Create stages and fields # Create stages and fields
@ -703,7 +703,7 @@ def save_form_template(request):
return JsonResponse( return JsonResponse(
{ {
"success": True, "success": True,
"template_id": template.id, "template_slug": template.slug,
"message": "Form template saved successfully!", "message": "Form template saved successfully!",
} }
) )
@ -712,9 +712,9 @@ def save_form_template(request):
@require_http_methods(["GET"]) @require_http_methods(["GET"])
def load_form_template(request, template_id): def load_form_template(request, template_slug):
"""Load an existing form template""" """Load an existing form template"""
template = get_object_or_404(FormTemplate, id=template_id, created_by=request.user) template = get_object_or_404(FormTemplate, slug=template_slug)
stages = [] stages = []
for stage in template.stages.all(): for stage in template.stages.all():
@ -747,6 +747,7 @@ def load_form_template(request, template_id):
"success": True, "success": True,
"template": { "template": {
"id": template.id, "id": template.id,
"template_slug": template.slug,
"name": template.name, "name": template.name,
"description": template.description, "description": template.description,
"is_active": template.is_active, "is_active": template.is_active,
@ -844,6 +845,7 @@ def form_wizard_view(request, template_slug):
) )
@csrf_exempt
@require_POST @require_POST
def submit_form(request, template_slug): def submit_form(request, template_slug):
"""Handle form submission""" """Handle form submission"""
@ -862,6 +864,7 @@ def submit_form(request, template_slug):
{"success": False, "message": "Application limit reached for this job."} {"success": False, "message": "Application limit reached for this job."}
) )
submission = FormSubmission.objects.create(template=template) submission = FormSubmission.objects.create(template=template)
# Process field responses # Process field responses
for field_id, value in request.POST.items(): for field_id, value in request.POST.items():
if field_id.startswith("field_"): if field_id.startswith("field_"):
@ -906,7 +909,7 @@ def submit_form(request, template_slug):
) )
submission.applicant_email = email.display_value submission.applicant_email = email.display_value
submission.save() submission.save()
time=timezone.now() # time=timezone.now()
Candidate.objects.create( Candidate.objects.create(
first_name=first_name.display_value, first_name=first_name.display_value,
last_name=last_name.display_value, last_name=last_name.display_value,
@ -914,10 +917,16 @@ def submit_form(request, template_slug):
phone=phone.display_value, phone=phone.display_value,
address=address.display_value, address=address.display_value,
resume=resume.get_file if resume.is_file else None, resume=resume.get_file if resume.is_file else None,
job=submission.template.job, job=job
) )
return redirect('application_success',slug=job.slug) return JsonResponse(
{
"success": True,
"message": "Form submitted successfully!",
"redirect_url": reverse('application_success',kwargs={'slug':job.slug}),
}
)
# return redirect('application_success',slug=job.slug)
except Exception as e: except Exception as e:
logger.error(f"Candidate creation failed,{e}") logger.error(f"Candidate creation failed,{e}")

View File

@ -324,6 +324,34 @@
}); });
} }
}); });
function form_loader(){
const forms = document.querySelectorAll('form');
forms.forEach(form => {
form.addEventListener('submit', function(e) {
const submitButton = form.querySelector('button[type="submit"], input[type="submit"]');
if (submitButton) {
submitButton.disabled = true;
submitButton.classList.add('loading');
window.addEventListener('unload', function() {
submitButton.disabled = false;
submitButton.classList.remove('loading');
});
}
});
});
}
form_loader();
try{
document.addEventListener('htmx:afterSwap', form_loader);
}catch(e){
console.error(e)
}
</script> </script>
{% block customJS %}{% endblock %} {% block customJS %}{% endblock %}

View File

@ -678,8 +678,8 @@
const djangoConfig = { const djangoConfig = {
csrfToken: "{{ csrf_token }}", csrfToken: "{{ csrf_token }}",
saveUrl: "{% url 'save_form_template' %}", saveUrl: "{% url 'save_form_template' %}",
loadUrl: {% if template_id %}"{% url 'load_form_template' template_id %}"{% else %}null{% endif %}, loadUrl: {% if template_slug %}"{% url 'load_form_template' template_slug %}"{% else %}null{% endif %},
templateId: {% if template_id %}{{ template_id }}{% else %}null{% endif %}, templateId: {% if template_slug %}'{{ template_slug }}'{% else %}null{% endif %},
jobId: {% if job_id %}{{ job_id }}{% else %}null{% endif %} // Add this if you need it jobId: {% if job_id %}{{ job_id }}{% else %}null{% endif %} // Add this if you need it
}; };
</script> </script>
@ -1212,7 +1212,7 @@ const elements = {
name: state.formName, name: state.formName,
description: state.formDescription, description: state.formDescription,
is_active: state.formActive, is_active: state.formActive,
template_id: state.templateId, template_slug: state.templateId,
stages: state.stages.map(stage => ({ stages: state.stages.map(stage => ({
name: stage.name, name: stage.name,
predefined: stage.predefined, predefined: stage.predefined,
@ -1248,7 +1248,7 @@ const elements = {
const result = await response.json(); const result = await response.json();
if (result.success) { if (result.success) {
state.templateId = result.template_id; state.templateId = result.template_slug;
window.location.href = "{% url 'form_templates_list' %}"; window.location.href = "{% url 'form_templates_list' %}";
} else { } else {
@ -1280,7 +1280,7 @@ const elements = {
// Set stages (this is where your actual stages come from) // Set stages (this is where your actual stages come from)
state.stages = templateData.stages; state.stages = templateData.stages;
state.templateId = templateData.id; state.templateId = templateData.template_slug;
// Update next IDs to avoid conflicts // Update next IDs to avoid conflicts
let maxFieldId = 0; let maxFieldId = 0;

View File

@ -538,7 +538,7 @@
const csrfToken = '{{ csrf_token }}'; const csrfToken = '{{ csrf_token }}';
const state = { const state = {
templateId: {{ template_slug }}, templateId: '{{ template_slug }}',
stages: [], stages: [],
currentStage: 0, currentStage: 0,
formData: {}, formData: {},
@ -838,20 +838,23 @@
const result = await response.json(); const result = await response.json();
if (result.success) { if (result.success) {
alert('Application submitted successfully! Thank you for your submission.'); console.log('Application submitted successfully! Thank you for your submission.');
window.location.href = '/applications/'; // Redirect to applications list const redirect_url = result['redirect_url']
window.location.href = redirect_url; // Redirect to applications list
} else { } else {
alert('Error submitting form: ' + (result.error || 'Unknown error')); console.log(result)
console.log('Error submitting form: ' + (result.error || 'Unknown error'));
} }
} catch (error) { } catch (error) {
console.error('Submission error:', error); console.log(error)
//console.error('Submission error:', error);
// Try to get response text for debugging // Try to get response text for debugging
try { try {
const errorText = await response.text(); const errorText = await response.text();
console.error('Response text:', errorText); console.error('Response text:', errorText);
alert('Error submitting form. Server response: ' + errorText); console.log('Error submitting form. Server response: ' + errorText);
} catch (e) { } catch (e) {
alert('Error submitting form: ' + error.message); console.log('Error submitting form: ' + error.message);
} }
} }
} }