- Add resume file upload to schedule drawer with instant preview and validation - Create resume lightbox modal viewer with background scroll lock and CV SVG icon - Integrate CV tab into inspector panel with enlarge action and state - Attach candidate resume to panelist notification emails when - Fix Outlook RFC 5546 iTIP element mismatch and add table credentials copy button
190 lines
6.5 KiB
JavaScript
190 lines
6.5 KiB
JavaScript
import { getMeteredIceServers, initMeteredIceServers, globalIceServers } from './metered.js';
|
|
import './interview-call.js';
|
|
import './candidate-room.js';
|
|
import './candidate-proctor.js';
|
|
|
|
window.globalIceServers = globalIceServers;
|
|
window.getMeteredIceServers = getMeteredIceServers;
|
|
window.initMeteredIceServers = initMeteredIceServers;
|
|
|
|
// Pre-fetch TURN credentials immediately on app boot
|
|
if (typeof window !== 'undefined') {
|
|
window.getMeteredIceServers();
|
|
}
|
|
|
|
// Global Button Loader Handler
|
|
if (typeof document !== 'undefined') {
|
|
document.addEventListener('click', function (e) {
|
|
const btn = e.target.closest('button[data-show-loader="true"]');
|
|
if (!btn || btn.disabled) return;
|
|
|
|
if (btn.type === 'submit' && btn.form && !btn.form.checkValidity()) {
|
|
return;
|
|
}
|
|
|
|
const spinner = btn.querySelector('.btn-spinner');
|
|
const icon = btn.querySelector('.btn-icon');
|
|
const text = btn.querySelector('.btn-text');
|
|
|
|
if (spinner) {
|
|
spinner.classList.remove('hidden!');
|
|
if (icon) icon.classList.add('hidden!');
|
|
}
|
|
|
|
const loadingText = btn.getAttribute('data-loading-text');
|
|
if (loadingText && text) {
|
|
text.innerText = loadingText;
|
|
}
|
|
});
|
|
}
|
|
|
|
// Copy Interview Assessment Credentials Handler
|
|
window.copyInterviewCredentials = function (btn) {
|
|
const text = btn.getAttribute('data-credentials');
|
|
if (!text) return;
|
|
|
|
const copyToClipboard = () => {
|
|
if (navigator.clipboard && window.isSecureContext) {
|
|
return navigator.clipboard.writeText(text);
|
|
} else {
|
|
const textarea = document.createElement('textarea');
|
|
textarea.value = text;
|
|
textarea.style.position = 'fixed';
|
|
textarea.style.left = '-999999px';
|
|
textarea.style.top = '-999999px';
|
|
textarea.style.opacity = '0';
|
|
document.body.appendChild(textarea);
|
|
textarea.focus();
|
|
textarea.select();
|
|
document.execCommand('copy');
|
|
document.body.removeChild(textarea);
|
|
return Promise.resolve();
|
|
}
|
|
};
|
|
|
|
copyToClipboard().then(() => {
|
|
const icon = btn.querySelector('i');
|
|
const label = btn.querySelector('.copy-label');
|
|
const originalIconClass = icon ? icon.className : '';
|
|
const originalText = label ? label.textContent : '';
|
|
const originalBtnClass = btn.className;
|
|
|
|
if (icon) icon.className = 'fa-solid fa-check text-emerald-400 text-[11px]';
|
|
if (label) {
|
|
label.textContent = 'Copied!';
|
|
label.classList.add('text-emerald-300');
|
|
}
|
|
btn.classList.add('border-emerald-500/50', 'bg-emerald-500/10');
|
|
|
|
setTimeout(() => {
|
|
if (icon) icon.className = originalIconClass;
|
|
if (label) {
|
|
label.textContent = originalText;
|
|
label.classList.remove('text-emerald-300');
|
|
}
|
|
btn.className = originalBtnClass;
|
|
}, 2000);
|
|
}).catch(err => {
|
|
console.error('Failed to copy credentials: ', err);
|
|
});
|
|
};
|
|
|
|
// Candidate Resume Lightbox Previewer
|
|
window.openResumeLightbox = function (url, title = 'Candidate Resume') {
|
|
if (!url) return;
|
|
const modal = document.getElementById('resume-lightbox-modal');
|
|
const frame = document.getElementById('resume-lightbox-frame');
|
|
const loader = document.getElementById('resume-lightbox-loader');
|
|
const titleEl = document.getElementById('resume-lightbox-title');
|
|
const newTabBtn = document.getElementById('resume-lightbox-newtab');
|
|
|
|
if (!modal || !frame) return;
|
|
|
|
if (titleEl) titleEl.textContent = title;
|
|
if (newTabBtn) newTabBtn.href = url;
|
|
|
|
if (loader) loader.classList.remove('hidden');
|
|
frame.classList.add('opacity-0');
|
|
|
|
frame.onload = function () {
|
|
if (loader) loader.classList.add('hidden');
|
|
frame.classList.remove('opacity-0');
|
|
};
|
|
|
|
frame.src = url;
|
|
modal.classList.add('active');
|
|
|
|
// Disable background page scrolling
|
|
if (typeof document !== 'undefined') {
|
|
document.body.classList.add('overflow-hidden');
|
|
document.documentElement.classList.add('overflow-hidden');
|
|
}
|
|
};
|
|
|
|
window.closeResumeLightbox = function (e = null) {
|
|
if (e && e.stopPropagation) {
|
|
e.stopPropagation();
|
|
}
|
|
const modal = document.getElementById('resume-lightbox-modal');
|
|
const frame = document.getElementById('resume-lightbox-frame');
|
|
if (modal) modal.classList.remove('active');
|
|
if (frame) frame.src = 'about:blank';
|
|
|
|
// Restore background page scrolling
|
|
if (typeof document !== 'undefined') {
|
|
document.body.classList.remove('overflow-hidden');
|
|
document.documentElement.classList.remove('overflow-hidden');
|
|
}
|
|
};
|
|
|
|
// Close on Escape key
|
|
if (typeof document !== 'undefined') {
|
|
document.addEventListener('keydown', function (e) {
|
|
if (e.key === 'Escape') {
|
|
window.closeResumeLightbox();
|
|
}
|
|
});
|
|
}
|
|
|
|
// Drawer Candidate Resume Upload Handlers
|
|
window.handleDrawerResumeSelect = function (input) {
|
|
if (!input || !input.files || !input.files[0]) return;
|
|
const file = input.files[0];
|
|
|
|
const dropzone = document.getElementById('drawer-resume-dropzone');
|
|
const selectedBadge = document.getElementById('drawer-resume-selected');
|
|
const filenameEl = document.getElementById('drawer-resume-filename');
|
|
const filesizeEl = document.getElementById('drawer-resume-filesize');
|
|
|
|
if (filenameEl) filenameEl.textContent = file.name;
|
|
if (filesizeEl) {
|
|
const sizeKb = file.size / 1024;
|
|
filesizeEl.textContent = sizeKb >= 1024
|
|
? (sizeKb / 1024).toFixed(2) + ' MB'
|
|
: sizeKb.toFixed(1) + ' KB';
|
|
}
|
|
|
|
if (dropzone) dropzone.classList.add('hidden');
|
|
if (selectedBadge) selectedBadge.classList.remove('hidden');
|
|
};
|
|
|
|
window.previewSelectedDrawerResume = function () {
|
|
const input = document.getElementById('drawer_resume_input');
|
|
if (!input || !input.files || !input.files[0]) return;
|
|
const file = input.files[0];
|
|
const objectUrl = URL.createObjectURL(file);
|
|
window.openResumeLightbox(objectUrl, `${file.name} (Uploaded Preview)`);
|
|
};
|
|
|
|
window.clearSelectedDrawerResume = function () {
|
|
const input = document.getElementById('drawer_resume_input');
|
|
const dropzone = document.getElementById('drawer-resume-dropzone');
|
|
const selectedBadge = document.getElementById('drawer-resume-selected');
|
|
|
|
if (input) input.value = '';
|
|
if (selectedBadge) selectedBadge.classList.add('hidden');
|
|
if (dropzone) dropzone.classList.remove('hidden');
|
|
};
|
|
|
|
|