feat(cms): enhance content editors and implement automatic ID generation

Improve the CMS administration interface across multiple pages (Accreditation, Admissions, History, Partnerships, and Policies) with a focus on usability and data integrity.
Key changes include:
- Implement `ensureUniqueIds` utility to automatically generate and maintain unique slugs for content items, removing the need for manual ID entry in the UI.
- Refactor the Admissions calculator to support detailed per-option editing via a new dedicated view and routes.
- Replace basic datalists with a custom, searchable icon combobox component for better visual selection.
- Update `_renderSingletonPageView` to handle active tab persistence via query parameters.
- Streamline editor configurations by removing redundant fields and improving help text.
- Enhance the Admissions "Key Dates" editor with a dynamic table interface for managing columns and rows.
- Normalize data payloads in controllers to ensure consistent API responses and internal linking.
This commit is contained in:
Tống Thành Đạt
2026-04-21 12:37:19 +07:00
parent 122df1a46e
commit 5d0fae6d51
30 changed files with 2174 additions and 477 deletions
+144
View File
@@ -477,6 +477,150 @@
margin-left: auto;
}
.cms-icon-combobox {
position: relative;
}
.cms-icon-dropdown-trigger {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.75rem;
border: 1px solid rgba(148, 163, 184, 0.18);
border-radius: 10px;
background: #fff;
padding: 0.75rem;
color: #334155;
text-align: left;
}
.cms-icon-dropdown-trigger:hover {
border-color: rgba(184, 183, 106, 0.55);
background: rgba(248, 250, 252, 0.96);
}
.cms-icon-combobox.is-open .cms-icon-dropdown-trigger {
border-color: rgba(184, 183, 106, 0.65);
box-shadow: 0 0 0 0.2rem rgba(184, 183, 106, 0.12);
}
.cms-icon-dropdown-value {
display: flex;
align-items: center;
gap: 0.75rem;
min-width: 0;
flex: 1;
}
.cms-icon-dropdown-text {
min-width: 0;
display: flex;
flex-direction: column;
gap: 0.1rem;
}
.cms-icon-dropdown-text strong,
.cms-icon-dropdown-text span {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.cms-icon-dropdown-caret {
color: #94a3b8;
transition: transform 0.18s ease;
}
.cms-icon-combobox.is-open .cms-icon-dropdown-caret {
transform: rotate(180deg);
}
.cms-icon-preview {
width: 44px;
min-width: 44px;
height: 44px;
display: inline-flex;
align-items: center;
justify-content: center;
border: 1px solid rgba(148, 163, 184, 0.18);
border-radius: 8px;
background: #fff;
color: #334155;
}
.cms-icon-dropdown-panel {
position: absolute;
top: calc(100% + 0.5rem);
left: 0;
right: 0;
z-index: 30;
background: #fff;
border: 1px solid rgba(148, 163, 184, 0.18);
border-radius: 10px;
padding: 0.75rem;
box-shadow: 0 10px 30px rgba(15, 23, 42, 0.12);
}
.cms-icon-dropdown-panel .form-control {
margin-bottom: 0.75rem;
}
.cms-icon-options {
max-height: 220px;
overflow: auto;
display: flex;
flex-direction: column;
gap: 0.375rem;
}
.cms-icon-option {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.75rem;
width: 100%;
border: 1px solid rgba(148, 163, 184, 0.18);
background: #fff;
color: #334155;
border-radius: 8px;
padding: 0.55rem 0.7rem;
text-align: left;
font-size: 0.875rem;
}
.cms-icon-option-main {
min-width: 0;
display: flex;
align-items: center;
gap: 0.625rem;
}
.cms-icon-option-main span {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.cms-icon-option:hover {
border-color: rgba(184, 183, 106, 0.55);
background: rgba(248, 250, 252, 0.96);
color: #0f172a;
}
.cms-icon-option.is-active {
border-color: rgba(184, 183, 106, 0.65);
background: rgba(184, 183, 106, 0.12);
color: #0f172a;
}
.cms-icon-option-empty {
color: #94a3b8;
font-size: 0.75rem;
padding: 0.5rem 0.25rem 0;
}
main {
flex: 1;
z-index: 1;