419 lines
20 KiB
HTML
419 lines
20 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>{{ form.title }} - Embed</title>
|
|
|
|
<!-- Tailwind CSS -->
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<script src="https://unpkg.com/lucide@latest"></script>
|
|
|
|
<script>
|
|
tailwind.config = {
|
|
theme: {
|
|
extend: {
|
|
colors: {
|
|
'temple-red': '#9d2235',
|
|
'temple-dark': '#1a1a1a',
|
|
'temple-cream': '#f8f7f2',
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap');
|
|
body {
|
|
font-family: 'Inter', sans-serif;
|
|
-webkit-font-smoothing: antialiased;
|
|
-moz-osx-font-smoothing: grayscale;
|
|
}
|
|
|
|
.code-block {
|
|
background: #2d3748;
|
|
color: #e2e8f0;
|
|
border-radius: 0.5rem;
|
|
padding: 1.25rem;
|
|
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
font-size: 0.875rem;
|
|
line-height: 1.5;
|
|
overflow-x: auto;
|
|
position: relative;
|
|
margin-top: 0.875rem;
|
|
}
|
|
|
|
.copy-btn {
|
|
position: absolute;
|
|
top: 0.625rem;
|
|
right: 0.625rem;
|
|
background: #4a5568;
|
|
border: none;
|
|
color: white;
|
|
padding: 0.5rem 0.75rem;
|
|
border-radius: 0.375rem;
|
|
cursor: pointer;
|
|
font-size: 0.75rem;
|
|
transition: background 0.2s;
|
|
}
|
|
|
|
.copy-btn:hover {
|
|
background: #2d3748;
|
|
}
|
|
|
|
.copy-btn.copied {
|
|
background: #48bb78;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="bg-gray-100 text-gray-800 min-h-screen">
|
|
<div class="p-4 md:p-6">
|
|
<div class="max-w-5xl mx-auto">
|
|
<!-- Header -->
|
|
<div class="bg-white rounded-2xl shadow-md p-6 mb-6">
|
|
<div class="flex flex-col md:flex-row md:items-start md:justify-between gap-4 mb-6">
|
|
<div class="flex-1">
|
|
<h1 class="text-2xl md:text-3xl font-bold text-gray-900 mb-2 flex items-center gap-2">
|
|
<i data-lucide="code-2" class="w-7 h-7 text-temple-red"></i>
|
|
Embed Form
|
|
</h1>
|
|
<p class="text-gray-600">Get embed code for "{{ form.title }}"</p>
|
|
</div>
|
|
<a href="{% url 'form_preview' form.id %}" target="_blank" class="inline-flex items-center gap-2 border border-temple-red text-temple-red hover:bg-temple-red hover:text-white px-4 py-2.5 rounded-xl transition font-medium">
|
|
<i data-lucide="external-link" class="w-4 h-4"></i> Preview Form
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Stats -->
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 text-center mb-6">
|
|
<div class="p-4 bg-gray-50 rounded-xl">
|
|
<div class="text-2xl font-bold text-temple-red">{{ form.submissions.count }}</div>
|
|
<div class="text-xs uppercase text-gray-500 font-semibold mt-1">Submissions</div>
|
|
</div>
|
|
<div class="p-4 bg-gray-50 rounded-xl">
|
|
<div class="text-2xl font-bold text-emerald-600">{{ form.structure.wizards|length|default:0 }}</div>
|
|
<div class="text-xs uppercase text-gray-500 font-semibold mt-1">Steps</div>
|
|
</div>
|
|
<div class="p-4 bg-gray-50 rounded-xl">
|
|
<div class="text-2xl font-bold text-blue-600">
|
|
{% if form.structure.wizards %}
|
|
{{ form.structure.wizards.0.fields|length|default:0 }}
|
|
{% else %}
|
|
0
|
|
{% endif %}
|
|
</div>
|
|
<div class="text-xs uppercase text-gray-500 font-semibold mt-1">Fields</div>
|
|
</div>
|
|
<div class="p-4 bg-gray-50 rounded-xl">
|
|
<div class="text-2xl font-bold text-amber-600">{{ form.created_at|date:"M d" }}</div>
|
|
<div class="text-xs uppercase text-gray-500 font-semibold mt-1">Created</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tabs -->
|
|
<div class="flex border-b border-gray-200 mb-6">
|
|
<button class="tab-btn px-6 py-3 font-medium text-gray-600 hover:text-temple-red border-b-2 border-transparent hover:border-temple-red transition flex items-center gap-2 active"
|
|
data-tab="iframe"
|
|
onclick="switchTab('iframe')">
|
|
<i data-lucide="globe" class="w-4 h-4"></i> iFrame
|
|
</button>
|
|
<button class="tab-btn px-6 py-3 font-medium text-gray-600 hover:text-temple-red border-b-2 border-transparent hover:border-temple-red transition flex items-center gap-2"
|
|
data-tab="popup"
|
|
onclick="switchTab('popup')">
|
|
<i data-lucide="external-link" class="w-4 h-4"></i> Popup
|
|
</button>
|
|
<button class="tab-btn px-6 py-3 font-medium text-gray-600 hover:text-temple-red border-b-2 border-transparent hover:border-temple-red transition flex items-center gap-2"
|
|
data-tab="inline"
|
|
onclick="switchTab('inline')">
|
|
<i data-lucide="code" class="w-4 h-4"></i> Inline
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Tab Contents -->
|
|
<div id="tab-content">
|
|
<!-- iFrame Tab -->
|
|
<div class="tab-pane" id="iframe-pane">
|
|
<h5 class="text-lg font-semibold text-gray-900 mb-3">iFrame Embed Code</h5>
|
|
<p class="text-gray-600 mb-4">Embed this form directly into your website using an iframe.</p>
|
|
|
|
<div class="code-block">
|
|
<button class="copy-btn" onclick="copyToClipboard(this, 'iframe-code')">
|
|
<i data-lucide="copy" class="w-3 h-3"></i> Copy
|
|
</button>
|
|
<code id="iframe-code"><iframe src="{{ request.build_absolute_uri }}{% url 'form_preview' form.id %}?embed=true"
|
|
width="100%"
|
|
height="600"
|
|
frameborder="0"
|
|
style="border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.1);"></iframe></code>
|
|
</div>
|
|
|
|
<div class="bg-gray-50 rounded-xl p-4 mt-4">
|
|
<h6 class="font-semibold text-gray-900 mb-3">Responsive Options</h6>
|
|
<div class="space-y-2">
|
|
<div class="responsive-option active bg-white border-2 border-temple-red p-4 rounded-xl cursor-pointer hover:shadow-md transition"
|
|
onclick="selectResponsive(this, 'iframe', 'fixed')">
|
|
<div class="font-semibold">Fixed Height: 600px</div>
|
|
<div class="text-sm text-gray-500">Best for most websites</div>
|
|
</div>
|
|
<div class="responsive-option bg-white border-2 border-gray-200 p-4 rounded-xl cursor-pointer hover:border-temple-red transition"
|
|
onclick="selectResponsive(this, 'iframe', 'responsive')">
|
|
<div class="font-semibold">Responsive: Auto height</div>
|
|
<div class="text-sm text-gray-500">Adjusts to content height</div>
|
|
</div>
|
|
<div class="responsive-option bg-white border-2 border-gray-200 p-4 rounded-xl cursor-pointer hover:border-temple-red transition"
|
|
onclick="selectResponsive(this, 'iframe', 'full')">
|
|
<div class="font-semibold">Full Screen: 100vh</div>
|
|
<div class="text-sm text-gray-500">Takes full viewport height</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Popup Tab -->
|
|
<div class="tab-pane hidden" id="popup-pane">
|
|
<h5 class="text-lg font-semibold text-gray-900 mb-3">Popup Embed Code</h5>
|
|
<p class="text-gray-600 mb-4">Add a button or link that opens to form in a modal popup.</p>
|
|
|
|
<div class="code-block">
|
|
<button class="copy-btn" onclick="copyToClipboard(this, 'popup-code')">
|
|
<i data-lucide="copy" class="w-3 h-3"></i> Copy
|
|
</button>
|
|
<code id="popup-code"><button onclick="openFormPopup()" class="bg-temple-red hover:bg-[#7a1a29] text-white px-6 py-3 rounded-xl font-medium transition">
|
|
Open Form
|
|
</button>
|
|
|
|
<script>
|
|
function openFormPopup() {
|
|
const modal = document.createElement('div');
|
|
modal.style.cssText = 'position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 9999; display: flex; align-items: center; justify-content: center;';
|
|
|
|
const iframe = document.createElement('iframe');
|
|
iframe.src = '{{ request.build_absolute_uri }}{% url 'form_preview' form.id %}?embed=true';
|
|
iframe.style.cssText = 'width: 90%; max-width: 800px; height: 80vh; border: none; border-radius: 12px; box-shadow: 0 20px 60px rgba(0,0,0,0.3);';
|
|
|
|
modal.appendChild(iframe);
|
|
document.body.appendChild(modal);
|
|
|
|
modal.onclick = function(e) {
|
|
if (e.target === modal) {
|
|
document.body.removeChild(modal);
|
|
}
|
|
};
|
|
}
|
|
</script></code>
|
|
</div>
|
|
|
|
<div class="mt-6">
|
|
<h6 class="font-semibold text-gray-900 mb-3">Customization Options</h6>
|
|
<ul class="space-y-2">
|
|
<li class="flex items-center gap-2 text-gray-700">
|
|
<i data-lucide="check" class="w-4 h-4 text-emerald-500"></i> Custom button text and styling
|
|
</li>
|
|
<li class="flex items-center gap-2 text-gray-700">
|
|
<i data-lucide="check" class="w-4 h-4 text-emerald-500"></i> Trigger on page load or scroll
|
|
</li>
|
|
<li class="flex items-center gap-2 text-gray-700">
|
|
<i data-lucide="check" class="w-4 h-4 text-emerald-500"></i> Custom modal dimensions
|
|
</li>
|
|
<li class="flex items-center gap-2 text-gray-700">
|
|
<i data-lucide="check" class="w-4 h-4 text-emerald-500"></i> Close on outside click
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Inline Tab -->
|
|
<div class="tab-pane hidden" id="inline-pane">
|
|
<h5 class="text-lg font-semibold text-gray-900 mb-3">Inline Embed Code</h5>
|
|
<p class="text-gray-600 mb-4">Embed form HTML directly into your page for maximum customization.</p>
|
|
|
|
<div class="bg-blue-50 border border-blue-200 rounded-xl p-4 mb-4 flex items-start gap-3">
|
|
<i data-lucide="info" class="w-5 h-5 text-blue-600 shrink-0 mt-0.5"></i>
|
|
<div>
|
|
<strong class="text-blue-900">Note:</strong> This option requires more technical knowledge but offers best integration.
|
|
</div>
|
|
</div>
|
|
|
|
<div class="code-block">
|
|
<button class="copy-btn" onclick="copyToClipboard(this, 'inline-code')">
|
|
<i data-lucide="copy" class="w-3 h-3"></i> Copy
|
|
</button>
|
|
<code id="inline-code"><!-- Form CSS -->
|
|
<link href="https://cdn.tailwindcss.com" rel="stylesheet">
|
|
|
|
<!-- Form Container -->
|
|
<div id="form-{{ form.id }}">
|
|
<div class="text-center py-12">
|
|
<div class="inline-block w-8 h-8 border-4 border-temple-red border-t-transparent rounded-full animate-spin"></div>
|
|
<p class="mt-4 text-gray-600">Loading form...</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Form Scripts -->
|
|
<script>
|
|
// Load form data and render
|
|
fetch('/recruitment/api/forms/{{ form.id }}/load/')
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
// Render form using to form structure
|
|
console.log('Form data:', data);
|
|
// Implement form rendering logic here
|
|
})
|
|
.catch(error => console.error('Error loading form:', error));
|
|
</script></code>
|
|
</div>
|
|
|
|
<div class="mt-6">
|
|
<h6 class="font-semibold text-gray-900 mb-3">Benefits of Inline Embed</h6>
|
|
<ul class="space-y-2">
|
|
<li class="flex items-center gap-2 text-gray-700">
|
|
<i data-lucide="check" class="w-4 h-4 text-emerald-500"></i> Full control over styling
|
|
</li>
|
|
<li class="flex items-center gap-2 text-gray-700">
|
|
<i data-lucide="check" class="w-4 h-4 text-emerald-500"></i> Better SEO integration
|
|
</li>
|
|
<li class="flex items-center gap-2 text-gray-700">
|
|
<i data-lucide="check" class="w-4 h-4 text-emerald-500"></i> Faster initial load
|
|
</li>
|
|
<li class="flex items-center gap-2 text-gray-700">
|
|
<i data-lucide="check" class="w-4 h-4 text-emerald-500"></i> Custom form handling
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Preview Section -->
|
|
<div class="bg-white rounded-2xl shadow-md overflow-hidden mt-6">
|
|
<div class="bg-gradient-to-br from-temple-red to-[#7a1a29] text-white p-4">
|
|
<h5 class="font-semibold flex items-center gap-2">
|
|
<i data-lucide="eye" class="w-5 h-5"></i> Live Preview
|
|
</h5>
|
|
</div>
|
|
<div class="p-0">
|
|
<iframe src="{% url 'form_preview' form.id %}?embed=true"
|
|
class="w-full border border-gray-200 rounded-xl"
|
|
style="height: 600px;"
|
|
frameborder="0">
|
|
</iframe>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
lucide.createIcons();
|
|
|
|
function switchTab(tabName) {
|
|
// Update tab buttons
|
|
document.querySelectorAll('.tab-btn').forEach(btn => {
|
|
btn.classList.remove('active', 'text-temple-red', 'border-temple-red');
|
|
btn.classList.add('text-gray-600', 'border-transparent');
|
|
});
|
|
|
|
const activeBtn = document.querySelector(`[data-tab="${tabName}"]`);
|
|
activeBtn.classList.add('active', 'text-temple-red', 'border-temple-red');
|
|
activeBtn.classList.remove('text-gray-600', 'border-transparent');
|
|
|
|
// Show/hide tab panes
|
|
document.querySelectorAll('.tab-pane').forEach(pane => {
|
|
pane.classList.add('hidden');
|
|
});
|
|
|
|
document.getElementById(`${tabName}-pane`).classList.remove('hidden');
|
|
}
|
|
|
|
function copyToClipboard(button, elementId) {
|
|
const element = document.getElementById(elementId);
|
|
const text = element.textContent;
|
|
|
|
navigator.clipboard.writeText(text).then(function() {
|
|
const originalText = button.innerHTML;
|
|
button.innerHTML = '<i data-lucide="check" class="w-3 h-3"></i> Copied!';
|
|
button.classList.add('copied');
|
|
lucide.createIcons();
|
|
|
|
setTimeout(function() {
|
|
button.innerHTML = originalText;
|
|
button.classList.remove('copied');
|
|
lucide.createIcons();
|
|
}, 2000);
|
|
}).catch(function(err) {
|
|
console.error('Failed to copy text: ', err);
|
|
|
|
// Fallback for older browsers
|
|
const textArea = document.createElement("textarea");
|
|
textArea.value = text;
|
|
document.body.appendChild(textArea);
|
|
textArea.focus();
|
|
textArea.select();
|
|
|
|
try {
|
|
document.execCommand('copy');
|
|
button.innerHTML = '<i data-lucide="check" class="w-3 h-3"></i> Copied!';
|
|
button.classList.add('copied');
|
|
lucide.createIcons();
|
|
|
|
setTimeout(function() {
|
|
button.innerHTML = originalText;
|
|
button.classList.remove('copied');
|
|
lucide.createIcons();
|
|
}, 2000);
|
|
} catch (err) {
|
|
console.error('Fallback copy failed: ', err);
|
|
}
|
|
|
|
document.body.removeChild(textArea);
|
|
});
|
|
}
|
|
|
|
function selectResponsive(element, type, option) {
|
|
// Remove active class from all options in this tab
|
|
const container = element.closest('.tab-pane');
|
|
container.querySelectorAll('.responsive-option').forEach(opt => {
|
|
opt.classList.remove('active', 'border-temple-red');
|
|
opt.classList.add('border-gray-200');
|
|
});
|
|
|
|
// Add active class to selected option
|
|
element.classList.add('active', 'border-temple-red');
|
|
element.classList.remove('border-gray-200');
|
|
|
|
// Update embed code based on selection
|
|
updateEmbedCode(type, option);
|
|
}
|
|
|
|
function updateEmbedCode(type, option) {
|
|
const baseUrl = '{{ request.build_absolute_uri }}{% url "form_preview" form.id %}?embed=true';
|
|
let height = '600';
|
|
let style = 'border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.1);';
|
|
|
|
if (type === 'iframe') {
|
|
switch(option) {
|
|
case 'responsive':
|
|
height = 'auto';
|
|
style += ' min-height: 600px;';
|
|
break;
|
|
case 'full':
|
|
height = '100vh';
|
|
style += ' min-height: 100vh;';
|
|
break;
|
|
default:
|
|
// fixed height - already set
|
|
break;
|
|
}
|
|
|
|
const code = `<iframe src="${baseUrl}"
|
|
width="100%"
|
|
height="${height}"
|
|
frameborder="0"
|
|
style="${style}"></iframe>`;
|
|
|
|
document.getElementById('iframe-code').textContent = code;
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |