Milestone admin and frontend stage

This commit is contained in:
dcconstructions
2026-06-27 17:47:46 +03:00
parent 66d59eba0a
commit e9c0dd56c2
16 changed files with 215 additions and 12 deletions
+22 -3
View File
@@ -220,6 +220,12 @@ const STATIC_FALLBACK = {
appIconAlt: "Иконка NODE.DC",
appWordmarkSrc: "./assets/webflow/images/69ad96a28b06b7552a339137_logtype.svg?v=node-dc",
appWordmarkAlt: "Логотип NODE.DC",
faviconSvg: "./assets/uploads/favicon/icon-adaptive.svg",
faviconIco: "./assets/uploads/favicon/favicon.ico",
faviconAppleTouchIcon: "./assets/uploads/favicon/apple-touch-icon.png",
faviconPng192: "./assets/uploads/favicon/icon-192.png",
faviconPng512: "./assets/uploads/favicon/icon-512.png",
faviconManifest: "./assets/uploads/favicon/manifest.webmanifest.json",
},
},
editableFields: [
@@ -289,6 +295,12 @@ const STATIC_FALLBACK = {
field("content.assets.appIconAlt", "Иконка приложения: alt", "text", "text", "Модель и логотипы"),
field("content.assets.appWordmarkSrc", "Wordmark приложения", "media", "attr", "Модель и логотипы"),
field("content.assets.appWordmarkAlt", "Wordmark приложения: alt", "text", "text", "Модель и логотипы"),
field("content.assets.faviconSvg", "Favicon SVG", "media", "attr", "Модель и логотипы"),
field("content.assets.faviconIco", "Favicon ICO", "media", "attr", "Модель и логотипы"),
field("content.assets.faviconAppleTouchIcon", "Favicon Apple 180", "media", "attr", "Модель и логотипы"),
field("content.assets.faviconPng192", "Favicon PNG 192", "media", "attr", "Модель и логотипы"),
field("content.assets.faviconPng512", "Favicon PNG 512", "media", "attr", "Модель и логотипы"),
field("content.assets.faviconManifest", "Favicon manifest", "media", "attr", "Модель и логотипы"),
],
};
@@ -297,7 +309,7 @@ const GROUP_COPY = {
"Шапка: ссылки": "Пункты навигации верхней mac-панели. Каждый пункт можно добавить, удалить и переставить.",
Уведомления: "Карточки уведомлений справа сверху. Порядок в админке соответствует порядку на сайте.",
Dock: "Нижняя системная панель: приложения, корзина, ссылки и подписи файлов.",
"Модель и логотипы": "Базовые ассеты статичного слоя: GLB-модель, PNG/SVG-логотипы и alt-тексты.",
"Модель и логотипы": "Базовые ассеты статичного слоя: GLB-модель, PNG/SVG-логотипы, favicon-комплект и alt-тексты.",
Заголовок: "Главный заголовок и вводный текст выбранной секции.",
"Верхний информационный блок": "Верхняя пара: длинный текст и крупный заголовок над медиаслайдером.",
"Нижний информационный блок": "Нижняя зеркальная пара: крупный заголовок и длинный текст под медиаслайдером.",
@@ -328,7 +340,8 @@ const GROUP_COPY = {
Контент: "Остальные typed-поля выбранного блока.",
};
const MEDIA_ACCEPT = "image/*,video/*,.gif,.webm,.mov,.mp4,.m4v,.avi,.mkv,.glb,.gltf,.svg,.avif,.webp,.woff,.woff2";
const MEDIA_ACCEPT =
"image/*,video/*,.gif,.webm,.mov,.mp4,.m4v,.avi,.mkv,.glb,.gltf,.svg,.ico,.avif,.webp,.webmanifest,.json,.woff,.woff2";
const MEDIA_DRAG_MIME = "application/x-nodedc-media-entry";
const MEDIA_KIND_FILTERS = [
["all", "Все"],
@@ -598,6 +611,11 @@ function ensureStaticElements() {
notification.eyebrowClass ||= STATIC_FALLBACK.content.notifications[index]?.eyebrowClass || "red-txt gray";
});
state.page.staticElements.content.assets ||= clone(STATIC_FALLBACK.content.assets);
for (const [key, value] of Object.entries(STATIC_FALLBACK.content.assets)) {
if (!Object.prototype.hasOwnProperty.call(state.page.staticElements.content.assets, key)) {
state.page.staticElements.content.assets[key] = value;
}
}
state.page.staticElements.content.dock ||= clone(STATIC_FALLBACK.content.dock);
normalizeDock(state.page.staticElements.content.dock, state.page.staticElements.content.assets);
state.page.staticElements.editableFields = clone(STATIC_FALLBACK.editableFields);
@@ -715,7 +733,7 @@ function adminPreviewUrl(value) {
function mediaKindFromValue(value) {
if (!value) return null;
if (/\.(mp4|webm|mov|m4v|avi|mkv)(\?.*)?$/i.test(value)) return "video";
if (/\.(png|jpe?g|gif|svg|avif|webp)(\?.*)?$/i.test(value)) return "image";
if (/\.(png|jpe?g|gif|svg|ico|avif|webp)(\?.*)?$/i.test(value)) return "image";
if (/\.(glb|gltf)(\?.*)?$/i.test(value)) return "model";
if (/\.(woff2?|ttf|otf)(\?.*)?$/i.test(value)) return "font";
return null;
@@ -781,6 +799,7 @@ function uploadBucketForField(block, editableField) {
if (path.includes("webgl") || currentValue.endsWith(".glb") || currentValue.endsWith(".gltf")) root = "models";
if (path.includes("video") || path.includes("media") || path.includes("sliders") || path.includes("slideritems")) root = "media";
if (path.includes("font") || /\.(woff2?|ttf|otf)(\?.*)?$/i.test(currentValue)) root = "fonts";
if (path.includes("favicon")) return "favicon";
return `${root}/${blockSegment}`;
}