feat: implement assets and blades layouts

This commit is contained in:
2026-08-18 18:23:49 -07:00
parent ebec702aff
commit b0848e65b9
112 changed files with 62486 additions and 88 deletions
+373
View File
@@ -0,0 +1,373 @@
(function () {
"use strict";
if (localStorage.getItem("menodarktheme")) {
document.querySelector("html").setAttribute("data-theme-mode", "dark");
document.querySelector("html").setAttribute("data-menu-styles", "dark");
document.querySelector("html").setAttribute("data-header-styles", "dark");
}
if (localStorage.menortl) {
let html = document.querySelector("html");
html.setAttribute("dir", "rtl");
document
.querySelector("#style")
?.setAttribute(
"href",
"assets/libs/bootstrap/css/bootstrap.rtl.min.css"
);
}
if (localStorage.menolayout) {
let html = document.querySelector("html");
html.setAttribute("data-nav-layout", "horizontal");
document.querySelector("html").setAttribute("data-menu-styles", "light");
}
if (localStorage.getItem("menolayout") == "horizontal") {
document
.querySelector("html")
.setAttribute("data-nav-layout", "horizontal");
}
if (localStorage.loaderEnable == "true") {
document.querySelector("html").setAttribute("loader", "enable");
} else {
if (!document.querySelector("html").getAttribute("loader")) {
document.querySelector("html").setAttribute("loader", "disable");
}
}
function localStorageBackup() {
// if there is a value stored, update color picker and background color
// Used to retrive the data from local storage
if (localStorage.primaryRGB) {
if (document.querySelector(".theme-container-primary")) {
document.querySelector(".theme-container-primary").value =
localStorage.primaryRGB;
}
document
.querySelector("html")
.style.setProperty("--primary-rgb", localStorage.primaryRGB);
}
if (localStorage.bodyBgRGB && localStorage.bodylightRGB) {
if (document.querySelector(".theme-container-background")) {
document.querySelector(".theme-container-background").value =
localStorage.bodyBgRGB;
}
document
.querySelector("html")
.style.setProperty("--body-bg-rgb", localStorage.bodyBgRGB);
document
.querySelector("html")
.style.setProperty("--body-bg-rgb2", localStorage.bodylightRGB);
document
.querySelector("html")
.style.setProperty("--light-rgb", localStorage.bodylightRGB);
document
.querySelector("html")
.style.setProperty(
"--form-control-bg",
`rgb(${localStorage.bodylightRGB})`
);
document
.querySelector("html")
.style.setProperty("--gray-3", `rgb(${localStorage.bodylightRGB})`);
document
.querySelector("html")
.style.setProperty("--input-border", "rgba(255,255,255,0.1)");
let html = document.querySelector("html");
html.setAttribute("data-theme-mode", "dark");
html.setAttribute("data-menu-styles", "dark");
html.setAttribute("data-header-styles", "dark");
}
if (localStorage.menodarktheme) {
let html = document.querySelector("html");
html.setAttribute("data-theme-mode", "dark");
}
if (localStorage.menolayout) {
let html = document.querySelector("html");
let layoutValue = localStorage.getItem("menolayout");
html.setAttribute("data-nav-layout", "horizontal");
html.setAttribute("data-nav-style", "menu-click");
// setTimeout(() => {
// clearNavDropdown();
// }, 1000);
// setTimeout(() => {
// checkHoriMenu();
// }, 5000);
}
if (localStorage.menoverticalstyles) {
let html = document.querySelector("html");
let verticalStyles = localStorage.getItem("menoverticalstyles");
if (verticalStyles == "default") {
html.setAttribute("data-vertical-style", "default");
localStorage.removeItem("menonavstyles");
}
if (verticalStyles == "closed") {
html.setAttribute("data-vertical-style", "closed");
localStorage.removeItem("menonavstyles");
}
if (verticalStyles == "icontext") {
html.setAttribute("data-vertical-style", "icontext");
localStorage.removeItem("menonavstyles");
}
if (verticalStyles == "overlay") {
html.setAttribute("data-vertical-style", "overlay");
localStorage.removeItem("menonavstyles");
}
if (verticalStyles == "detached") {
html.setAttribute("data-vertical-style", "detached");
localStorage.removeItem("menonavstyles");
}
if (verticalStyles == "doublemenu") {
html.setAttribute("data-vertical-style", "doublemenu");
localStorage.removeItem("menonavstyles");
setTimeout(() => {
const menuSlideItem = document.querySelectorAll(
".main-menu > li > .side-menu__item"
);
// Create the tooltip element
const tooltip = document.createElement("div");
tooltip.className = "custome-tooltip";
// Set the CSS properties of the tooltip element
tooltip.style.setProperty("position", "fixed");
tooltip.style.setProperty("display", "none");
tooltip.style.setProperty("padding", "0.5rem");
tooltip.style.setProperty("font-weight", "500");
tooltip.style.setProperty("font-size", "0.75rem");
tooltip.style.setProperty("background-color", "rgb(15, 23 ,42)");
tooltip.style.setProperty("color", "rgb(255, 255 ,255)");
tooltip.style.setProperty("margin-inline-start", "48px");
tooltip.style.setProperty("border-radius", "0.25rem");
tooltip.style.setProperty("z-index", "99");
menuSlideItem.forEach((e) => {
// Add an event listener to the menu slide item to show the tooltip
e.addEventListener("mouseenter", () => {
if (localStorage.menoverticalstyles == "doublemenu") {
tooltip.style.setProperty("display", "block");
tooltip.textContent =
e.querySelector(".side-menu__label").textContent;
if (
document
.querySelector("html")
.getAttribute("data-vertical-style") == "doublemenu"
) {
e.appendChild(tooltip);
}
}
});
// Add an event listener to hide the tooltip
e.addEventListener("mouseleave", () => {
tooltip.style.setProperty("display", "none");
tooltip.textContent =
e.querySelector(".side-menu__label").textContent;
});
});
}, 1000);
}
}
if (localStorage.menonavstyles) {
let html = document.querySelector("html");
let navStyles = localStorage.getItem("menonavstyles");
if (navStyles == "menu-click") {
html.setAttribute("data-nav-style", "menu-click");
localStorage.removeItem("menoverticalstyles");
html.removeAttribute("data-vertical-style");
}
if (navStyles == "menu-hover") {
html.setAttribute("data-nav-style", "menu-hover");
localStorage.removeItem("menoverticalstyles");
html.removeAttribute("data-vertical-style");
}
if (navStyles == "icon-click") {
html.setAttribute("data-nav-style", "icon-click");
localStorage.removeItem("menoverticalstyles");
html.removeAttribute("data-vertical-style");
}
if (navStyles == "icon-hover") {
html.setAttribute("data-nav-style", "icon-hover");
localStorage.removeItem("menoverticalstyles");
html.removeAttribute("data-vertical-style");
}
}
if (localStorage.menoclassic) {
let html = document.querySelector("html");
html.setAttribute("data-page-style", "classic");
}
if (localStorage.menomodern) {
let html = document.querySelector("html");
html.setAttribute("data-page-style", "modern");
}
if (localStorage.menoboxed) {
let html = document.querySelector("html");
html.setAttribute("data-width", "boxed");
}
if (localStorage.menofullwidth) {
let html = document.querySelector("html");
html.setAttribute("data-width", "fullwidth");
}
if (localStorage.menodefaultwidth) {
let html = document.querySelector("html");
html.setAttribute("data-width", "default");
}
if (localStorage.menoheaderfixed) {
let html = document.querySelector("html");
html.setAttribute("data-header-position", "fixed");
}
if (localStorage.menoheaderscrollable) {
let html = document.querySelector("html");
html.setAttribute("data-header-position", "scrollable");
}
if (localStorage.menomenufixed) {
let html = document.querySelector("html");
html.setAttribute("data-menu-position", "fixed");
}
if (localStorage.menomenuscrollable) {
let html = document.querySelector("html");
html.setAttribute("data-menu-position", "scrollable");
}
if (localStorage.menoMenu) {
let html = document.querySelector("html");
let menuValue = localStorage.getItem("menoMenu");
switch (menuValue) {
case "light":
html.setAttribute("data-menu-styles", "light");
break;
case "dark":
html.setAttribute("data-menu-styles", "dark");
break;
case "color":
html.setAttribute("data-menu-styles", "color");
break;
case "gradient":
html.setAttribute("data-menu-styles", "gradient");
break;
case "transparent":
html.setAttribute("data-menu-styles", "transparent");
break;
default:
break;
}
}
if (localStorage.menoHeader) {
let html = document.querySelector("html");
let headerValue = localStorage.getItem("menoHeader");
html.setAttribute("data-header-styles", headerValue);
}
if (localStorage.bgimg) {
let html = document.querySelector("html");
let value = localStorage.getItem("bgimg");
html.setAttribute("data-bg-img", value);
}
}
localStorageBackup();
// keep chosen files here (useful when uploading)
let selectedFiles = [];
document.addEventListener('DOMContentLoaded', () => {
const input = document.getElementById('imageInput');
if (input) {
input.addEventListener('change', previewImages);
}
// Optional: allow dropping files onto the placeholder
const placeholder = document.getElementById('uploadPlaceholder');
if (placeholder) {
placeholder.addEventListener('dragover', e => {
e.preventDefault();
placeholder.style.borderColor = '#555';
});
placeholder.addEventListener('dragleave', e => {
placeholder.style.borderColor = '#cfcfcf';
});
placeholder.addEventListener('drop', e => {
e.preventDefault();
placeholder.style.borderColor = '#cfcfcf';
const dtFiles = Array.from(e.dataTransfer.files || []);
// Use same handler as input: create a fake event-like object with .files
previewImages({ target: { files: dtFiles } });
});
}
});
// Update the actual input.files property to match selectedFiles using DataTransfer
function updateInputFiles() {
const dataTransfer = new DataTransfer();
selectedFiles.forEach(file => dataTransfer.items.add(file));
const input = document.getElementById('imageInput');
input.files = dataTransfer.files;
}
function previewImages(event) {
const container = document.getElementById('imagePreviewContainer');
const uploadPlaceholder = document.getElementById('uploadPlaceholder');
const newFiles = Array.from(event.target.files || []);
if (!newFiles.length) return;
newFiles.forEach(file => {
if (!file.type.startsWith('image/')) return;
// avoid exact duplicates (same name + size)
if (selectedFiles.some(f => f.name === file.name && f.size === file.size)) {
return;
}
selectedFiles.push(file);
const reader = new FileReader();
reader.onload = function(e) {
const wrapper = document.createElement('div');
wrapper.className = 'preview-item';
wrapper.style.position = 'relative';
wrapper.style.width = '150px';
wrapper.style.height = '150px';
wrapper.style.marginRight = '8px';
const img = document.createElement('img');
img.src = e.target.result;
img.alt = file.name;
img.style.width = '100%';
img.style.height = '100%';
img.style.objectFit = 'cover';
img.className = 'img-fluid rounded';
const btn = document.createElement('button');
btn.type = 'button';
btn.className = 'remove-btn btn btn-sm btn-danger position-absolute top-0 end-0';
btn.innerText = '×';
btn.title = 'Remove';
btn.style.cursor = 'pointer';
// Position button at top right
btn.style.position = 'absolute';
btn.style.top = '2px';
btn.style.right = '2px';
btn.style.zIndex = '10';
btn.addEventListener('click', () => {
wrapper.remove();
selectedFiles = selectedFiles.filter(f => !(f.name === file.name && f.size === file.size));
updateInputFiles();
});
wrapper.appendChild(img);
wrapper.appendChild(btn);
// insert before the upload placeholder so the placeholder stays on the right
container.insertBefore(wrapper, uploadPlaceholder);
};
reader.readAsDataURL(file);
});
// update input.files to include all selected files
updateInputFiles();
}
// for debugging: expose selectedFiles in console
window.getSelectedFiles = () => selectedFiles;
})();