build: include production build artifacts in repo
This commit is contained in:
Vendored
+137
@@ -0,0 +1,137 @@
|
||||
import { z } from "zod";
|
||||
export declare const ROLES: readonly ["ADMIN", "EDITOR"];
|
||||
export type Role = (typeof ROLES)[number];
|
||||
export declare const ROLE_LABELS: Record<Role, string>;
|
||||
/** Normalize Iranian mobile to `09XXXXXXXXX` (Latin digits). */
|
||||
export declare function normalizeIrMobile(raw: string): string;
|
||||
export declare const irMobileSchema: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
|
||||
export declare const loginSchema: z.ZodObject<{
|
||||
phone: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
|
||||
password: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
export type LoginInput = z.infer<typeof loginSchema>;
|
||||
export declare const changePasswordSchema: z.ZodObject<{
|
||||
currentPassword: z.ZodString;
|
||||
newPassword: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
export type ChangePasswordInput = z.infer<typeof changePasswordSchema>;
|
||||
export declare const userCreateSchema: z.ZodObject<{
|
||||
phone: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
|
||||
name: z.ZodString;
|
||||
role: z.ZodEnum<{
|
||||
ADMIN: "ADMIN";
|
||||
EDITOR: "EDITOR";
|
||||
}>;
|
||||
password: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
export type UserCreateInput = z.infer<typeof userCreateSchema>;
|
||||
export declare const userUpdateSchema: z.ZodObject<{
|
||||
name: z.ZodString;
|
||||
role: z.ZodEnum<{
|
||||
ADMIN: "ADMIN";
|
||||
EDITOR: "EDITOR";
|
||||
}>;
|
||||
isActive: z.ZodBoolean;
|
||||
password: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
export type UserUpdateInput = z.infer<typeof userUpdateSchema>;
|
||||
export interface AdminUserDto {
|
||||
id: number;
|
||||
phone: string;
|
||||
name: string;
|
||||
role: Role;
|
||||
isActive: boolean;
|
||||
lastLoginAt: string | null;
|
||||
createdAt: string;
|
||||
}
|
||||
export interface AuthResponse {
|
||||
accessToken: string;
|
||||
user: AdminUserDto;
|
||||
}
|
||||
export declare const MESSAGE_STATUSES: readonly ["NEW", "READ", "ARCHIVED"];
|
||||
export type MessageStatus = (typeof MESSAGE_STATUSES)[number];
|
||||
export declare const MESSAGE_STATUS_LABELS: Record<MessageStatus, string>;
|
||||
export declare const contactInputSchema: z.ZodObject<{
|
||||
name: z.ZodString;
|
||||
org: z.ZodString;
|
||||
phone: z.ZodString;
|
||||
message: z.ZodDefault<z.ZodString>;
|
||||
website: z.ZodOptional<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
export type ContactInput = z.infer<typeof contactInputSchema>;
|
||||
export declare const messageUpdateSchema: z.ZodObject<{
|
||||
status: z.ZodEnum<{
|
||||
NEW: "NEW";
|
||||
READ: "READ";
|
||||
ARCHIVED: "ARCHIVED";
|
||||
}>;
|
||||
}, z.core.$strip>;
|
||||
export interface ContactMessageDto {
|
||||
id: number;
|
||||
name: string;
|
||||
org: string;
|
||||
phone: string;
|
||||
message: string;
|
||||
status: MessageStatus;
|
||||
createdAt: string;
|
||||
}
|
||||
export interface MediaDto {
|
||||
id: number;
|
||||
url: string;
|
||||
alt: string;
|
||||
mime: string;
|
||||
size: number;
|
||||
width: number | null;
|
||||
height: number | null;
|
||||
originalName: string;
|
||||
createdAt: string;
|
||||
}
|
||||
export declare const mediaUpdateSchema: z.ZodObject<{
|
||||
alt: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
export interface Paginated<T> {
|
||||
items: T[];
|
||||
total: number;
|
||||
page: number;
|
||||
pageSize: number;
|
||||
}
|
||||
export interface DashboardCategoryStat {
|
||||
id: number;
|
||||
name: string;
|
||||
count: number;
|
||||
}
|
||||
export interface DashboardTrendDay {
|
||||
date: string;
|
||||
dayName: string;
|
||||
messages: number;
|
||||
}
|
||||
export interface DashboardDto {
|
||||
categories: number;
|
||||
products: number;
|
||||
draftProducts: number;
|
||||
newMessages: number;
|
||||
media: number;
|
||||
recentMessages: ContactMessageDto[];
|
||||
recentActivity: {
|
||||
id: number;
|
||||
action: string;
|
||||
entity: string;
|
||||
summary: string;
|
||||
user: string | null;
|
||||
createdAt: string;
|
||||
}[];
|
||||
categoryStats: DashboardCategoryStat[];
|
||||
messageBreakdown: {
|
||||
new: number;
|
||||
read: number;
|
||||
archived: number;
|
||||
total: number;
|
||||
};
|
||||
sectionsSummary: {
|
||||
total: number;
|
||||
visible: number;
|
||||
hidden: number;
|
||||
};
|
||||
trend: DashboardTrendDay[];
|
||||
}
|
||||
//# sourceMappingURL=admin.d.ts.map
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../src/admin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,KAAK,8BAA+B,CAAC;AAClD,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1C,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAG5C,CAAC;AAOF,gEAAgE;AAChE,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAYrD;AAED,eAAO,MAAM,cAAc,gFAK0D,CAAC;AAEtF,eAAO,MAAM,WAAW;;;iBAGtB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAErD,eAAO,MAAM,oBAAoB;;;iBAG/B,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAEvE,eAAO,MAAM,gBAAgB;;;;;;;;iBAK3B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE/D,eAAO,MAAM,gBAAgB;;;;;;;;iBAM3B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE/D,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,YAAY,CAAC;CACpB;AAID,eAAO,MAAM,gBAAgB,sCAAuC,CAAC;AACrE,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAI/D,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;;;;iBAY7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,mBAAmB;;;;;;iBAE9B,CAAC;AAEH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,iBAAiB;;iBAA+B,CAAC;AAE9D,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,iBAAiB,EAAE,CAAC;IACpC,cAAc,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1H,aAAa,EAAE,qBAAqB,EAAE,CAAC;IACvC,gBAAgB,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACjF,eAAe,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACpE,KAAK,EAAE,iBAAiB,EAAE,CAAC;CAC5B"}
|
||||
Vendored
+80
@@ -0,0 +1,80 @@
|
||||
import { z } from "zod";
|
||||
import { req, text } from "./common.js";
|
||||
export const ROLES = ["ADMIN", "EDITOR"];
|
||||
export const ROLE_LABELS = {
|
||||
ADMIN: "مدیر کل",
|
||||
EDITOR: "ویرایشگر",
|
||||
};
|
||||
const password = z.string().min(8, "رمز عبور باید حداقل ۸ کاراکتر باشد").max(128);
|
||||
const FA_DIGITS = "۰۱۲۳۴۵۶۷۸۹";
|
||||
const AR_DIGITS = "٠١٢٣٤٥٦٧٨٩";
|
||||
/** Normalize Iranian mobile to `09XXXXXXXXX` (Latin digits). */
|
||||
export function normalizeIrMobile(raw) {
|
||||
let s = raw.trim().replace(/[\s\-()]/g, "");
|
||||
s = s.replace(/[۰-۹٠-٩]/g, (d) => {
|
||||
const fa = FA_DIGITS.indexOf(d);
|
||||
if (fa >= 0)
|
||||
return String(fa);
|
||||
const ar = AR_DIGITS.indexOf(d);
|
||||
return ar >= 0 ? String(ar) : d;
|
||||
});
|
||||
if (s.startsWith("+98"))
|
||||
s = `0${s.slice(3)}`;
|
||||
else if (s.startsWith("0098"))
|
||||
s = `0${s.slice(4)}`;
|
||||
else if (s.startsWith("98") && s.length === 12)
|
||||
s = `0${s.slice(2)}`;
|
||||
return s;
|
||||
}
|
||||
export const irMobileSchema = z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, "شماره موبایل را وارد کنید")
|
||||
.transform(normalizeIrMobile)
|
||||
.pipe(z.string().regex(/^09\d{9}$/, "شماره موبایل معتبر نیست (مثلاً ۰۹۱۲۱۲۳۴۵۶۷)"));
|
||||
export const loginSchema = z.object({
|
||||
phone: irMobileSchema,
|
||||
password: z.string().min(1, "رمز عبور را وارد کنید").max(128),
|
||||
});
|
||||
export const changePasswordSchema = z.object({
|
||||
currentPassword: z.string().min(1, "رمز فعلی را وارد کنید").max(128),
|
||||
newPassword: password,
|
||||
});
|
||||
export const userCreateSchema = z.object({
|
||||
phone: irMobileSchema,
|
||||
name: req(80),
|
||||
role: z.enum(ROLES),
|
||||
password,
|
||||
});
|
||||
export const userUpdateSchema = z.object({
|
||||
name: req(80),
|
||||
role: z.enum(ROLES),
|
||||
isActive: z.boolean(),
|
||||
/** set only when resetting the password */
|
||||
password: password.optional(),
|
||||
});
|
||||
/* ---------------- contact messages ---------------- */
|
||||
export const MESSAGE_STATUSES = ["NEW", "READ", "ARCHIVED"];
|
||||
export const MESSAGE_STATUS_LABELS = {
|
||||
NEW: "جدید",
|
||||
READ: "خواندهشده",
|
||||
ARCHIVED: "بایگانی",
|
||||
};
|
||||
export const contactInputSchema = z.object({
|
||||
name: req(80),
|
||||
org: req(120),
|
||||
phone: z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, "این فیلد الزامی است")
|
||||
.max(30)
|
||||
.regex(/^[0-9۰-۹+\-\s()]{5,30}$/, "شماره تماس معتبر نیست"),
|
||||
message: text(2000),
|
||||
/** honeypot — real visitors never fill it */
|
||||
website: z.string().max(200).optional(),
|
||||
});
|
||||
export const messageUpdateSchema = z.object({
|
||||
status: z.enum(MESSAGE_STATUSES),
|
||||
});
|
||||
export const mediaUpdateSchema = z.object({ alt: text(200) });
|
||||
//# sourceMappingURL=admin.js.map
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"admin.js","sourceRoot":"","sources":["../src/admin.ts"],"names":[],"mappings":"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"}
|
||||
Vendored
+154
@@ -0,0 +1,154 @@
|
||||
import { z } from "zod";
|
||||
export declare const productAttributeSchema: z.ZodObject<{
|
||||
name: z.ZodString;
|
||||
value: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
export type ProductAttribute = z.infer<typeof productAttributeSchema>;
|
||||
export declare const productGroupInputSchema: z.ZodObject<{
|
||||
id: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
||||
slug: z.ZodString;
|
||||
name: z.ZodString;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
export type ProductGroupInput = z.infer<typeof productGroupInputSchema>;
|
||||
export declare const categoryInputSchema: z.ZodObject<{
|
||||
slug: z.ZodString;
|
||||
code: z.ZodString;
|
||||
name: z.ZodString;
|
||||
nameEn: z.ZodDefault<z.ZodString>;
|
||||
shortDesc: z.ZodDefault<z.ZodString>;
|
||||
fullDesc: z.ZodDefault<z.ZodString>;
|
||||
icon: z.ZodDefault<z.ZodString>;
|
||||
coverImageId: z.ZodDefault<z.ZodNullable<z.ZodCoercedNumber<unknown>>>;
|
||||
isPublished: z.ZodDefault<z.ZodBoolean>;
|
||||
seoTitle: z.ZodDefault<z.ZodString>;
|
||||
seoDescription: z.ZodDefault<z.ZodString>;
|
||||
groups: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
||||
id: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
||||
slug: z.ZodString;
|
||||
name: z.ZodString;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>>>;
|
||||
}, z.core.$strip>;
|
||||
export type CategoryInput = z.infer<typeof categoryInputSchema>;
|
||||
export declare const productInputSchema: z.ZodObject<{
|
||||
categoryId: z.ZodCoercedNumber<unknown>;
|
||||
groupId: z.ZodDefault<z.ZodNullable<z.ZodCoercedNumber<unknown>>>;
|
||||
code: z.ZodString;
|
||||
slug: z.ZodString;
|
||||
name: z.ZodString;
|
||||
nameEn: z.ZodDefault<z.ZodString>;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
specs: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
||||
variants: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
||||
details: z.ZodDefault<z.ZodString>;
|
||||
brand: z.ZodDefault<z.ZodString>;
|
||||
origin: z.ZodDefault<z.ZodString>;
|
||||
sizes: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
||||
standards: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
||||
features: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
||||
applications: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
||||
attributes: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
||||
name: z.ZodString;
|
||||
value: z.ZodString;
|
||||
}, z.core.$strip>>>;
|
||||
packaging: z.ZodDefault<z.ZodString>;
|
||||
minOrder: z.ZodDefault<z.ZodString>;
|
||||
seoTitle: z.ZodDefault<z.ZodString>;
|
||||
seoDescription: z.ZodDefault<z.ZodString>;
|
||||
imageId: z.ZodDefault<z.ZodNullable<z.ZodCoercedNumber<unknown>>>;
|
||||
galleryIds: z.ZodDefault<z.ZodArray<z.ZodCoercedNumber<unknown>>>;
|
||||
isPublished: z.ZodDefault<z.ZodBoolean>;
|
||||
}, z.core.$strip>;
|
||||
export type ProductInput = z.infer<typeof productInputSchema>;
|
||||
export declare const reorderSchema: z.ZodObject<{
|
||||
ids: z.ZodArray<z.ZodCoercedNumber<unknown>>;
|
||||
}, z.core.$strip>;
|
||||
export type ReorderInput = z.infer<typeof reorderSchema>;
|
||||
export declare const productListQuerySchema: z.ZodObject<{
|
||||
categoryId: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
||||
groupId: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
|
||||
q: z.ZodOptional<z.ZodString>;
|
||||
status: z.ZodOptional<z.ZodEnum<{
|
||||
published: "published";
|
||||
draft: "draft";
|
||||
}>>;
|
||||
page: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
||||
pageSize: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
||||
}, z.core.$strip>;
|
||||
export type ProductListQuery = z.infer<typeof productListQuerySchema>;
|
||||
export interface PublicProductGroup {
|
||||
slug: string;
|
||||
name: string;
|
||||
desc: string;
|
||||
}
|
||||
export interface PublicProduct {
|
||||
code: string;
|
||||
slug: string;
|
||||
name: string;
|
||||
nameEn: string;
|
||||
desc: string;
|
||||
specs: string[];
|
||||
variants: string[];
|
||||
/** image URL, or null when the product has no own photo */
|
||||
image: string | null;
|
||||
/** slug of a `PublicCategory.groups` entry */
|
||||
group: string | null;
|
||||
}
|
||||
export interface PublicCategorySummary {
|
||||
slug: string;
|
||||
code: string;
|
||||
name: string;
|
||||
nameEn: string;
|
||||
shortDesc: string;
|
||||
icon: string;
|
||||
coverImage: string | null;
|
||||
productCount: number;
|
||||
}
|
||||
export interface PublicProductImage {
|
||||
url: string;
|
||||
alt: string;
|
||||
width: number | null;
|
||||
height: number | null;
|
||||
}
|
||||
/** Everything the product page needs (`GET /api/public/products/:slug`) */
|
||||
export interface PublicProductDetail extends PublicProduct {
|
||||
details: string;
|
||||
brand: string;
|
||||
origin: string;
|
||||
sizes: string[];
|
||||
standards: string[];
|
||||
features: string[];
|
||||
applications: string[];
|
||||
attributes: ProductAttribute[];
|
||||
packaging: string;
|
||||
minOrder: string;
|
||||
seoTitle: string;
|
||||
seoDescription: string;
|
||||
/** main image first, then the gallery */
|
||||
images: PublicProductImage[];
|
||||
groupName: string | null;
|
||||
category: {
|
||||
slug: string;
|
||||
code: string;
|
||||
name: string;
|
||||
nameEn: string;
|
||||
fullDesc: string;
|
||||
coverImage: string | null;
|
||||
};
|
||||
related: PublicProduct[];
|
||||
updatedAt: string;
|
||||
}
|
||||
/** Published product URLs for the sitemap */
|
||||
export interface PublicProductRef {
|
||||
slug: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
export interface PublicCategory extends PublicCategorySummary {
|
||||
fullDesc: string;
|
||||
seoTitle: string;
|
||||
seoDescription: string;
|
||||
groups: PublicProductGroup[];
|
||||
products: PublicProduct[];
|
||||
}
|
||||
//# sourceMappingURL=catalog.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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"}
|
||||
Vendored
+66
@@ -0,0 +1,66 @@
|
||||
import { z } from "zod";
|
||||
import { idSchema, req, slugSchema, text } from "./common.js";
|
||||
const shortList = z.array(z.string().trim().min(1).max(120)).max(20).default([]);
|
||||
export const productAttributeSchema = z.object({
|
||||
name: req(80),
|
||||
value: req(300),
|
||||
});
|
||||
export const productGroupInputSchema = z.object({
|
||||
/** present when editing an existing group */
|
||||
id: idSchema.optional(),
|
||||
slug: slugSchema,
|
||||
name: req(120),
|
||||
desc: text(1000),
|
||||
});
|
||||
export const categoryInputSchema = z.object({
|
||||
slug: slugSchema,
|
||||
code: req(20),
|
||||
name: req(120),
|
||||
nameEn: text(120),
|
||||
shortDesc: text(500),
|
||||
fullDesc: text(3000),
|
||||
icon: text(40),
|
||||
coverImageId: idSchema.nullable().default(null),
|
||||
isPublished: z.boolean().default(true),
|
||||
seoTitle: text(120),
|
||||
seoDescription: text(300),
|
||||
groups: z.array(productGroupInputSchema).max(30).default([]),
|
||||
});
|
||||
export const productInputSchema = z.object({
|
||||
categoryId: idSchema,
|
||||
groupId: idSchema.nullable().default(null),
|
||||
code: req(30),
|
||||
slug: slugSchema,
|
||||
name: req(160),
|
||||
nameEn: text(160),
|
||||
desc: text(2000),
|
||||
specs: shortList,
|
||||
variants: shortList,
|
||||
details: text(8000),
|
||||
brand: text(80),
|
||||
origin: text(80),
|
||||
sizes: shortList,
|
||||
standards: shortList,
|
||||
features: z.array(z.string().trim().min(1).max(300)).max(30).default([]),
|
||||
applications: shortList,
|
||||
attributes: z.array(productAttributeSchema).max(40).default([]),
|
||||
packaging: text(200),
|
||||
minOrder: text(120),
|
||||
seoTitle: text(120),
|
||||
seoDescription: text(300),
|
||||
imageId: idSchema.nullable().default(null),
|
||||
galleryIds: z.array(idSchema).max(12).default([]),
|
||||
isPublished: z.boolean().default(true),
|
||||
});
|
||||
export const reorderSchema = z.object({
|
||||
ids: z.array(idSchema).min(1).max(1000),
|
||||
});
|
||||
export const productListQuerySchema = z.object({
|
||||
categoryId: idSchema.optional(),
|
||||
groupId: idSchema.optional(),
|
||||
q: z.string().trim().max(100).optional(),
|
||||
status: z.enum(["published", "draft"]).optional(),
|
||||
page: z.coerce.number().int().min(1).default(1),
|
||||
pageSize: z.coerce.number().int().min(1).max(200).default(50),
|
||||
});
|
||||
//# sourceMappingURL=catalog.js.map
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../src/catalog.ts"],"names":[],"mappings":"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"}
|
||||
Vendored
+27
@@ -0,0 +1,27 @@
|
||||
import { z } from "zod";
|
||||
/** Required, trimmed text */
|
||||
export declare const req: (max?: number) => z.ZodString;
|
||||
/** Optional, trimmed text (empty string when missing) */
|
||||
export declare const text: (max?: number) => z.ZodDefault<z.ZodString>;
|
||||
export declare const idSchema: z.ZodCoercedNumber<unknown>;
|
||||
export declare const slugSchema: z.ZodString;
|
||||
export declare const iconNameSchema: z.ZodString;
|
||||
/** Image stored by URL inside section content */
|
||||
export declare const imageRefSchema: z.ZodObject<{
|
||||
url: z.ZodString;
|
||||
alt: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
export type ImageRef = z.infer<typeof imageRefSchema>;
|
||||
export declare const linkSchema: z.ZodObject<{
|
||||
label: z.ZodString;
|
||||
href: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
/** Field validation issue as returned by the API (`path` is dot-joined) */
|
||||
export interface ValidationIssue {
|
||||
path: string;
|
||||
message: string;
|
||||
}
|
||||
export declare const toIssues: (error: z.ZodError) => ValidationIssue[];
|
||||
/** Convert latin digits to Persian digits */
|
||||
export declare const faNum: (v: number | string) => string;
|
||||
//# sourceMappingURL=common.d.ts.map
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,6BAA6B;AAC7B,eAAO,MAAM,GAAG,GAAI,YAAS,gBAA6D,CAAC;AAC3F,yDAAyD;AACzD,eAAO,MAAM,IAAI,GAAI,YAAS,8BAA2C,CAAC;AAE1E,eAAO,MAAM,QAAQ,6BAAqC,CAAC;AAE3D,eAAO,MAAM,UAAU,aAK4E,CAAC;AAEpG,eAAO,MAAM,cAAc,aAAmC,CAAC;AAE/D,iDAAiD;AACjD,eAAO,MAAM,cAAc;;;iBAGzB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD,eAAO,MAAM,UAAU;;;iBAGrB,CAAC;AAEH,2EAA2E;AAC3E,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,QAAQ,GAAI,OAAO,CAAC,CAAC,QAAQ,KAAG,eAAe,EAC2B,CAAC;AAExF,6CAA6C;AAC7C,eAAO,MAAM,KAAK,GAAI,GAAG,MAAM,GAAG,MAAM,KAAG,MACgB,CAAC"}
|
||||
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
import { z } from "zod";
|
||||
/** Required, trimmed text */
|
||||
export const req = (max = 300) => z.string().trim().min(1, "این فیلد الزامی است").max(max);
|
||||
/** Optional, trimmed text (empty string when missing) */
|
||||
export const text = (max = 300) => z.string().trim().max(max).default("");
|
||||
export const idSchema = z.coerce.number().int().positive();
|
||||
export const slugSchema = z
|
||||
.string()
|
||||
.trim()
|
||||
.min(1, "این فیلد الزامی است")
|
||||
.max(80)
|
||||
.regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "فقط حروف کوچک انگلیسی، عدد و خط تیره (مثلاً safety-shoes)");
|
||||
export const iconNameSchema = z.string().trim().min(1).max(80);
|
||||
/** Image stored by URL inside section content */
|
||||
export const imageRefSchema = z.object({
|
||||
url: req(500),
|
||||
alt: text(200),
|
||||
});
|
||||
export const linkSchema = z.object({
|
||||
label: req(60),
|
||||
href: req(300),
|
||||
});
|
||||
export const toIssues = (error) => error.issues.map((i) => ({ path: i.path.map(String).join("."), message: i.message }));
|
||||
/** Convert latin digits to Persian digits */
|
||||
export const faNum = (v) => String(v).replace(/\d/g, (d) => "۰۱۲۳۴۵۶۷۸۹"[Number(d)]);
|
||||
//# sourceMappingURL=common.js.map
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,6BAA6B;AAC7B,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAC3F,yDAAyD;AACzD,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAE1E,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;AAE3D,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC;KACxB,MAAM,EAAE;KACR,IAAI,EAAE;KACN,GAAG,CAAC,CAAC,EAAE,qBAAqB,CAAC;KAC7B,GAAG,CAAC,EAAE,CAAC;KACP,KAAK,CAAC,4BAA4B,EAAE,2DAA2D,CAAC,CAAC;AAEpG,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAE/D,iDAAiD;AACjD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC;IACb,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC;CACf,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;IACd,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC;CACf,CAAC,CAAC;AAQH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAiB,EAAqB,EAAE,CAC/D,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAExF,6CAA6C;AAC7C,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,CAAkB,EAAU,EAAE,CAClD,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC"}
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* Vuesax linear icon aliases and recommended picker list.
|
||||
*/
|
||||
export declare const ICON_ALIASES: Record<string, string>;
|
||||
export declare function resolveVuesaxIcon(name: string): string;
|
||||
/**
|
||||
* Recommended icon names displayed in pickers and dropdowns
|
||||
*/
|
||||
export declare const RECOMMENDED_ICONS: readonly ["shield-tick", "shield-security", "shield-cross", "security-safe", "security-user", "verify", "award", "medal-star", "box-tick", "box", "truck-time", "buildings", "building-4", "buildings-2", "global", "people", "user-tag", "24-support", "call", "sms", "location", "clock", "clipboard-tick", "document-text", "document-filter", "teacher", "status", "search-status", "setting-2", "setting-4", "glass", "tag", "routing-2", "volume-high", "wind-2", "danger", "lamp-on", "gas-station", "hierarchy", "flash", "flash-circle", "tree", "heart-tick", "star", "like-1", "radar-2", "lock", "eye", "gallery", "video-play"];
|
||||
export declare const ICON_NAMES: readonly ["shield-tick", "shield-security", "shield-cross", "security-safe", "security-user", "verify", "award", "medal-star", "box-tick", "box", "truck-time", "buildings", "building-4", "buildings-2", "global", "people", "user-tag", "24-support", "call", "sms", "location", "clock", "clipboard-tick", "document-text", "document-filter", "teacher", "status", "search-status", "setting-2", "setting-4", "glass", "tag", "routing-2", "volume-high", "wind-2", "danger", "lamp-on", "gas-station", "hierarchy", "flash", "flash-circle", "tree", "heart-tick", "star", "like-1", "radar-2", "lock", "eye", "gallery", "video-play", ...string[]];
|
||||
export type IconName = string;
|
||||
//# sourceMappingURL=icons.d.ts.map
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../src/icons.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAmF/C,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAItD;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,8mBAmDpB,CAAC;AAEX,eAAO,MAAM,UAAU,2nBAGb,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC"}
|
||||
Vendored
+151
@@ -0,0 +1,151 @@
|
||||
/**
|
||||
* Vuesax linear icon aliases and recommended picker list.
|
||||
*/
|
||||
export const ICON_ALIASES = {
|
||||
// Navigation & Actions
|
||||
ArrowLeft: "arrow-left",
|
||||
ArrowRight: "arrow-right",
|
||||
ArrowUp: "arrow-up",
|
||||
ArrowDown: "arrow-down",
|
||||
ChevronDown: "arrow-down-1",
|
||||
ChevronUp: "arrow-up-1",
|
||||
ChevronLeft: "arrow-left-1",
|
||||
ChevronRight: "arrow-right-1",
|
||||
Menu: "menu",
|
||||
X: "close-circle",
|
||||
Plus: "add",
|
||||
Trash: "trash",
|
||||
Edit: "edit-2",
|
||||
Copy: "copy",
|
||||
Check: "tick-circle",
|
||||
Search: "search-normal",
|
||||
Filter: "filter",
|
||||
Eye: "eye",
|
||||
EyeOff: "eye-slash",
|
||||
ImageOff: "gallery-slash",
|
||||
Quote: "quote-up",
|
||||
// Contact & Social
|
||||
Phone: "call",
|
||||
Mail: "sms",
|
||||
MapPin: "location",
|
||||
Clock: "clock",
|
||||
Globe: "global",
|
||||
Send: "send-2",
|
||||
Instagram: "instagram",
|
||||
Linkedin: "link",
|
||||
MessageCircle: "messages-2",
|
||||
Youtube: "video-play",
|
||||
AtSign: "sms",
|
||||
// Equipment & Safety Categories
|
||||
HardHat: "security-safe",
|
||||
Glasses: "glass",
|
||||
Shirt: "tag",
|
||||
Footprints: "routing-2",
|
||||
Hand: "shield-tick",
|
||||
Ear: "volume-high",
|
||||
Wind: "wind-2",
|
||||
TriangleAlert: "danger",
|
||||
Siren: "lamp-on",
|
||||
TrafficCone: "danger",
|
||||
Construction: "setting-2",
|
||||
Factory: "building-4",
|
||||
Building2: "buildings-2",
|
||||
Fuel: "gas-station",
|
||||
Pickaxe: "hierarchy",
|
||||
Flame: "flash",
|
||||
Zap: "flash-circle",
|
||||
Leaf: "tree",
|
||||
HeartPulse: "heart-tick",
|
||||
Star: "star",
|
||||
ThumbsUp: "like-1",
|
||||
Target: "radar-2",
|
||||
Lock: "lock",
|
||||
// Trust, Certifications & Standards
|
||||
ShieldCheck: "shield-tick",
|
||||
ShieldPlus: "shield-security",
|
||||
ShieldAlert: "shield-cross",
|
||||
BadgeCheck: "verify",
|
||||
Award: "award",
|
||||
Medal: "medal-star",
|
||||
PackageCheck: "box-tick",
|
||||
Package: "box",
|
||||
Truck: "truck-time",
|
||||
Warehouse: "buildings",
|
||||
Users: "people",
|
||||
Handshake: "user-tag",
|
||||
Headset: "24-support",
|
||||
ClipboardCheck: "clipboard-tick",
|
||||
FileCheck: "document-text",
|
||||
FileSearch: "document-filter",
|
||||
GraduationCap: "teacher",
|
||||
Gauge: "status",
|
||||
Microscope: "search-status",
|
||||
Wrench: "setting-4",
|
||||
};
|
||||
export function resolveVuesaxIcon(name) {
|
||||
if (!name)
|
||||
return "shield-tick";
|
||||
if (name in ICON_ALIASES)
|
||||
return ICON_ALIASES[name];
|
||||
return name.replace(/^vuesax-linear:/, "");
|
||||
}
|
||||
/**
|
||||
* Recommended icon names displayed in pickers and dropdowns
|
||||
*/
|
||||
export const RECOMMENDED_ICONS = [
|
||||
"shield-tick",
|
||||
"shield-security",
|
||||
"shield-cross",
|
||||
"security-safe",
|
||||
"security-user",
|
||||
"verify",
|
||||
"award",
|
||||
"medal-star",
|
||||
"box-tick",
|
||||
"box",
|
||||
"truck-time",
|
||||
"buildings",
|
||||
"building-4",
|
||||
"buildings-2",
|
||||
"global",
|
||||
"people",
|
||||
"user-tag",
|
||||
"24-support",
|
||||
"call",
|
||||
"sms",
|
||||
"location",
|
||||
"clock",
|
||||
"clipboard-tick",
|
||||
"document-text",
|
||||
"document-filter",
|
||||
"teacher",
|
||||
"status",
|
||||
"search-status",
|
||||
"setting-2",
|
||||
"setting-4",
|
||||
"glass",
|
||||
"tag",
|
||||
"routing-2",
|
||||
"volume-high",
|
||||
"wind-2",
|
||||
"danger",
|
||||
"lamp-on",
|
||||
"gas-station",
|
||||
"hierarchy",
|
||||
"flash",
|
||||
"flash-circle",
|
||||
"tree",
|
||||
"heart-tick",
|
||||
"star",
|
||||
"like-1",
|
||||
"radar-2",
|
||||
"lock",
|
||||
"eye",
|
||||
"gallery",
|
||||
"video-play",
|
||||
];
|
||||
export const ICON_NAMES = [
|
||||
...RECOMMENDED_ICONS,
|
||||
...Object.keys(ICON_ALIASES),
|
||||
];
|
||||
//# sourceMappingURL=icons.js.map
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"icons.js","sourceRoot":"","sources":["../src/icons.ts"],"names":[],"mappings":"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"}
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
export * from "./common.js";
|
||||
export * from "./icons.js";
|
||||
export * from "./catalog.js";
|
||||
export * from "./sections.js";
|
||||
export * from "./admin.js";
|
||||
import type { PublicCategorySummary } from "./catalog.js";
|
||||
import type { SiteSections } from "./sections.js";
|
||||
/** Everything the home page needs, returned by `GET /api/public/site` in one request */
|
||||
export interface PublicSite {
|
||||
sections: SiteSections;
|
||||
categories: PublicCategorySummary[];
|
||||
}
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC;AAE3B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,wFAAwF;AACxF,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,YAAY,CAAC;IACvB,UAAU,EAAE,qBAAqB,EAAE,CAAC;CACrC"}
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
export * from "./common.js";
|
||||
export * from "./icons.js";
|
||||
export * from "./catalog.js";
|
||||
export * from "./sections.js";
|
||||
export * from "./admin.js";
|
||||
//# sourceMappingURL=index.js.map
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC"}
|
||||
Vendored
+467
@@ -0,0 +1,467 @@
|
||||
import { z } from "zod";
|
||||
/**
|
||||
* 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 declare const WEEK_DAYS: readonly ["Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday"];
|
||||
export declare const SOCIAL_TYPES: readonly ["website", "telegram", "instagram", "linkedin", "whatsapp", "bale", "eitaa", "aparat", "youtube", "email", "phone"];
|
||||
export type SocialType = (typeof SOCIAL_TYPES)[number];
|
||||
export declare const sectionHeadSchema: z.ZodObject<{
|
||||
tag: z.ZodString;
|
||||
title: z.ZodString;
|
||||
highlight: z.ZodDefault<z.ZodString>;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
export type SectionHeadData = z.infer<typeof sectionHeadSchema>;
|
||||
export declare const settingsSectionSchema: z.ZodObject<{
|
||||
name: z.ZodString;
|
||||
nameEn: z.ZodString;
|
||||
title: z.ZodString;
|
||||
description: z.ZodString;
|
||||
phone: z.ZodString;
|
||||
phoneDisplay: z.ZodString;
|
||||
email: z.ZodEmail;
|
||||
address: z.ZodObject<{
|
||||
street: z.ZodString;
|
||||
locality: z.ZodString;
|
||||
country: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
workingHours: z.ZodString;
|
||||
openingHours: z.ZodObject<{
|
||||
days: z.ZodArray<z.ZodEnum<{
|
||||
Saturday: "Saturday";
|
||||
Sunday: "Sunday";
|
||||
Monday: "Monday";
|
||||
Tuesday: "Tuesday";
|
||||
Wednesday: "Wednesday";
|
||||
Thursday: "Thursday";
|
||||
Friday: "Friday";
|
||||
}>>;
|
||||
opens: z.ZodString;
|
||||
closes: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
foundingDate: z.ZodString;
|
||||
socials: z.ZodArray<z.ZodObject<{
|
||||
type: z.ZodEnum<{
|
||||
instagram: "instagram";
|
||||
phone: "phone";
|
||||
website: "website";
|
||||
telegram: "telegram";
|
||||
linkedin: "linkedin";
|
||||
whatsapp: "whatsapp";
|
||||
bale: "bale";
|
||||
eitaa: "eitaa";
|
||||
aparat: "aparat";
|
||||
youtube: "youtube";
|
||||
email: "email";
|
||||
}>;
|
||||
url: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
ogImage: z.ZodObject<{
|
||||
url: z.ZodString;
|
||||
alt: z.ZodDefault<z.ZodString>;
|
||||
width: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
|
||||
height: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
|
||||
}, z.core.$strip>;
|
||||
}, z.core.$strip>;
|
||||
export declare const heroSectionSchema: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
badge: z.ZodString;
|
||||
title: z.ZodString;
|
||||
titleHighlight: z.ZodString;
|
||||
intro: z.ZodString;
|
||||
primaryCta: z.ZodObject<{
|
||||
label: z.ZodString;
|
||||
href: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
secondaryCta: z.ZodObject<{
|
||||
label: z.ZodString;
|
||||
href: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
chips: z.ZodArray<z.ZodObject<{
|
||||
icon: z.ZodString;
|
||||
label: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
miniStats: z.ZodArray<z.ZodObject<{
|
||||
value: z.ZodString;
|
||||
label: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
image: z.ZodObject<{
|
||||
url: z.ZodString;
|
||||
alt: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
lastInspection: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
export declare const tapeSectionSchema: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
items: z.ZodArray<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
export declare const statsSectionSchema: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
items: z.ZodArray<z.ZodObject<{
|
||||
end: z.ZodNumber;
|
||||
suffix: z.ZodDefault<z.ZodString>;
|
||||
label: z.ZodString;
|
||||
note: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
export declare const productsIntroSectionSchema: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
head: z.ZodObject<{
|
||||
tag: z.ZodString;
|
||||
title: z.ZodString;
|
||||
highlight: z.ZodDefault<z.ZodString>;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
ctaLabel: z.ZodString;
|
||||
trust: z.ZodArray<z.ZodObject<{
|
||||
icon: z.ZodString;
|
||||
title: z.ZodString;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
export declare const aboutSectionSchema: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
head: z.ZodObject<{
|
||||
tag: z.ZodString;
|
||||
title: z.ZodString;
|
||||
highlight: z.ZodDefault<z.ZodString>;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
body: z.ZodString;
|
||||
image: z.ZodObject<{
|
||||
url: z.ZodString;
|
||||
alt: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
badge: z.ZodObject<{
|
||||
value: z.ZodString;
|
||||
label: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
timeline: z.ZodArray<z.ZodObject<{
|
||||
year: z.ZodString;
|
||||
text: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
features: z.ZodArray<z.ZodObject<{
|
||||
icon: z.ZodString;
|
||||
label: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
export declare const servicesSectionSchema: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
head: z.ZodObject<{
|
||||
tag: z.ZodString;
|
||||
title: z.ZodString;
|
||||
highlight: z.ZodDefault<z.ZodString>;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
items: z.ZodArray<z.ZodObject<{
|
||||
icon: z.ZodString;
|
||||
title: z.ZodString;
|
||||
desc: z.ZodString;
|
||||
items: z.ZodArray<z.ZodString>;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
export declare const standardsSectionSchema: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
head: z.ZodObject<{
|
||||
tag: z.ZodString;
|
||||
title: z.ZodString;
|
||||
highlight: z.ZodDefault<z.ZodString>;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
note: z.ZodDefault<z.ZodString>;
|
||||
ctaLabel: z.ZodString;
|
||||
items: z.ZodArray<z.ZodObject<{
|
||||
code: z.ZodString;
|
||||
label: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
export declare const industriesSectionSchema: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
head: z.ZodObject<{
|
||||
tag: z.ZodString;
|
||||
title: z.ZodString;
|
||||
highlight: z.ZodDefault<z.ZodString>;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
items: z.ZodArray<z.ZodObject<{
|
||||
name: z.ZodString;
|
||||
nameEn: z.ZodDefault<z.ZodString>;
|
||||
count: z.ZodDefault<z.ZodString>;
|
||||
image: z.ZodObject<{
|
||||
url: z.ZodString;
|
||||
alt: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
export declare const testimonialsSectionSchema: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
head: z.ZodObject<{
|
||||
tag: z.ZodString;
|
||||
title: z.ZodString;
|
||||
highlight: z.ZodDefault<z.ZodString>;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
items: z.ZodArray<z.ZodObject<{
|
||||
text: z.ZodString;
|
||||
name: z.ZodString;
|
||||
role: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
export declare const contactSectionSchema: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
head: z.ZodObject<{
|
||||
tag: z.ZodString;
|
||||
title: z.ZodString;
|
||||
highlight: z.ZodDefault<z.ZodString>;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
emergencyTitle: z.ZodString;
|
||||
emergencyText: z.ZodString;
|
||||
formTag: z.ZodDefault<z.ZodString>;
|
||||
formTitle: z.ZodString;
|
||||
successTitle: z.ZodString;
|
||||
successText: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
export declare const footerSectionSchema: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
about: z.ZodString;
|
||||
copyright: z.ZodString;
|
||||
certLine: z.ZodDefault<z.ZodString>;
|
||||
emergencyNote: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
export declare const sectionSchemas: {
|
||||
readonly settings: z.ZodObject<{
|
||||
name: z.ZodString;
|
||||
nameEn: z.ZodString;
|
||||
title: z.ZodString;
|
||||
description: z.ZodString;
|
||||
phone: z.ZodString;
|
||||
phoneDisplay: z.ZodString;
|
||||
email: z.ZodEmail;
|
||||
address: z.ZodObject<{
|
||||
street: z.ZodString;
|
||||
locality: z.ZodString;
|
||||
country: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
workingHours: z.ZodString;
|
||||
openingHours: z.ZodObject<{
|
||||
days: z.ZodArray<z.ZodEnum<{
|
||||
Saturday: "Saturday";
|
||||
Sunday: "Sunday";
|
||||
Monday: "Monday";
|
||||
Tuesday: "Tuesday";
|
||||
Wednesday: "Wednesday";
|
||||
Thursday: "Thursday";
|
||||
Friday: "Friday";
|
||||
}>>;
|
||||
opens: z.ZodString;
|
||||
closes: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
foundingDate: z.ZodString;
|
||||
socials: z.ZodArray<z.ZodObject<{
|
||||
type: z.ZodEnum<{
|
||||
instagram: "instagram";
|
||||
phone: "phone";
|
||||
website: "website";
|
||||
telegram: "telegram";
|
||||
linkedin: "linkedin";
|
||||
whatsapp: "whatsapp";
|
||||
bale: "bale";
|
||||
eitaa: "eitaa";
|
||||
aparat: "aparat";
|
||||
youtube: "youtube";
|
||||
email: "email";
|
||||
}>;
|
||||
url: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
ogImage: z.ZodObject<{
|
||||
url: z.ZodString;
|
||||
alt: z.ZodDefault<z.ZodString>;
|
||||
width: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
|
||||
height: z.ZodDefault<z.ZodNullable<z.ZodNumber>>;
|
||||
}, z.core.$strip>;
|
||||
}, z.core.$strip>;
|
||||
readonly hero: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
badge: z.ZodString;
|
||||
title: z.ZodString;
|
||||
titleHighlight: z.ZodString;
|
||||
intro: z.ZodString;
|
||||
primaryCta: z.ZodObject<{
|
||||
label: z.ZodString;
|
||||
href: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
secondaryCta: z.ZodObject<{
|
||||
label: z.ZodString;
|
||||
href: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
chips: z.ZodArray<z.ZodObject<{
|
||||
icon: z.ZodString;
|
||||
label: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
miniStats: z.ZodArray<z.ZodObject<{
|
||||
value: z.ZodString;
|
||||
label: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
image: z.ZodObject<{
|
||||
url: z.ZodString;
|
||||
alt: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
lastInspection: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
readonly tape: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
items: z.ZodArray<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
readonly stats: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
items: z.ZodArray<z.ZodObject<{
|
||||
end: z.ZodNumber;
|
||||
suffix: z.ZodDefault<z.ZodString>;
|
||||
label: z.ZodString;
|
||||
note: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
readonly productsIntro: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
head: z.ZodObject<{
|
||||
tag: z.ZodString;
|
||||
title: z.ZodString;
|
||||
highlight: z.ZodDefault<z.ZodString>;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
ctaLabel: z.ZodString;
|
||||
trust: z.ZodArray<z.ZodObject<{
|
||||
icon: z.ZodString;
|
||||
title: z.ZodString;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
readonly about: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
head: z.ZodObject<{
|
||||
tag: z.ZodString;
|
||||
title: z.ZodString;
|
||||
highlight: z.ZodDefault<z.ZodString>;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
body: z.ZodString;
|
||||
image: z.ZodObject<{
|
||||
url: z.ZodString;
|
||||
alt: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
badge: z.ZodObject<{
|
||||
value: z.ZodString;
|
||||
label: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
timeline: z.ZodArray<z.ZodObject<{
|
||||
year: z.ZodString;
|
||||
text: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
features: z.ZodArray<z.ZodObject<{
|
||||
icon: z.ZodString;
|
||||
label: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
readonly services: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
head: z.ZodObject<{
|
||||
tag: z.ZodString;
|
||||
title: z.ZodString;
|
||||
highlight: z.ZodDefault<z.ZodString>;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
items: z.ZodArray<z.ZodObject<{
|
||||
icon: z.ZodString;
|
||||
title: z.ZodString;
|
||||
desc: z.ZodString;
|
||||
items: z.ZodArray<z.ZodString>;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
readonly standards: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
head: z.ZodObject<{
|
||||
tag: z.ZodString;
|
||||
title: z.ZodString;
|
||||
highlight: z.ZodDefault<z.ZodString>;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
note: z.ZodDefault<z.ZodString>;
|
||||
ctaLabel: z.ZodString;
|
||||
items: z.ZodArray<z.ZodObject<{
|
||||
code: z.ZodString;
|
||||
label: z.ZodString;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
readonly industries: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
head: z.ZodObject<{
|
||||
tag: z.ZodString;
|
||||
title: z.ZodString;
|
||||
highlight: z.ZodDefault<z.ZodString>;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
items: z.ZodArray<z.ZodObject<{
|
||||
name: z.ZodString;
|
||||
nameEn: z.ZodDefault<z.ZodString>;
|
||||
count: z.ZodDefault<z.ZodString>;
|
||||
image: z.ZodObject<{
|
||||
url: z.ZodString;
|
||||
alt: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
readonly testimonials: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
head: z.ZodObject<{
|
||||
tag: z.ZodString;
|
||||
title: z.ZodString;
|
||||
highlight: z.ZodDefault<z.ZodString>;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
items: z.ZodArray<z.ZodObject<{
|
||||
text: z.ZodString;
|
||||
name: z.ZodString;
|
||||
role: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>>;
|
||||
}, z.core.$strip>;
|
||||
readonly contact: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
head: z.ZodObject<{
|
||||
tag: z.ZodString;
|
||||
title: z.ZodString;
|
||||
highlight: z.ZodDefault<z.ZodString>;
|
||||
desc: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
emergencyTitle: z.ZodString;
|
||||
emergencyText: z.ZodString;
|
||||
formTag: z.ZodDefault<z.ZodString>;
|
||||
formTitle: z.ZodString;
|
||||
successTitle: z.ZodString;
|
||||
successText: z.ZodString;
|
||||
}, z.core.$strip>;
|
||||
readonly footer: z.ZodObject<{
|
||||
enabled: z.ZodDefault<z.ZodBoolean>;
|
||||
about: z.ZodString;
|
||||
copyright: z.ZodString;
|
||||
certLine: z.ZodDefault<z.ZodString>;
|
||||
emergencyNote: z.ZodDefault<z.ZodString>;
|
||||
}, z.core.$strip>;
|
||||
};
|
||||
export type SectionKey = keyof typeof sectionSchemas;
|
||||
export declare const SECTION_KEYS: SectionKey[];
|
||||
export type SectionData<K extends SectionKey> = z.infer<(typeof sectionSchemas)[K]>;
|
||||
export type SiteSections = {
|
||||
[K in SectionKey]: SectionData<K>;
|
||||
};
|
||||
export type SiteSettings = SectionData<"settings">;
|
||||
export declare const isSectionKey: (key: string) => key is SectionKey;
|
||||
/** Persian labels for the admin panel */
|
||||
export declare const SECTION_LABELS: Record<SectionKey, {
|
||||
title: string;
|
||||
desc: string;
|
||||
}>;
|
||||
//# sourceMappingURL=sections.d.ts.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"sections.d.ts","sourceRoot":"","sources":["../src/sections.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;GAKG;AAEH,eAAO,MAAM,SAAS,yFAQZ,CAAC;AAEX,eAAO,MAAM,YAAY,+HAYf,CAAC;AACX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAKvD,eAAO,MAAM,iBAAiB;;;;;iBAM5B,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAEhE,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6BhC,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAa5B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;iBAG5B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;iBAY7B,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;iBAKrC,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;iBAQ7B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;iBAahC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;iBAMjC,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;;;iBAalC,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;iBAIpC,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;iBAS/B,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;iBAM9B,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAajB,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,cAAc,CAAC;AACrD,eAAO,MAAM,YAAY,EAAkC,UAAU,EAAE,CAAC;AACxE,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,UAAU,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpF,MAAM,MAAM,YAAY,GAAG;KAAG,CAAC,IAAI,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC;CAAE,CAAC;AACjE,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;AAEnD,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,KAAG,GAAG,IAAI,UAAmC,CAAC;AAEtF,yCAAyC;AACzC,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,UAAU,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAa9E,CAAC"}
|
||||
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
|
||||
Vendored
+1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user