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 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