forked from UKSOURCE/cms.hailearning.edu.vn
feat: Add initial CMS for home page content management, including sections for hero, testimonials, partners, and more.
This commit is contained in:
122
views/admin/home/sections/achievements.ejs
Normal file
122
views/admin/home/sections/achievements.ejs
Normal file
@@ -0,0 +1,122 @@
|
||||
<!-- Achievements Tab -->
|
||||
<div class="tab-pane fade" id="achievements" role="tabpanel">
|
||||
<div class="row g-4">
|
||||
<!-- Basic Info -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-chart-pie me-2"></i>General Information
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Heading</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="achievementsHeading"
|
||||
value="<%= data.achievements?.heading || '' %>"
|
||||
placeholder="e.g., Our Achievements in Numbers"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Subheading</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="achievementsSubheading"
|
||||
value="<%= data.achievements?.subheading || '' %>"
|
||||
placeholder="e.g., Did You Know"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Achievement Items -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-list-ul me-2"></i>Achievement Items (Fixed 4 Items)
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body" id="achievementItemsContainer">
|
||||
<% for(let i=0; i<4; i++) {
|
||||
const item = (data.achievements?.items && data.achievements.items[i]) || {};
|
||||
%>
|
||||
<div class="card mb-3 bg-light border achievement-item">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h6 class="card-title fw-bold mb-0">Achievement #<%= i + 1 %></h6>
|
||||
</div>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label fw-medium">Value (Number)</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control achievement-value"
|
||||
value="<%= item.value || '' %>"
|
||||
placeholder="e.g., 95"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label fw-medium">Suffix</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control achievement-suffix"
|
||||
value="<%= item.suffix || '' %>"
|
||||
placeholder="e.g., %"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Label</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control achievement-label"
|
||||
value="<%= item.label || '' %>"
|
||||
placeholder="e.g., Visa Success Rate"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Description</label>
|
||||
<textarea
|
||||
class="form-control achievement-description"
|
||||
rows="2"
|
||||
placeholder="Short description of this achievement"
|
||||
><%= item.description || '' %></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Đăng ký scraper cho phần achievements
|
||||
window.homeScrapers = window.homeScrapers || {};
|
||||
window.homeScrapers.achievements = function() {
|
||||
const items = [];
|
||||
document.querySelectorAll('.achievement-item').forEach(el => {
|
||||
items.push({
|
||||
value: el.querySelector('.achievement-value').value,
|
||||
suffix: el.querySelector('.achievement-suffix').value,
|
||||
label: el.querySelector('.achievement-label').value,
|
||||
description: el.querySelector('.achievement-description').value
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
heading: document.getElementById('achievementsHeading').value,
|
||||
subheading: document.getElementById('achievementsSubheading').value,
|
||||
items: items
|
||||
};
|
||||
};
|
||||
</script>
|
||||
175
views/admin/home/sections/blogPreview.ejs
Normal file
175
views/admin/home/sections/blogPreview.ejs
Normal file
@@ -0,0 +1,175 @@
|
||||
<!-- Blog Preview Tab -->
|
||||
<div class="tab-pane fade" id="blogpreview" role="tabpanel">
|
||||
<div class="row g-4">
|
||||
<!-- Basic Info -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white d-flex justify-content-between align-items-center">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-info-circle me-2"></i>Basic Information & Blog Selection
|
||||
</h6>
|
||||
<span class="badge bg-info text-dark">CMS will automatically fetch the 3 latest posts if no specific blog is
|
||||
selected.</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Heading</label>
|
||||
<input type="text" class="form-control" id="blogPreviewHeading"
|
||||
value="<%= data.blogPreview?.heading || '' %>" placeholder="e.g., Latest Insights & Updates" />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Subheading</label>
|
||||
<input type="text" class="form-control" id="blogPreviewSubheading"
|
||||
value="<%= data.blogPreview?.subheading || '' %>" placeholder="e.g., Visa Tips & Guides" />
|
||||
</div>
|
||||
|
||||
<div class="col-md-12 mt-4">
|
||||
<label class="form-label fw-bold"><i class="fas fa-check-square me-2"></i>Select Featured Blogs (Direct
|
||||
from Blog Module)</label>
|
||||
<p class="text-muted small mb-3">Select blog posts to prioritize on the home page. If none are selected,
|
||||
the system will use the 3 latest posts.</p>
|
||||
<div class="row g-3 blog-selector-container"
|
||||
style="max-height: 400px; overflow-y: auto; border: 1px solid #eee; padding: 15px; border-radius: 8px;">
|
||||
<% if (allBlogs && allBlogs.length> 0) { %>
|
||||
<% allBlogs.forEach(blog=> {
|
||||
const isSelected = data.blogPreview?.selectedBlogIds && data.blogPreview.selectedBlogIds.some(id =>
|
||||
id.toString() === blog._id.toString());
|
||||
%>
|
||||
<div class="col-md-4">
|
||||
<div class="card h-100 blog-select-card <%= isSelected ? 'border-primary bg-light' : '' %>"
|
||||
onclick="toggleBlogSelection(this, '<%= blog._id %>')"
|
||||
style="cursor: pointer; transition: all 0.2s;">
|
||||
<div class="position-absolute top-0 end-0 m-2">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input blog-checkbox" type="checkbox" value="<%= blog._id %>"
|
||||
<%=isSelected ? 'checked' : '' %> onclick="event.stopPropagation();
|
||||
handleCheckboxChange(this)">
|
||||
</div>
|
||||
</div>
|
||||
<img
|
||||
src="<%= blog.featuredImage ? getFullImageUrl(blog.featuredImage, backendUrl) : '/assets/img/placeholder.jpg' %>"
|
||||
class="card-img-top" style="height: 210px; object-fit: cover;">
|
||||
<div class="card-body p-2">
|
||||
<h6 class="card-title small fw-bold mb-1" title="<%= blog.title %>"
|
||||
style="display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; height: 2.6em; line-height: 1.3em;">
|
||||
<%= blog.title %>
|
||||
</h6>
|
||||
<p class="card-text tiny text-muted mb-0">
|
||||
<%= blog.publishedAt ? new Date(blog.publishedAt).toLocaleDateString('vi-VN') : '' %>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% }) %>
|
||||
<% } else { %>
|
||||
<div class="col-12 text-center py-4">
|
||||
<p class="text-muted">No published blogs found. Please create some blogs first.</p>
|
||||
<a href="/admin/blog/create" class="btn btn-sm btn-outline-primary">Create Blog</a>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CTA Button -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-mouse-pointer me-2"></i>CTA Button
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Label</label>
|
||||
<input type="text" class="form-control" id="blogPreviewCtaLabel"
|
||||
value="<%= data.blogPreview?.ctaButton?.label || '' %>" placeholder="e.g., View All Articles" />
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Link</label>
|
||||
<input type="text" class="form-control" id="blogPreviewCtaHref"
|
||||
value="<%= data.blogPreview?.ctaButton?.href || '' %>" placeholder="/blog" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function toggleBlogSelection(card, blogId) {
|
||||
const checkbox = card.querySelector('.blog-checkbox');
|
||||
const isChecking = !checkbox.checked;
|
||||
|
||||
if (isChecking) {
|
||||
const checkedCount = document.querySelectorAll('.blog-checkbox:checked').length;
|
||||
if (checkedCount >= 3) {
|
||||
alert('You can only select up to 3 blogs.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
checkbox.checked = isChecking;
|
||||
handleCheckboxUpdate(card, checkbox.checked);
|
||||
}
|
||||
|
||||
function handleCheckboxChange(checkbox) {
|
||||
if (checkbox.checked) {
|
||||
const checkedCount = document.querySelectorAll('.blog-checkbox:checked').length;
|
||||
if (checkedCount > 3) {
|
||||
checkbox.checked = false;
|
||||
alert('You can only select up to 3 blogs.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
const card = checkbox.closest('.blog-select-card');
|
||||
handleCheckboxUpdate(card, checkbox.checked);
|
||||
}
|
||||
|
||||
function handleCheckboxUpdate(card, isChecked) {
|
||||
if (isChecked) {
|
||||
card.classList.add('border-primary', 'bg-light');
|
||||
} else {
|
||||
card.classList.remove('border-primary', 'bg-light');
|
||||
}
|
||||
}
|
||||
|
||||
// Đăng ký scraper cho Blog Preview
|
||||
window.homeScrapers = window.homeScrapers || {};
|
||||
window.homeScrapers.blogPreview = () => {
|
||||
const selectedIds = [];
|
||||
document.querySelectorAll('.blog-checkbox:checked').forEach(cb => {
|
||||
selectedIds.push(cb.value);
|
||||
});
|
||||
|
||||
// Chúng ta vẫn giữ cấu trúc cũ cho items nếu muốn preview offline,
|
||||
// nhưng server sẽ ưu tiên dùng selectedBlogIds để populate dữ liệu mới nhất.
|
||||
return {
|
||||
heading: document.getElementById('blogPreviewHeading').value,
|
||||
subheading: document.getElementById('blogPreviewSubheading').value,
|
||||
ctaButton: {
|
||||
label: document.getElementById('blogPreviewCtaLabel').value,
|
||||
href: document.getElementById('blogPreviewCtaHref').value
|
||||
},
|
||||
selectedBlogIds: selectedIds,
|
||||
items: [] // Server side will handle full items content
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.tiny {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
.blog-select-card:hover {
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
</style>
|
||||
124
views/admin/home/sections/faq.ejs
Normal file
124
views/admin/home/sections/faq.ejs
Normal file
@@ -0,0 +1,124 @@
|
||||
<!-- FAQ Tab -->
|
||||
<div class="tab-pane fade" id="faq" role="tabpanel">
|
||||
<div class="row g-4">
|
||||
<!-- Basic Info -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-info-circle me-2"></i>Basic Information
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Heading</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="faqHeading"
|
||||
value="<%= data.faq?.heading || '' %>"
|
||||
placeholder="e.g., Got Questions? We've Got Answers"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Subheading</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="faqSubheading"
|
||||
value="<%= data.faq?.subheading || '' %>"
|
||||
placeholder="e.g., Visa FAQs"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Description</label>
|
||||
<textarea
|
||||
class="form-control"
|
||||
id="faqDescription"
|
||||
rows="3"
|
||||
placeholder="Enter description"
|
||||
><%= data.faq?.description || '' %></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- FAQ Items -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-question-circle me-2"></i>FAQ Items
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<% (data.faq?.items || []).forEach(function(item, index) { %>
|
||||
<div class="card mb-3 bg-light border">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title fw-bold mb-3">FAQ <%= index + 1 %></h6>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Question</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="faqQuestion_<%= index %>"
|
||||
value="<%= item.question || '' %>"
|
||||
placeholder="Enter question"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Answer</label>
|
||||
<textarea
|
||||
class="form-control"
|
||||
id="faqAnswer_<%= index %>"
|
||||
rows="3"
|
||||
placeholder="Enter answer"
|
||||
><%= item.answer || '' %></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% }); %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CTA Button -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-mouse-pointer me-2"></i>CTA Button
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Label</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="faqCtaLabel"
|
||||
value="<%= data.faq?.ctaButton?.label || '' %>"
|
||||
placeholder="e.g., contact us"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Link</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="faqCtaHref"
|
||||
value="<%= data.faq?.ctaButton?.href || '' %>"
|
||||
placeholder="/contact"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
157
views/admin/home/sections/hero.ejs
Normal file
157
views/admin/home/sections/hero.ejs
Normal file
@@ -0,0 +1,157 @@
|
||||
<!-- Hero Tab -->
|
||||
<div class="tab-pane fade show active" id="hero" role="tabpanel">
|
||||
<div class="row g-4">
|
||||
<!-- Basic Info -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-info-circle me-2"></i>Basic Information
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Title</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="heroTitle"
|
||||
value="<%= data.hero?.title || '' %>"
|
||||
placeholder="e.g., From Application to Visa"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Subtitle</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="heroSubtitle"
|
||||
value="<%= data.hero?.subtitle || '' %>"
|
||||
placeholder="e.g., Global Education Simplified"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Description</label>
|
||||
<textarea
|
||||
class="form-control"
|
||||
id="heroDescription"
|
||||
rows="3"
|
||||
placeholder="Enter hero description"
|
||||
><%= data.hero?.description || '' %></textarea>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Background Image</label>
|
||||
<div class="input-group mb-2">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="heroBackgroundImage"
|
||||
value="<%= data.hero?.backgroundImage || '' %>"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-outline-primary btn-upload-image"
|
||||
data-target-input="heroBackgroundImage"
|
||||
data-image-type="home"
|
||||
>
|
||||
<i class="fas fa-upload me-1"></i>Upload
|
||||
</button>
|
||||
</div>
|
||||
<% if (data.hero?.backgroundImage) { %>
|
||||
<div class="mt-2">
|
||||
<img
|
||||
src="<%= data.hero.backgroundImage %>"
|
||||
class="img-thumbnail"
|
||||
style="height: 200px; width: 100%; object-fit: cover;"
|
||||
alt="Background preview"
|
||||
/>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Video URL</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="heroVideoUrl"
|
||||
value="<%= data.hero?.videoUrl || '' %>"
|
||||
placeholder="https://www.youtube.com/watch?v=..."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Primary Button -->
|
||||
<div class="col-md-6">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-mouse-pointer me-2"></i>Primary Button
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Label</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="heroPrimaryButtonLabel"
|
||||
value="<%= data.hero?.primaryButton?.label || '' %>"
|
||||
placeholder="e.g., Apply now"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Link</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="heroPrimaryButtonHref"
|
||||
value="<%= data.hero?.primaryButton?.href || '' %>"
|
||||
placeholder="/contact"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Secondary Button -->
|
||||
<div class="col-md-6">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-mouse-pointer me-2"></i>Secondary Button
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Label</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="heroSecondaryButtonLabel"
|
||||
value="<%= data.hero?.secondaryButton?.label || '' %>"
|
||||
placeholder="e.g., Book Free Consultation"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Link</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="heroSecondaryButtonHref"
|
||||
value="<%= data.hero?.secondaryButton?.href || '' %>"
|
||||
placeholder="/contact"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
150
views/admin/home/sections/partners.ejs
Normal file
150
views/admin/home/sections/partners.ejs
Normal file
@@ -0,0 +1,150 @@
|
||||
<!-- Partners Tab -->
|
||||
<div class="tab-pane fade" id="partners" role="tabpanel">
|
||||
<div class="row g-4">
|
||||
<!-- Visa Consultancy Awards -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-award me-2"></i>Awards & Certifications (Fixed 4 Items)
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div id="visaConsultancyContainer">
|
||||
<% for(let i=0; i<4; i++) {
|
||||
const item = (data.partners?.visaConsultancy?.items && data.partners.visaConsultancy.items[i]) || {};
|
||||
%>
|
||||
<div class="card mb-3 bg-light border visa-item">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h6 class="card-title fw-bold mb-0">Award #<%= i + 1 %></h6>
|
||||
</div>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-8">
|
||||
<label class="form-label fw-medium">Award Name</label>
|
||||
<input type="text" class="form-control visa-name" value="<%= item.name || '' %>" placeholder="Award Name" />
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label fw-medium">Year</label>
|
||||
<input type="text" class="form-control visa-year" value="<%= item.year || '' %>" placeholder="e.g., 2025" />
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Icon / Logo</label>
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control visa-icon" id="visaIcon_<%= i %>" value="<%= item.icon || '' %>" />
|
||||
<button type="button" class="btn btn-outline-primary btn-upload-image"
|
||||
data-target-input="visaIcon_<%= i %>" data-image-type="home">
|
||||
<i class="fas fa-upload me-1"></i>Upload
|
||||
</button>
|
||||
</div>
|
||||
<div class="mt-2 preview-container">
|
||||
<img src="<%= item.icon || '' %>" class="img-thumbnail <%= item.icon ? '' : 'd-none' %>" style="height: 60px; object-fit: contain;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Brand Logos -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white d-flex justify-content-between align-items-center">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-images me-2"></i>Brand Partner Logos (Slider)
|
||||
</h6>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary" onclick="addBrandPartnerItem()">
|
||||
<i class="fas fa-plus me-1"></i>Add Logo
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div id="brandPartnersContainer" class="row g-3">
|
||||
<% (data.partners?.brands?.items || []).forEach(function(item, index) { %>
|
||||
<div class="col-md-4 brand-partner-item">
|
||||
<div class="card border bg-light h-100">
|
||||
<div class="card-body py-2">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<span class="small fw-bold">Brand Logo</span>
|
||||
<button type="button" class="btn btn-link text-danger p-0" onclick="this.closest('.brand-partner-item').remove()">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="text" class="form-control brand-logo-input" id="brandLogo_<%= index %>" value="<%= item.logo || '' %>" />
|
||||
<button type="button" class="btn btn-outline-primary btn-upload-image"
|
||||
data-target-input="brandLogo_<%= index %>" data-image-type="home">
|
||||
<i class="fas fa-upload"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="mt-2 text-center preview-container">
|
||||
<img src="<%= item.logo || '' %>" class="img-thumbnail <%= item.logo ? '' : 'd-none' %>" style="height: 50px; object-fit: contain;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% }); %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Thu thập dữ liệu partners
|
||||
window.homeScrapers = window.homeScrapers || {};
|
||||
window.homeScrapers.partners = function() {
|
||||
const visaItems = [];
|
||||
document.querySelectorAll('.visa-item').forEach(el => {
|
||||
visaItems.push({
|
||||
name: el.querySelector('.visa-name').value,
|
||||
year: el.querySelector('.visa-year').value,
|
||||
icon: el.querySelector('.visa-icon').value
|
||||
});
|
||||
});
|
||||
|
||||
const brandItems = [];
|
||||
document.querySelectorAll('.brand-partner-item').forEach(el => {
|
||||
const logo = el.querySelector('.brand-logo-input').value;
|
||||
if (logo) brandItems.push({ logo: logo });
|
||||
});
|
||||
|
||||
return {
|
||||
visaConsultancy: { items: visaItems },
|
||||
brands: { items: brandItems }
|
||||
};
|
||||
};
|
||||
|
||||
function addBrandPartnerItem() {
|
||||
const container = document.getElementById('brandPartnersContainer');
|
||||
const id = 'brandLogo_' + Date.now();
|
||||
const div = document.createElement('div');
|
||||
div.className = 'col-md-4 brand-partner-item';
|
||||
div.innerHTML = `
|
||||
<div class="card border bg-light h-100">
|
||||
<div class="card-body py-2">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<span class="small fw-bold">New Brand Logo</span>
|
||||
<button type="button" class="btn btn-link text-danger p-0" onclick="this.closest('.brand-partner-item').remove()">
|
||||
<i class="fas fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="input-group input-group-sm">
|
||||
<input type="text" class="form-control brand-logo-input" id="${id}">
|
||||
<button type="button" class="btn btn-outline-primary btn-upload-image" data-target-input="${id}" data-image-type="home">
|
||||
<i class="fas fa-upload"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="mt-2 text-center preview-container">
|
||||
<img src="" class="img-thumbnail d-none" style="height: 50px; object-fit: contain;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
container.appendChild(div);
|
||||
}
|
||||
</script>
|
||||
159
views/admin/home/sections/testimonials.ejs
Normal file
159
views/admin/home/sections/testimonials.ejs
Normal file
@@ -0,0 +1,159 @@
|
||||
<!-- Testimonials Tab -->
|
||||
<div class="tab-pane fade" id="testimonials" role="tabpanel">
|
||||
<div class="row g-4">
|
||||
<!-- Basic Info -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-info-circle me-2"></i>Basic Information
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Heading</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="testimonialsHeading"
|
||||
value="<%= data.testimonials?.heading || '' %>"
|
||||
placeholder="e.g., Student Reviews & Testimonials"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Subheading</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="testimonialsSubheading"
|
||||
value="<%= data.testimonials?.subheading || '' %>"
|
||||
placeholder="e.g., What Our Students Say"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Video URL</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="testimonialsVideoUrl"
|
||||
value="<%= data.testimonials?.videoUrl || '' %>"
|
||||
placeholder="https://www.youtube.com/watch?v=..."
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Video Thumbnail</label>
|
||||
<div class="input-group mb-2">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="testimonialsVideoThumbnail"
|
||||
value="<%= data.testimonials?.videoThumbnail || '' %>"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-outline-primary btn-upload-image"
|
||||
data-target-input="testimonialsVideoThumbnail"
|
||||
data-image-type="home"
|
||||
>
|
||||
<i class="fas fa-upload me-1"></i>Upload
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Testimonial Items -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-comments me-2"></i>Testimonials
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<% (data.testimonials?.items || []).forEach(function(item, index) { %>
|
||||
<div class="card mb-3 bg-light border">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title fw-bold mb-3">Testimonial <%= index + 1 %></h6>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Name</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="testimonialsName_<%= index %>"
|
||||
value="<%= item.name || '' %>"
|
||||
placeholder="e.g., Sohel Tanvir"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Role</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="testimonialsRole_<%= index %>"
|
||||
value="<%= item.role || '' %>"
|
||||
placeholder="e.g., Student"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Country</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="testimonialsCountry_<%= index %>"
|
||||
value="<%= item.country || '' %>"
|
||||
placeholder="e.g., Canada"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Rating</label>
|
||||
<input
|
||||
type="number"
|
||||
class="form-control"
|
||||
id="testimonialsRating_<%= index %>"
|
||||
value="<%= item.rating || 5 %>"
|
||||
min="1"
|
||||
max="5"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Comment</label>
|
||||
<textarea
|
||||
class="form-control"
|
||||
id="testimonialsComment_<%= index %>"
|
||||
rows="3"
|
||||
placeholder="Enter testimonial comment"
|
||||
><%= item.comment || '' %></textarea>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Avatar</label>
|
||||
<div class="input-group mb-2">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="testimonialsAvatar_<%= index %>"
|
||||
value="<%= item.avatar || '' %>"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-outline-primary btn-upload-image"
|
||||
data-target-input="testimonialsAvatar_<%= index %>"
|
||||
data-image-type="home"
|
||||
>
|
||||
<i class="fas fa-upload me-1"></i>Upload
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% }); %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
67
views/admin/home/sections/videoGallery.ejs
Normal file
67
views/admin/home/sections/videoGallery.ejs
Normal file
@@ -0,0 +1,67 @@
|
||||
<!-- Video Gallery Tab -->
|
||||
<div class="tab-pane fade" id="videogallery" role="tabpanel">
|
||||
<div class="row g-4">
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-video me-2"></i>Video Gallery
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Heading</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="videoGalleryHeading"
|
||||
value="<%= data.videoGallery?.heading || '' %>"
|
||||
placeholder="e.g., VIDEO PLAY GALLERY"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Video URL</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="videoGalleryVideoUrl"
|
||||
value="<%= data.videoGallery?.videoUrl || '' %>"
|
||||
placeholder="https://example.com/video.mp4"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Thumbnail Image</label>
|
||||
<div class="input-group mb-2">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="videoGalleryThumbnail"
|
||||
value="<%= data.videoGallery?.thumbnail || '' %>"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-outline-primary btn-upload-image"
|
||||
data-target-input="videoGalleryThumbnail"
|
||||
data-image-type="home"
|
||||
>
|
||||
<i class="fas fa-upload me-1"></i>Upload
|
||||
</button>
|
||||
</div>
|
||||
<% if (data.videoGallery?.thumbnail) { %>
|
||||
<div class="mt-2">
|
||||
<img
|
||||
src="<%= data.videoGallery.thumbnail %>"
|
||||
class="img-thumbnail"
|
||||
style="height: 200px; width: 100%; object-fit: cover;"
|
||||
alt="Thumbnail preview"
|
||||
/>
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
163
views/admin/home/sections/visaCountries.ejs
Normal file
163
views/admin/home/sections/visaCountries.ejs
Normal file
@@ -0,0 +1,163 @@
|
||||
<!-- Visa Countries Tab -->
|
||||
<div class="tab-pane fade" id="visacountries" role="tabpanel">
|
||||
<div class="row g-4">
|
||||
<!-- Basic Info -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-info-circle me-2"></i>Basic Information
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Heading</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="visaCountriesHeading"
|
||||
value="<%= data.visaCountries?.heading || '' %>"
|
||||
placeholder="e.g., Visa & VISAWAY Services To UK"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Subheading</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="visaCountriesSubheading"
|
||||
value="<%= data.visaCountries?.subheading || '' %>"
|
||||
placeholder="e.g., UK. United Kingdom"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Description</label>
|
||||
<textarea
|
||||
class="form-control"
|
||||
id="visaCountriesDescription"
|
||||
rows="3"
|
||||
placeholder="Enter description"
|
||||
><%= data.visaCountries?.description || '' %></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Countries -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-globe me-2"></i>Countries
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<% (data.visaCountries?.countries || []).forEach(function(country, index) { %>
|
||||
<div class="card mb-3 bg-light border">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title fw-bold mb-3">Country <%= index + 1 %></h6>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Country Name</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="visaCountriesName_<%= index %>"
|
||||
value="<%= country.name || '' %>"
|
||||
placeholder="e.g., United Kingdom"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Country Code</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="visaCountriesCode_<%= index %>"
|
||||
value="<%= country.code || '' %>"
|
||||
placeholder="e.g., UK"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Flag Image</label>
|
||||
<div class="input-group mb-2">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="visaCountriesFlag_<%= index %>"
|
||||
value="<%= country.flag || '' %>"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-outline-primary btn-upload-image"
|
||||
data-target-input="visaCountriesFlag_<%= index %>"
|
||||
data-image-type="home"
|
||||
>
|
||||
<i class="fas fa-upload me-1"></i>Upload
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Link</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="visaCountriesLink_<%= index %>"
|
||||
value="<%= country.link || '' %>"
|
||||
placeholder="/country-details/uk"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Visa Types (comma-separated)</label>
|
||||
<textarea
|
||||
class="form-control"
|
||||
id="visaCountriesVisaTypes_<%= index %>"
|
||||
rows="2"
|
||||
placeholder="e.g., Student Visa, Work Visa, Tourist Visa"
|
||||
><%= (country.visaTypes || []).join(', ') %></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% }); %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CTA Button -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-mouse-pointer me-2"></i>CTA Button
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Label</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="visaCountriesCtaLabel"
|
||||
value="<%= data.visaCountries?.ctaButton?.label || '' %>"
|
||||
placeholder="e.g., Get Started"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Link</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="visaCountriesCtaHref"
|
||||
value="<%= data.visaCountries?.ctaButton?.href || '' %>"
|
||||
placeholder="/contact"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
100
views/admin/home/sections/visaSolutions.ejs
Normal file
100
views/admin/home/sections/visaSolutions.ejs
Normal file
@@ -0,0 +1,100 @@
|
||||
<!-- Visa Solutions Tab -->
|
||||
<div class="tab-pane fade" id="visasolutions" role="tabpanel">
|
||||
<div class="row g-4">
|
||||
<!-- Basic Info -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-info-circle me-2"></i>Basic Information
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Heading</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="visaSolutionsHeading"
|
||||
value="<%= data.visaSolutions?.heading || '' %>"
|
||||
placeholder="e.g., Comprehensive Visa Solutions"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Subheading</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="visaSolutionsSubheading"
|
||||
value="<%= data.visaSolutions?.subheading || '' %>"
|
||||
placeholder="e.g., Our Expert Services"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Services Items -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-list-ul me-2"></i>Visa Solutions Items
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<% (data.visaSolutions?.items || []).forEach(function(item, index) { %>
|
||||
<div class="card mb-3 bg-light border">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title fw-bold mb-3">Service <%= index + 1 %></h6>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label fw-medium">Number</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="visaSolutionsNumber_<%= index %>"
|
||||
value="<%= item.number || '' %>"
|
||||
placeholder="e.g., 01"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<label class="form-label fw-medium">Title</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="visaSolutionsTitle_<%= index %>"
|
||||
value="<%= item.title || '' %>"
|
||||
placeholder="e.g., Student Visa Guidance"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Description</label>
|
||||
<textarea
|
||||
class="form-control"
|
||||
id="visaSolutionsDescription_<%= index %>"
|
||||
rows="2"
|
||||
placeholder="Enter description"
|
||||
><%= item.description || '' %></textarea>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Link</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="visaSolutionsLink_<%= index %>"
|
||||
value="<%= item.link || '' %>"
|
||||
placeholder="/service-details"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% }); %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
169
views/admin/home/sections/whyChooseUs.ejs
Normal file
169
views/admin/home/sections/whyChooseUs.ejs
Normal file
@@ -0,0 +1,169 @@
|
||||
<!-- Why Choose Us Tab -->
|
||||
<div class="tab-pane fade" id="whychooseus" role="tabpanel">
|
||||
<div class="row g-4">
|
||||
<!-- Basic Info -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-info-circle me-2"></i>Basic Information
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Heading</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="whyChooseUsHeading"
|
||||
value="<%= data.whyChooseUs?.heading || '' %>"
|
||||
placeholder="e.g., Turning Study Abroad Dreams Into Reality"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Subheading</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="whyChooseUsSubheading"
|
||||
value="<%= data.whyChooseUs?.subheading || '' %>"
|
||||
placeholder="e.g., About Our Consultancy"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Description</label>
|
||||
<textarea
|
||||
class="form-control"
|
||||
id="whyChooseUsDescription"
|
||||
rows="3"
|
||||
placeholder="Enter description"
|
||||
><%= data.whyChooseUs?.description || '' %></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Items -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-list-ul me-2"></i>Why Choose Us Items
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<% (data.whyChooseUs?.items || []).forEach(function(item, index) { %>
|
||||
<div class="card mb-3 bg-light border">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title fw-bold mb-3">Item <%= index + 1 %></h6>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Icon URL</label>
|
||||
<div class="input-group mb-2">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="whyChooseUsIcon_<%= index %>"
|
||||
value="<%= item.icon || '' %>"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-outline-primary btn-upload-image"
|
||||
data-target-input="whyChooseUsIcon_<%= index %>"
|
||||
data-image-type="home"
|
||||
>
|
||||
<i class="fas fa-upload me-1"></i>Upload
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Title</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="whyChooseUsTitle_<%= index %>"
|
||||
value="<%= item.title || '' %>"
|
||||
placeholder="e.g., Global Reach"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label fw-medium">Description</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="whyChooseUsItemDescription_<%= index %>"
|
||||
value="<%= item.description || '' %>"
|
||||
placeholder="e.g., Expanding Opportunities Worldwide"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% }); %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Features -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-star me-2"></i>Features
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<% (data.whyChooseUs?.features || []).forEach(function(feature, index) { %>
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-medium">Feature <%= index + 1 %></label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="whyChooseUsFeature_<%= index %>"
|
||||
value="<%= feature %>"
|
||||
placeholder="Enter feature"
|
||||
/>
|
||||
</div>
|
||||
<% }); %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- CTA Button -->
|
||||
<div class="col-md-12">
|
||||
<div class="card border shadow-sm">
|
||||
<div class="card-header bg-white">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-mouse-pointer me-2"></i>CTA Button
|
||||
</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Label</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="whyChooseUsCtaLabel"
|
||||
value="<%= data.whyChooseUs?.ctaButton?.label || '' %>"
|
||||
placeholder="e.g., Get Started"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label fw-medium">Link</label>
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
id="whyChooseUsCtaHref"
|
||||
value="<%= data.whyChooseUs?.ctaButton?.href || '' %>"
|
||||
placeholder="/about"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user