forked from UKSOURCE/cms.hailearning.edu.vn
fea/nhat-dat-11042026-merge #1
@@ -42,6 +42,7 @@ exports.index = async (req, res) => {
|
|||||||
socialLinks: header.top?.socialLinks || [],
|
socialLinks: header.top?.socialLinks || [],
|
||||||
},
|
},
|
||||||
logo: header.logo?.light || "",
|
logo: header.logo?.light || "",
|
||||||
|
header: header,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
topbar: {
|
topbar: {
|
||||||
@@ -53,6 +54,7 @@ exports.index = async (req, res) => {
|
|||||||
socialLinks: [],
|
socialLinks: [],
|
||||||
},
|
},
|
||||||
logo: "",
|
logo: "",
|
||||||
|
header: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
const activeTab = req.query.tab || "topbar";
|
const activeTab = req.query.tab || "topbar";
|
||||||
@@ -172,40 +174,28 @@ exports.update = async (req, res) => {
|
|||||||
location: parsedData.contactInfo?.location || "",
|
location: parsedData.contactInfo?.location || "",
|
||||||
socialLinks: parsedData.socialLinks || [],
|
socialLinks: parsedData.socialLinks || [],
|
||||||
};
|
};
|
||||||
|
} catch (parseErr) {
|
||||||
|
console.error("✗ Error parsing topbarJson:", parseErr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (logo) {
|
// Nếu có offcanvasJson, parse nó
|
||||||
updateData.logo = logoData;
|
const { offcanvasJson } = req.body;
|
||||||
}
|
if (offcanvasJson && typeof offcanvasJson === "string") {
|
||||||
|
try {
|
||||||
console.log(
|
const parsedOffcanvas = JSON.parse(offcanvasJson);
|
||||||
"Preparing to update header with data:",
|
console.log("✓ Parsed offcanvasJson successfully:", parsedOffcanvas);
|
||||||
JSON.stringify(updateData, null, 2),
|
offcanvas = {
|
||||||
);
|
description: parsedOffcanvas.description || "",
|
||||||
|
contactInfo: {
|
||||||
const updatedHeader = await Header.findByIdAndUpdate(
|
address: parsedOffcanvas.contactInfo?.address || "",
|
||||||
headerId,
|
email: parsedOffcanvas.contactInfo?.email || "",
|
||||||
updateData,
|
workingHours: parsedOffcanvas.contactInfo?.workingHours || "",
|
||||||
{ new: true, runValidators: true },
|
phone: parsedOffcanvas.contactInfo?.phone || "",
|
||||||
);
|
},
|
||||||
|
};
|
||||||
if (!updatedHeader) {
|
} catch (parseErr) {
|
||||||
console.error("✗ Header not found with ID:", headerId);
|
console.error("✗ Error parsing offcanvasJson:", parseErr);
|
||||||
return res.status(404).json({
|
|
||||||
success: false,
|
|
||||||
message: "Header not found",
|
|
||||||
});
|
|
||||||
}
|
|
||||||
res.json({
|
|
||||||
success: true,
|
|
||||||
message: "Header updated successfully",
|
|
||||||
data: updatedHeader,
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error("✗ Error updating header:", error);
|
|
||||||
res.status(400).json({
|
|
||||||
success: false,
|
|
||||||
message: error.message,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
<div class="content-with-fixed-buttons">
|
<div class="content-with-fixed-buttons">
|
||||||
<!-- Hidden inputs for JSON data -->
|
<!-- Hidden inputs for JSON data -->
|
||||||
<input type="hidden" name="topbarJson" id="topbarJson" />
|
<input type="hidden" name="topbarJson" id="topbarJson" />
|
||||||
|
<input type="hidden" name="offcanvasJson" id="offcanvasJson" />
|
||||||
<input type="hidden" name="logo" id="logoInput" />
|
<input type="hidden" name="logo" id="logoInput" />
|
||||||
<input type="hidden" name="activeTab" id="activeTabInput" value="topbar" />
|
<input type="hidden" name="activeTab" id="activeTabInput" value="topbar" />
|
||||||
<input type="hidden" name="menuUpdates" id="menuUpdates" />
|
<input type="hidden" name="menuUpdates" id="menuUpdates" />
|
||||||
@@ -99,6 +100,25 @@
|
|||||||
placeholder="69 Street, 5th Avenue LA, United States"
|
placeholder="69 Street, 5th Avenue LA, United States"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label fw-medium">Working Hours <small class="text-muted fw-normal">(Drawer Menu)</small></label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
id="offcanvasWorkingHours"
|
||||||
|
value="<%= (data.header && data.header.offcanvas && data.header.offcanvas.contactInfo && data.header.offcanvas.contactInfo.workingHours) ? data.header.offcanvas.contactInfo.workingHours : '' %>"
|
||||||
|
placeholder="Mon-Friday, 09am - 05pm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<label class="form-label fw-medium">Offcanvas Description <small class="text-muted fw-normal">(Drawer Menu)</small></label>
|
||||||
|
<textarea
|
||||||
|
class="form-control"
|
||||||
|
id="offcanvasDescription"
|
||||||
|
rows="3"
|
||||||
|
placeholder="Short description displayed in the offcanvas sidebar..."
|
||||||
|
><%= (data.header && data.header.offcanvas && data.header.offcanvas.description) ? data.header.offcanvas.description : '' %></textarea>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -179,6 +199,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- Menu Structure Tab -->
|
<!-- Menu Structure Tab -->
|
||||||
<div class="tab-pane fade <%= activeTab === 'menu' ? 'show active' : '' %>" id="menu" role="tabpanel">
|
<div class="tab-pane fade <%= activeTab === 'menu' ? 'show active' : '' %>" id="menu" role="tabpanel">
|
||||||
<%- include('menu') %>
|
<%- include('menu') %>
|
||||||
@@ -349,6 +370,7 @@
|
|||||||
// 1. Collect and Save Topbar & Logo
|
// 1. Collect and Save Topbar & Logo
|
||||||
const headerData = {
|
const headerData = {
|
||||||
topbarJson: document.getElementById('topbarJson').value,
|
topbarJson: document.getElementById('topbarJson').value,
|
||||||
|
offcanvasJson: document.getElementById('offcanvasJson').value,
|
||||||
logo: document.getElementById('logoInput').value,
|
logo: document.getElementById('logoInput').value,
|
||||||
activeTab: document.getElementById('activeTabInput').value
|
activeTab: document.getElementById('activeTabInput').value
|
||||||
};
|
};
|
||||||
@@ -421,6 +443,18 @@
|
|||||||
document.getElementById('topbarJson').value = JSON.stringify(topbarData);
|
document.getElementById('topbarJson').value = JSON.stringify(topbarData);
|
||||||
document.getElementById('logoInput').value = document.getElementById('logoImage').value || '';
|
document.getElementById('logoInput').value = document.getElementById('logoImage').value || '';
|
||||||
|
|
||||||
|
// Collect offcanvas data — phone/email/address shared from topbar
|
||||||
|
const offcanvasData = {
|
||||||
|
description: document.getElementById('offcanvasDescription').value || '',
|
||||||
|
contactInfo: {
|
||||||
|
phone: document.getElementById('contactPhone').value || '',
|
||||||
|
email: document.getElementById('contactEmail').value || '',
|
||||||
|
address: document.getElementById('contactLocation').value || '',
|
||||||
|
workingHours: document.getElementById('offcanvasWorkingHours').value || ''
|
||||||
|
}
|
||||||
|
};
|
||||||
|
document.getElementById('offcanvasJson').value = JSON.stringify(offcanvasData);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const menuUpdates = collectMenuUpdates();
|
const menuUpdates = collectMenuUpdates();
|
||||||
document.getElementById('menuUpdates').value = JSON.stringify(menuUpdates);
|
document.getElementById('menuUpdates').value = JSON.stringify(menuUpdates);
|
||||||
|
|||||||
Reference in New Issue
Block a user