ATS/templates/recruitment/schedule_meeting_form.html
2026-02-01 13:38:06 +03:00

208 lines
9.1 KiB
HTML

{% extends "base.html" %}
{% load static i18n %}
{% block title %}{% trans "Schedule Meeting" %} - {{ job.title }} - {{ block.super }}{% endblock %}
{% block content %}
<div class="px-4 py-6 max-w-2xl mx-auto">
<!-- Header -->
<div class="flex flex-col sm:flex-row sm:justify-between sm:items-start gap-4 mb-6">
<div class="flex-1">
<h1 class="text-2xl font-bold text-temple-dark mb-1 flex items-center gap-2">
<i data-lucide="calendar-plus" class="w-7 h-7"></i>
{% if has_future_meeting %}
{% trans "Update Interview" %} for {{ application.name }}
{% else %}
{% trans "Schedule Interview" %} for {{ application.name }}
{% endif %}
</h1>
<p class="text-gray-600">{% trans "Job" %}: {{ job.title }}</p>
{% if has_future_meeting %}
<div class="mt-3 bg-blue-50 border border-blue-200 rounded-lg p-3 flex items-start gap-2">
<i data-lucide="info" class="w-5 h-5 text-blue-500 flex-shrink-0 mt-0.5"></i>
<p class="text-sm text-blue-800">
{% trans "This application has upcoming interviews. You are updating an existing schedule." %}
</p>
</div>
{% endif %}
</div>
<a href="{% url 'applications_interview_view' job.slug %}"
class="inline-flex items-center gap-2 border border-gray-300 text-gray-700 hover:bg-gray-50 px-4 py-2.5 rounded-lg text-sm font-medium transition">
<i data-lucide="arrow-left" class="w-4 h-4"></i>
{% trans "Back to Candidates" %}
</a>
</div>
<!-- Form Card -->
<div class="bg-white rounded-xl shadow-md border border-gray-200">
<div class="p-6">
<form method="post" id="meetingForm">
{% csrf_token %}
<!-- Topic Field -->
<div class="mb-6">
<label for="{{ form.topic.id_for_label }}" class="block text-sm font-semibold text-gray-700 mb-2">
{% trans "Meeting Topic" %}
</label>
{{ form.topic }}
{% if form.topic.errors %}
<div class="mt-1 text-sm text-red-600">
{% for error in form.topic.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
<p class="mt-1 text-sm text-gray-500">
{% trans "Default topic will be 'Interview: [Job Title] with [Candidate Name]' if left empty." %}
</p>
</div>
<!-- Start Time Field -->
<div class="mb-6">
<label for="{{ form.start_time.id_for_label }}" class="block text-sm font-semibold text-gray-700 mb-2">
{% trans "Start Time" %}
</label>
{{ form.start_time }}
{% if form.start_time.errors %}
<div class="mt-1 text-sm text-red-600">
{% for error in form.start_time.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
<p class="mt-1 text-sm text-gray-500">
{% trans "Please select a date and time for interview." %}
</p>
</div>
<!-- Duration Field -->
<div class="mb-8">
<label for="{{ form.duration.id_for_label }}" class="block text-sm font-semibold text-gray-700 mb-2">
{% trans "Duration (minutes)" %}
</label>
{{ form.duration }}
{% if form.duration.errors %}
<div class="mt-1 text-sm text-red-600">
{% for error in form.duration.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
</div>
<!-- Action Buttons -->
<div class="flex flex-col sm:flex-row gap-3 pt-4 border-t border-gray-200">
<button type="submit"
class="flex-1 sm:flex-none bg-temple-red hover:bg-red-800 text-white font-semibold px-8 py-3 rounded-xl transition shadow-md hover:shadow-lg flex items-center justify-center gap-2">
<i data-lucide="save" class="w-5 h-5"></i>
{% trans "Schedule Meeting" %}
</button>
<a href="{% url 'applications_interview_view' job.slug %}"
class="flex-1 sm:flex-none border border-gray-300 text-gray-700 hover:bg-gray-50 px-8 py-3 rounded-xl transition flex items-center justify-center gap-2">
<i data-lucide="x" class="w-5 h-5"></i>
{% trans "Cancel" %}
</a>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
{% block customJS %}
<script>
document.addEventListener('DOMContentLoaded', function() {
// Initialize Lucide icons
lucide.createIcons();
// Add form styling to inputs
const formInputs = document.querySelectorAll('input, select, textarea');
formInputs.forEach(input => {
input.classList.add('w-full', 'px-3', 'py-2.5', 'border', 'border-gray-300', 'rounded-lg', 'focus:ring-2', 'focus:ring-temple-red', 'focus:border-transparent', 'transition', 'text-gray-900');
});
// Form validation
const form = document.getElementById('meetingForm');
if (form) {
form.addEventListener('submit', function(e) {
const submitBtn = form.querySelector('button[type="submit"]');
const topic = document.getElementById('id_topic');
const startTime = document.getElementById('id_start_time');
const duration = document.getElementById('id_duration');
// Add loading state
submitBtn.disabled = true;
submitBtn.innerHTML = `<i data-lucide="loader-2" class="w-5 h-5 mr-2 animate-spin"></i> {% trans "Scheduling..." %}`;
// Basic validation
if (startTime && !startTime.value) {
e.preventDefault();
submitBtn.disabled = false;
submitBtn.innerHTML = `<i data-lucide="save" class="w-5 h-5 mr-2"></i> {% trans "Schedule Meeting" %}`;
alert('{% trans "Please select a start time." %}');
return;
}
if (duration && !duration.value) {
e.preventDefault();
submitBtn.disabled = false;
submitBtn.innerHTML = `<i data-lucide="save" class="w-5 h-5 mr-2"></i> {% trans "Schedule Meeting" %}`;
alert('{% trans "Please specify the duration." %}');
return;
}
// Validate that start time is in the future
if (startTime && startTime.value) {
const selectedDate = new Date(startTime.value);
const now = new Date();
if (selectedDate <= now) {
e.preventDefault();
submitBtn.disabled = false;
submitBtn.innerHTML = `<i data-lucide="save" class="w-5 h-5 mr-2"></i> {% trans "Schedule Meeting" %}`;
alert('{% trans "Please select a future date and time for the interview." %}');
return;
}
}
});
}
// Warn before leaving if form has data
let formChanged = false;
const inputsToTrack = form ? form.querySelectorAll('input, select, textarea') : [];
inputsToTrack.forEach(input => {
input.addEventListener('change', function() {
formChanged = true;
});
});
window.addEventListener('beforeunload', function(e) {
if (formChanged) {
e.preventDefault();
e.returnValue = '{% trans "You have unsaved changes. Are you sure you want to leave?" %}';
return e.returnValue;
}
});
if (form) {
form.addEventListener('submit', function() {
formChanged = false;
});
}
// Set minimum date to today for datetime-local input
const startTimeInput = document.getElementById('id_start_time');
if (startTimeInput) {
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const minDateTime = `${year}-${month}-${day}T${hours}:${minutes}`;
startTimeInput.setAttribute('min', minDateTime);
}
});
</script>
{% endblock %}