build: include production build artifacts in repo
This commit is contained in:
Vendored
+198
@@ -0,0 +1,198 @@
|
||||
import { z } from "zod";
|
||||
import { iconNameSchema, imageRefSchema, linkSchema, req, text } from "./common.js";
|
||||
/**
|
||||
* Editable website sections. Each key is one row in the `SiteSection` table whose `data`
|
||||
* column must match the schema below — validated by the API on write and by the admin forms.
|
||||
*
|
||||
* Multi-line titles use "\n" for line breaks.
|
||||
*/
|
||||
export const WEEK_DAYS = [
|
||||
"Saturday",
|
||||
"Sunday",
|
||||
"Monday",
|
||||
"Tuesday",
|
||||
"Wednesday",
|
||||
"Thursday",
|
||||
"Friday",
|
||||
];
|
||||
export const SOCIAL_TYPES = [
|
||||
"website",
|
||||
"telegram",
|
||||
"instagram",
|
||||
"linkedin",
|
||||
"whatsapp",
|
||||
"bale",
|
||||
"eitaa",
|
||||
"aparat",
|
||||
"youtube",
|
||||
"email",
|
||||
"phone",
|
||||
];
|
||||
const iconLabel = z.object({ icon: iconNameSchema, label: req(80) });
|
||||
const iconCard = z.object({ icon: iconNameSchema, title: req(80), desc: text(300) });
|
||||
export const sectionHeadSchema = z.object({
|
||||
tag: req(80),
|
||||
title: req(200),
|
||||
/** optional accented last line of the title */
|
||||
highlight: text(120),
|
||||
desc: text(500),
|
||||
});
|
||||
export const settingsSectionSchema = z.object({
|
||||
name: req(80),
|
||||
nameEn: req(120),
|
||||
/** default <title> and og:title */
|
||||
title: req(120),
|
||||
/** default meta description */
|
||||
description: req(400),
|
||||
/** machine-readable phone for tel: links and schema.org, e.g. +98-21-91008800 */
|
||||
phone: req(30),
|
||||
phoneDisplay: req(40),
|
||||
email: z.email("ایمیل معتبر نیست"),
|
||||
address: z.object({
|
||||
street: req(200),
|
||||
locality: req(80),
|
||||
country: z.string().trim().length(2).default("IR"),
|
||||
}),
|
||||
/** human-readable working hours, e.g. «شنبه تا پنجشنبه — ۸:۰۰ تا ۱۷:۰۰» */
|
||||
workingHours: req(120),
|
||||
openingHours: z.object({
|
||||
days: z.array(z.enum(WEEK_DAYS)).max(7),
|
||||
opens: z.string().regex(/^\d{2}:\d{2}$/, "قالب ساعت باید HH:MM باشد"),
|
||||
closes: z.string().regex(/^\d{2}:\d{2}$/, "قالب ساعت باید HH:MM باشد"),
|
||||
}),
|
||||
foundingDate: z.string().regex(/^\d{4}$/, "سال میلادی چهاررقمی"),
|
||||
socials: z.array(z.object({ type: z.enum(SOCIAL_TYPES), url: req(300) })).max(12),
|
||||
ogImage: imageRefSchema.extend({
|
||||
width: z.number().int().positive().nullable().default(null),
|
||||
height: z.number().int().positive().nullable().default(null),
|
||||
}),
|
||||
});
|
||||
export const heroSectionSchema = z.object({
|
||||
enabled: z.boolean().default(true),
|
||||
badge: req(120),
|
||||
title: req(80),
|
||||
titleHighlight: req(80),
|
||||
intro: req(600),
|
||||
primaryCta: linkSchema,
|
||||
secondaryCta: linkSchema,
|
||||
chips: z.array(iconLabel).max(6),
|
||||
miniStats: z.array(z.object({ value: req(20), label: req(80) })).max(4),
|
||||
image: imageRefSchema,
|
||||
/** «آخرین بازرسی» date shown on the status card */
|
||||
lastInspection: text(20),
|
||||
});
|
||||
export const tapeSectionSchema = z.object({
|
||||
enabled: z.boolean().default(true),
|
||||
items: z.array(req(80)).min(1).max(20),
|
||||
});
|
||||
export const statsSectionSchema = z.object({
|
||||
enabled: z.boolean().default(true),
|
||||
items: z
|
||||
.array(z.object({
|
||||
end: z.number().int().min(0).max(1_000_000_000),
|
||||
suffix: text(5),
|
||||
label: req(80),
|
||||
note: text(40),
|
||||
}))
|
||||
.max(8),
|
||||
});
|
||||
export const productsIntroSectionSchema = z.object({
|
||||
enabled: z.boolean().default(true),
|
||||
head: sectionHeadSchema,
|
||||
ctaLabel: req(60),
|
||||
trust: z.array(iconCard).max(6),
|
||||
});
|
||||
export const aboutSectionSchema = z.object({
|
||||
enabled: z.boolean().default(true),
|
||||
head: sectionHeadSchema,
|
||||
body: req(2000),
|
||||
image: imageRefSchema,
|
||||
badge: z.object({ value: req(20), label: req(80) }),
|
||||
timeline: z.array(z.object({ year: req(10), text: req(200) })).max(12),
|
||||
features: z.array(iconLabel).max(6),
|
||||
});
|
||||
export const servicesSectionSchema = z.object({
|
||||
enabled: z.boolean().default(true),
|
||||
head: sectionHeadSchema,
|
||||
items: z
|
||||
.array(z.object({
|
||||
icon: iconNameSchema,
|
||||
title: req(80),
|
||||
desc: req(600),
|
||||
items: z.array(req(120)).max(8),
|
||||
}))
|
||||
.max(10),
|
||||
});
|
||||
export const standardsSectionSchema = z.object({
|
||||
enabled: z.boolean().default(true),
|
||||
head: sectionHeadSchema,
|
||||
note: text(500),
|
||||
ctaLabel: req(80),
|
||||
items: z.array(z.object({ code: req(30), label: req(80) })).max(12),
|
||||
});
|
||||
export const industriesSectionSchema = z.object({
|
||||
enabled: z.boolean().default(true),
|
||||
head: sectionHeadSchema,
|
||||
items: z
|
||||
.array(z.object({
|
||||
name: req(60),
|
||||
nameEn: text(60),
|
||||
count: text(20),
|
||||
image: imageRefSchema,
|
||||
}))
|
||||
.max(12),
|
||||
});
|
||||
export const testimonialsSectionSchema = z.object({
|
||||
enabled: z.boolean().default(true),
|
||||
head: sectionHeadSchema,
|
||||
items: z.array(z.object({ text: req(600), name: req(80), role: text(160) })).max(12),
|
||||
});
|
||||
export const contactSectionSchema = z.object({
|
||||
enabled: z.boolean().default(true),
|
||||
head: sectionHeadSchema,
|
||||
emergencyTitle: req(80),
|
||||
emergencyText: req(400),
|
||||
formTag: text(80),
|
||||
formTitle: req(160),
|
||||
successTitle: req(80),
|
||||
successText: req(300),
|
||||
});
|
||||
export const footerSectionSchema = z.object({
|
||||
enabled: z.boolean().default(true),
|
||||
about: req(500),
|
||||
copyright: req(160),
|
||||
certLine: text(160),
|
||||
emergencyNote: text(80),
|
||||
});
|
||||
export const sectionSchemas = {
|
||||
settings: settingsSectionSchema,
|
||||
hero: heroSectionSchema,
|
||||
tape: tapeSectionSchema,
|
||||
stats: statsSectionSchema,
|
||||
productsIntro: productsIntroSectionSchema,
|
||||
about: aboutSectionSchema,
|
||||
services: servicesSectionSchema,
|
||||
standards: standardsSectionSchema,
|
||||
industries: industriesSectionSchema,
|
||||
testimonials: testimonialsSectionSchema,
|
||||
contact: contactSectionSchema,
|
||||
footer: footerSectionSchema,
|
||||
};
|
||||
export const SECTION_KEYS = Object.keys(sectionSchemas);
|
||||
export const isSectionKey = (key) => key in sectionSchemas;
|
||||
/** Persian labels for the admin panel */
|
||||
export const SECTION_LABELS = {
|
||||
settings: { title: "تنظیمات سایت", desc: "نام، اطلاعات تماس، ساعات کاری، شبکههای اجتماعی و سئوی پیشفرض" },
|
||||
hero: { title: "بخش اول (Hero)", desc: "تیتر اصلی، متن معرفی، دکمهها، نشانها و تصویر پسزمینه" },
|
||||
tape: { title: "نوار متحرک", desc: "عبارتهای نوار زرد متحرک زیر Hero" },
|
||||
stats: { title: "آمار", desc: "شمارندههای عددی" },
|
||||
productsIntro: { title: "معرفی محصولات", desc: "عنوان بخش محصولات و کارتهای اعتماد" },
|
||||
about: { title: "درباره ما", desc: "متن معرفی، تصویر، تایملاین و ویژگیها" },
|
||||
services: { title: "خدمات", desc: "فهرست خدمات و جزئیات هر خدمت" },
|
||||
standards: { title: "استانداردها", desc: "استانداردها و گواهینامهها" },
|
||||
industries: { title: "صنایع", desc: "صنایع تحت پوشش و تصویر هرکدام" },
|
||||
testimonials: { title: "نظرات مشتریان", desc: "نقلقولهای مشتریان" },
|
||||
contact: { title: "تماس با ما", desc: "عنوانها و متنهای فرم تماس" },
|
||||
footer: { title: "فوتر", desc: "متن معرفی، کپیرایت و توضیحات پایین صفحه" },
|
||||
};
|
||||
//# sourceMappingURL=sections.js.map
|
||||
Reference in New Issue
Block a user