import { z } from 'zod'; import type { Blog } from '../types'; /** * Shared blog form schema, defaults and payload builder — reused by the admin * BlogFormPage and the representative RepresentationBlogFormPage so both accept * the same core + SEO + scheduling fields without duplication. */ export const blogFormSchema = z.object({ title: z.string().min(3, 'عنوان الزامی است'), summary: z.string().optional(), body: z.string().min(10, 'محتوا الزامی است'), tags: z.string().optional(), status: z.enum(['draft', 'published']), image_url: z.string().optional(), city_id: z.number().nullable().optional(), // SEO meta_title: z.string().optional(), meta_description: z.string().optional(), primary_keyword: z.string().optional(), secondary_keywords: z.string().optional(), // comma-separated in the form internal_links: z.string().optional(), // comma-separated URLs external_links: z.string().optional(), reading_time: z.number().nullable().optional(), faq: z.array(z.object({ q: z.string(), a: z.string() })).optional(), // scheduling (unix seconds, null = manual publish) scheduled_at: z.number().nullable().optional(), }); export type BlogFormData = z.infer; const splitCsv = (s?: string): string[] => s ? s.split(',').map((x) => x.trim()).filter(Boolean) : []; export function blogDefaults(blog?: Blog): Partial { if (!blog) return { status: 'draft', faq: [] }; return { title: blog.title, summary: blog.summary ?? '', body: blog.body, tags: blog.tags?.join(', ') ?? '', status: blog.status, image_url: blog.image_url ?? '', city_id: blog.city ? Number(blog.city.id) : null, meta_title: blog.meta_title ?? '', meta_description: blog.meta_description ?? '', primary_keyword: blog.primary_keyword ?? '', secondary_keywords: (blog.secondary_keywords ?? []).join(', '), internal_links: (blog.internal_links ?? []).map((l) => (typeof l === 'string' ? l : l.url)).join(', '), external_links: (blog.external_links ?? []).map((l) => (typeof l === 'string' ? l : l.url)).join(', '), reading_time: blog.reading_time ?? null, faq: blog.faq ?? [], scheduled_at: blog.scheduled_at ?? null, }; } /** Build the API payload (shared shape for admin + representative endpoints). */ export function buildBlogPayload(d: BlogFormData): Record { return { title: d.title, body: d.body, summary: d.summary, status: d.status, image_url: d.image_url ?? '', tags: splitCsv(d.tags), city_id: d.city_id ?? null, meta_title: d.meta_title || null, meta_description: d.meta_description || null, primary_keyword: d.primary_keyword || null, secondary_keywords: splitCsv(d.secondary_keywords), internal_links: splitCsv(d.internal_links), external_links: splitCsv(d.external_links), reading_time: d.reading_time ?? null, faq: (d.faq ?? []).filter((f) => f.q.trim() && f.a.trim()), scheduled_at: d.scheduled_at ?? null, }; }