134 lines
7.3 KiB
HTML
134 lines
7.3 KiB
HTML
{% load i18n %}
|
|
<!-- This snippet is loaded by HTMX into #meetingModalBody -->
|
|
<form id="meetingForm" method="post" action="{{ action_url }}?_target=modal">
|
|
{% csrf_token %}
|
|
<input type="hidden" name="candidate_pk" value="{{ candidate.pk }}">
|
|
{% if scheduled_interview %}
|
|
<input type="hidden" name="interview_pk" value="{{ scheduled_interview.pk }}">
|
|
{% endif %}
|
|
|
|
<div class="mb-4">
|
|
<label for="id_topic" class="block text-sm font-medium text-gray-700 mb-2">{% trans "Topic" %}</label>
|
|
<input type="text" class="w-full px-4 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-temple-red/20 focus:border-temple-red outline-none transition" id="id_topic" name="topic" value="{{ initial_data.topic|default:'' }}" required>
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<label for="id_start_time" class="block text-sm font-medium text-gray-700 mb-2">{% trans "Start Time and Date" %}</label>
|
|
<input type="datetime-local" class="w-full px-4 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-temple-red/20 focus:border-temple-red outline-none transition" id="id_start_time" name="start_time" value="{{ initial_data.start_time|default:'' }}" required>
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<label for="id_duration" class="block text-sm font-medium text-gray-700 mb-2">{% trans "Duration (minutes)" %}</label>
|
|
<input type="number" class="w-full px-4 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-temple-red/20 focus:border-temple-red outline-none transition" id="id_duration" name="duration" value="{{ initial_data.duration|default:60 }}" min="15" step="15" required>
|
|
</div>
|
|
|
|
<div id="meetingDetails" class="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-4" style="display: none;">
|
|
<strong class="block text-blue-900 mb-2">{% trans "Meeting Details (will appear after scheduling):" %}</strong>
|
|
<p class="mb-1"><strong>{% trans "Join URL:" %}</strong> <a id="joinUrlDisplay" href="#" target="_blank" class="text-temple-red hover:underline"></a></p>
|
|
<p class="mb-0"><strong>{% trans "Meeting ID:" %}</strong> <span id="meetingIdDisplay"></span></p>
|
|
</div>
|
|
|
|
<div id="successMessage" class="bg-green-50 border border-green-200 rounded-lg p-4 mb-4" style="display: none;">
|
|
<span id="successText" class="block text-green-900"></span>
|
|
<small><a id="joinLinkSuccess" href="#" target="_blank" class="text-green-700 hover:underline">{% trans "Click here to join meeting" %}</a></small>
|
|
</div>
|
|
|
|
<div id="errorMessage" class="bg-red-50 border border-red-200 rounded-lg p-4 mb-4" style="display: none;">
|
|
<span id="errorText" class="block text-red-900"></span>
|
|
</div>
|
|
|
|
<div class="flex items-center justify-end gap-3 mt-4">
|
|
<button type="button" class="inline-flex items-center gap-2 bg-gray-100 hover:bg-gray-200 text-gray-700 font-medium px-4 py-2.5 rounded-lg text-sm transition" onclick="document.getElementById('meetingModal').classList.add('hidden')">{% trans "Cancel" %}</button>
|
|
<button type="submit" class="inline-flex items-center gap-2 bg-temple-red hover:bg-temple-dark text-white font-medium px-4 py-2.5 rounded-lg text-sm transition shadow-sm hover:shadow-md" id="scheduleBtn">
|
|
{% if scheduled_interview %}{% trans "Reschedule Meeting" %}{% else %}{% trans "Schedule Meeting" %}{% endif %}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
|
|
{% block customJS %}
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const form = document.getElementById('meetingForm');
|
|
const scheduleBtn = document.getElementById('scheduleBtn');
|
|
const meetingDetailsDiv = document.getElementById('meetingDetails');
|
|
const joinUrlDisplay = document.getElementById('joinUrlDisplay');
|
|
const meetingIdDisplay = document.getElementById('meetingIdDisplay');
|
|
const successMessageDiv = document.getElementById('successMessage');
|
|
const successText = document.getElementById('successText');
|
|
const joinLinkSuccess = document.getElementById('joinLinkSuccess');
|
|
const errorMessageDiv = document.getElementById('errorMessage');
|
|
const errorText = document.getElementById('errorText');
|
|
|
|
const submitBtnText = scheduleBtn.textContent || "{% trans 'Schedule Meeting' %}";
|
|
|
|
form.addEventListener('submit', function(event) {
|
|
event.preventDefault();
|
|
|
|
meetingDetailsDiv.style.display = 'none';
|
|
successMessageDiv.style.display = 'none';
|
|
errorMessageDiv.style.display = 'none';
|
|
|
|
scheduleBtn.disabled = true;
|
|
scheduleBtn.innerHTML = '<svg class="animate-spin -ml-1 mr-2 h-4 w-4 text-white" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg> {% trans "Processing..." %}';
|
|
|
|
const formData = new FormData(form);
|
|
const isModalTarget = new URLSearchParams(window.location.search).get('_target') === 'modal';
|
|
const url = form.action.replace(/\?.*$/, "");
|
|
|
|
fetch(url, {
|
|
method: 'POST',
|
|
body: formData,
|
|
headers: {
|
|
'X-CSRFToken': formData.get('csrfmiddlewaretoken'),
|
|
'Accept': 'application/json',
|
|
},
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
scheduleBtn.disabled = false;
|
|
scheduleBtn.textContent = submitBtnText;
|
|
|
|
if (data.success) {
|
|
successText.textContent = data.message;
|
|
successMessageDiv.style.display = 'block';
|
|
if (data.join_url) {
|
|
joinUrlDisplay.textContent = data.join_url;
|
|
joinUrlDisplay.href = data.join_url;
|
|
joinLinkSuccess.href = data.join_url;
|
|
meetingDetailsDiv.style.display = 'block';
|
|
}
|
|
if (data.meeting_id) {
|
|
meetingIdDisplay.textContent = data.meeting_id;
|
|
}
|
|
|
|
if (isModalTarget) {
|
|
const modalElement = document.getElementById('meetingModal');
|
|
if (modalElement) {
|
|
modalElement.classList.add('hidden');
|
|
}
|
|
}
|
|
if (window.parent && window.parent.dispatchEvent) {
|
|
window.parent.dispatchEvent(new CustomEvent('meetingUpdated', { detail: data }));
|
|
}
|
|
} else {
|
|
errorText.textContent = data.error || '{% trans "An unknown error occurred." %}';
|
|
errorMessageDiv.style.display = 'block';
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
scheduleBtn.disabled = false;
|
|
scheduleBtn.textContent = submitBtnText;
|
|
errorText.textContent = '{% trans "An error occurred while processing your request." %}';
|
|
errorMessageDiv.style.display = 'block';
|
|
});
|
|
});
|
|
|
|
{% if initial_data %}
|
|
document.getElementById('id_topic').value = '{{ initial_data.topic }}';
|
|
document.getElementById('id_start_time').value = '{{ initial_data.start_time }}';
|
|
document.getElementById('id_duration').value = '{{ initial_data.duration }}';
|
|
{% endif %}
|
|
});
|
|
</script>
|
|
{% endblock %} |