33 lines
2.5 KiB
TypeScript
33 lines
2.5 KiB
TypeScript
import { z } from "zod";
|
||
|
||
export const SIGN_PAPERS = {
|
||
letter: { label: "US Letter · 8.5 × 11 in", width: "8.5in", height: "11in", viewHeight: 1100 },
|
||
a4: { label: "A4 · 210 × 297 mm", width: "210mm", height: "297mm", viewHeight: 1202 },
|
||
letterLandscape: { label: "US Letter landscape · 11 × 8.5 in", width: "11in", height: "8.5in", viewHeight: 850 * 8.5 / 11 },
|
||
a4Landscape: { label: "A4 landscape · 297 × 210 mm", width: "297mm", height: "210mm", viewHeight: 850 * 210 / 297 },
|
||
a5: { label: "A5 · 148 × 210 mm", width: "148mm", height: "210mm", viewHeight: 850 * 210 / 148 },
|
||
a5Landscape: { label: "A5 landscape · 210 × 148 mm", width: "210mm", height: "148mm", viewHeight: 850 * 148 / 210 },
|
||
card3x5: { label: "Small card · 3 × 5 in", width: "3in", height: "5in", viewHeight: 850 * 5 / 3 },
|
||
card5x3: { label: "Small landscape card · 5 × 3 in", width: "5in", height: "3in", viewHeight: 510 },
|
||
card4x6: { label: "Postcard · 4 × 6 in", width: "4in", height: "6in", viewHeight: 1275 },
|
||
card6x4: { label: "Landscape postcard · 6 × 4 in", width: "6in", height: "4in", viewHeight: 850 * 4 / 6 },
|
||
card5x7: { label: "Table card · 5 × 7 in", width: "5in", height: "7in", viewHeight: 1190 },
|
||
card7x5: { label: "Landscape table card · 7 × 5 in", width: "7in", height: "5in", viewHeight: 850 * 5 / 7 },
|
||
square: { label: "Square card · 5 × 5 in", width: "5in", height: "5in", viewHeight: 850 },
|
||
} as const;
|
||
|
||
const image = z.string().max(12 * 1024 * 1024).regex(/^data:image\/(png|jpeg|webp);base64,[A-Za-z0-9+/=]+$/).optional();
|
||
const papers: ["custom", ...(keyof typeof SIGN_PAPERS)[]] = ["custom", ...Object.keys(SIGN_PAPERS) as (keyof typeof SIGN_PAPERS)[]];
|
||
export const savedSignSchema = z.object({
|
||
title: z.string().trim().min(1).max(120), headline: z.string().trim().min(1).max(44),
|
||
message: z.string().trim().min(1).max(120),
|
||
paper: z.enum(papers),
|
||
ink: z.enum(["indigo", "black"]), layout: z.enum(["photo", "typography", "compact"]).optional(),
|
||
customWidth: z.number().finite().positive().optional(), customHeight: z.number().finite().positive().optional(),
|
||
unit: z.enum(["in", "mm"]).optional(), background: z.string().regex(/^#[a-f0-9]{6}$/i).optional(),
|
||
accent: z.string().regex(/^#[a-f0-9]{6}$/i).optional(), font: z.enum(["funnel", "inter", "geologica"]).optional(),
|
||
decoration: z.enum(["arch", "frame", "minimal"]).optional(), showBrand: z.boolean().optional(),
|
||
backgroundImage: image, logoImage: image,
|
||
}).strict();
|
||
export type SavedSign = z.infer<typeof savedSignSchema>;
|