Files
cms.techvanguard.vn/views/admin/partnerships/partials/hero-tab.ejs
T
Tống Thành Đạt a39c336dd4 feat(cms): enhance content editors with dynamic UI configs and validation
Implement a more flexible, configuration-driven approach for CMS editors across accreditation, admissions, and partnerships modules.
- Move UI labels, help texts, and field limits from hardcoded views to `editorUi` configurations in config files.
- Add server-side and client-side validation to prevent duplicate category tabs in accreditation and partnerships editors.
- Refactor partnership and admission views to dynamically render tabs and fields based on the provided configuration.
- Update field length constraints and default values across multiple content editors to better align with frontend requirements.
- Improve the admissions calculator editor with dynamic field configurations and default value fallbacks.
2026-04-22 18:06:03 +07:00

47 lines
2.7 KiB
Plaintext

<div class="tab-pane fade <%= activeTab === 'hero' ? 'show active' : '' %>" id="hero" role="tabpanel">
<% const heroUi = editorUi.hero || {}; %>
<div class="card border shadow-sm">
<div class="card-header bg-white">
<h6 class="mb-0"><i class="fas fa-image me-2"></i>Hero</h6>
</div>
<div class="card-body p-4">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label fw-semibold"><%= heroUi.badge?.label || "Eyebrow label" %></label>
<input class="form-control" id="heroBadge" maxlength="<%= heroUi.badge?.maxLength || 40 %>" value="<%= data.hero?.badge || '' %>">
</div>
<div class="col-md-6">
<label class="form-label fw-semibold"><%= heroUi.linkLabel?.label || "Scroll link label" %></label>
<input class="form-control" id="heroLinkLabel" maxlength="<%= heroUi.linkLabel?.maxLength || 40 %>" value="<%= data.hero?.linkLabel || '' %>">
</div>
<div class="col-12">
<label class="form-label fw-semibold"><%= heroUi.title?.label || "Headline" %></label>
<input class="form-control" id="heroTitle" maxlength="<%= heroUi.title?.maxLength || 90 %>" value="<%= data.hero?.title || '' %>">
</div>
<div class="col-12">
<label class="form-label fw-semibold"><%= heroUi.description?.label || "Supporting text" %></label>
<textarea class="form-control" id="heroDescription" rows="<%= heroUi.description?.rows || 4 %>" maxlength="<%= heroUi.description?.maxLength || 220 %>"><%= data.hero?.description || '' %></textarea>
</div>
<div class="col-12">
<label class="form-label fw-semibold"><%= heroUi.image?.label || "Hero image" %></label>
<div class="input-group">
<input class="form-control" id="heroImage" value="<%= data.hero?.image || '' %>">
<button class="btn btn-outline-primary" type="button" data-upload-target="heroImage" data-preview-target="heroImagePreview">
<i class="fas fa-upload me-1"></i>Upload
</button>
</div>
<div class="form-text"><%= [heroUi.image?.helpText, heroUi.image?.imageHint].filter(Boolean).join(" ") %></div>
<img id="heroImagePreview" src="<%= data.hero?.image ? `${backendUrl}${data.hero.image}` : '' %>" class="img-thumbnail mt-2 <%= data.hero?.image ? '' : 'd-none' %>" style="max-height: 200px;">
</div>
<div class="col-12">
<label class="form-label fw-semibold"><%= heroUi.imageAlt?.label || "Hero image alt text" %></label>
<input class="form-control" id="heroImageAlt" maxlength="<%= heroUi.imageAlt?.maxLength || 120 %>" value="<%= data.hero?.imageAlt || '' %>">
</div>
</div>
</div>
</div>
</div>