Add digital catalog with shareable flipbook and ktg.montzar.ir deploy files.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-19 14:37:49 +03:30
co-authored by Cursor
commit a8374e7d6c
54 changed files with 8462 additions and 0 deletions
+53
View File
@@ -0,0 +1,53 @@
export const EFFECTS = ["magazine", "slide", "fade", "card", "scroll"] as const;
export type EffectId = (typeof EFFECTS)[number];
export function isEffectId(value: string): value is EffectId {
return (EFFECTS as readonly string[]).includes(value);
}
export type CatalogPublic = {
id: string;
title: string;
effect: EffectId;
pageCount: number;
flipMs: number;
createdAt: string;
};
export type CreateCatalogResponse = {
id: string;
viewUrl: string;
deleteUrl: string;
qrUrl: string;
doneUrl: string;
};
export const LIMITS = {
maxFileBytes: 100 * 1024 * 1024,
maxPages: 200,
maxCreatesPerHour: 10,
maxPageWidth: 1600,
jpegQuality: 85,
rateWindowMs: 60 * 60 * 1000,
minFlipMs: 400,
maxFlipMs: 5000,
} as const;
export const DEFAULT_TITLE = "کاتالوگ";
export const DEFAULT_FLIP_MS = 1000;
export function clampFlipMs(value: unknown): number {
const n = Number(value);
if (!Number.isFinite(n)) return DEFAULT_FLIP_MS;
return Math.min(LIMITS.maxFlipMs, Math.max(LIMITS.minFlipMs, Math.round(n)));
}
export function fileTooLargeMessage(sizeBytes: number): string {
const used = (sizeBytes / (1024 * 1024)).toFixed(1);
const max = LIMITS.maxFileBytes / (1024 * 1024);
return `حجم فایل ${used} مگابایت است؛ حداکثر ${max} مگابایت مجاز است.`;
}
export function tooManyPagesMessage(count: number): string {
return `این فایل ${count} صفحه دارد؛ حداکثر ${LIMITS.maxPages} صفحه مجاز است.`;
}