TorbatYar/frontend/modules/workspace/labels.ts
Mortezakoohjani a483b47369 feat(workspace): complete production workspace and content operations
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-12 11:54:17 +03:30

189 lines
6.9 KiB
TypeScript

const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
export const HUB_STATUS: Record<string, string> = {
active: "فعال",
archived: "بایگانی‌شده",
};
export const TEAM_STATUS: Record<string, string> = {
active: "فعال",
archived: "بایگانی‌شده",
};
export const TEAM_ROLE: Record<string, string> = {
owner: "مالک",
manager: "مدیر",
member: "عضو",
viewer: "ناظر",
};
export const PROJECT_STATUS: Record<string, string> = {
planning: "برنامه‌ریزی",
active: "فعال",
on_hold: "متوقف",
completed: "تکمیل‌شده",
archived: "بایگانی‌شده",
};
export const PRIORITY: Record<string, string> = {
low: "کم",
medium: "متوسط",
high: "بالا",
urgent: "فوری",
};
export const TASK_STATUS: Record<string, string> = {
backlog: "بک‌لاگ",
todo: "انجام شود",
in_progress: "در حال انجام",
review: "بررسی",
done: "انجام‌شده",
archived: "بایگانی‌شده",
};
export const KANBAN_COLUMNS = [
{ id: "backlog", label: "بک‌لاگ" },
{ id: "todo", label: "انجام شود" },
{ id: "in_progress", label: "در حال انجام" },
{ id: "review", label: "بررسی" },
{ id: "done", label: "انجام‌شده" },
] as const;
export const CONTENT_STATUS: Record<string, string> = {
draft: "پیش‌نویس",
brief: "بریف",
in_production: "در حال تولید",
internal_review: "بررسی داخلی",
client_review: "بررسی مشتری",
approved: "تأیید شده",
scheduled: "زمان‌بندی شده",
published: "منتشر شده",
archived: "بایگانی‌شده",
};
export const CONTENT_BOARD_COLUMNS = [
{ id: "draft", label: "ایده‌ها", statuses: ["draft"] },
{ id: "brief", label: "بریف", statuses: ["brief"] },
{ id: "in_production", label: "تولید", statuses: ["in_production"] },
{ id: "review", label: "در انتظار بررسی", statuses: ["internal_review", "client_review"] },
{ id: "approved", label: "تأیید شده", statuses: ["approved"] },
{ id: "scheduled", label: "زمان‌بندی شده", statuses: ["scheduled"] },
{ id: "published", label: "منتشر شده", statuses: ["published"] },
] as const;
export const CONTENT_TYPE: Record<string, string> = {
instagram_post: "پست اینستاگرام",
instagram_reel: "ریل اینستاگرام",
instagram_story: "استوری اینستاگرام",
blog_article: "مقاله وبلاگ",
website_page: "محتوای صفحه وب",
video: "ویدیو",
podcast: "پادکست",
advertisement: "تبلیغات",
email: "ایمیل",
sms_brief: "بریف پیامک",
creative_brief: "بریف خلاق",
other: "سایر",
};
export const CHANNEL: Record<string, string> = {
instagram: "اینستاگرام",
blog: "وبلاگ",
website: "وب‌سایت",
video: "ویدیو",
audio: "صوتی",
ads: "تبلیغات",
email: "ایمیل",
sms: "پیامک",
creative: "خلاق",
other: "سایر",
};
export const APPROVAL_TYPE: Record<string, string> = {
internal: "تأیید داخلی",
client: "تأیید مشتری",
final: "تأیید نهایی",
};
export const APPROVAL_STATUS: Record<string, string> = {
pending: "در انتظار",
approved: "تأیید شده",
rejected: "رد شده",
changes_requested: "نیاز به اصلاح",
};
export const BRIEF_FIELDS: { key: string; label: string; multiline?: boolean }[] = [
{ key: "objective", label: "هدف", multiline: true },
{ key: "audience", label: "مخاطب" },
{ key: "key_message", label: "پیام کلیدی", multiline: true },
{ key: "hook", label: "هوک" },
{ key: "cta", label: "فراخوان عمل" },
{ key: "tone", label: "لحن" },
{ key: "platform", label: "پلتفرم / کانال" },
{ key: "references", label: "مراجع", multiline: true },
{ key: "deliverables", label: "تحویل‌دادنی‌ها", multiline: true },
{ key: "deadline", label: "مهلت" },
{ key: "notes", label: "یادداشت", multiline: true },
];
export const ACTIVITY_ACTION: Record<string, string> = {
created: "ایجاد شد",
updated: "به‌روزرسانی شد",
status_changed: "وضعیت تغییر کرد",
member_added: "عضو اضافه شد",
member_updated: "نقش عضو تغییر کرد",
approval_requested: "تأیید درخواست شد",
approval_responded: "پاسخ تأیید ثبت شد",
asset_referenced: "ارجاع فایل ثبت شد",
commented: "نظر ثبت شد",
};
export function labelOf(map: Record<string, string>, value?: string | null, fallback = "نامشخص") {
if (!value) return fallback;
return map[value] ?? fallback;
}
export function displayPerson(value?: string | null) {
if (!value || value === "unassigned") return "تعیین نشده";
if (UUID_RE.test(value)) return "عضو تیم";
return value;
}
export function isTechnicalId(value?: string | null) {
return !!value && UUID_RE.test(value);
}
export function formatWhen(value?: string | null) {
if (!value) return "—";
const date = new Date(value);
if (Number.isNaN(date.getTime())) return value.slice(0, 10);
return new Intl.DateTimeFormat("fa-IR", { dateStyle: "medium", timeStyle: "short" }).format(date);
}
export function formatDay(value?: string | null) {
if (!value) return "—";
const date = new Date(value);
if (Number.isNaN(date.getTime())) return value.slice(0, 10);
return new Intl.DateTimeFormat("fa-IR", { dateStyle: "medium" }).format(date);
}
export function contentActionLabel(current: string, next: string) {
if (current === "draft" && next === "in_production") return "شروع تولید";
if (current === "brief" && next === "in_production") return "شروع تولید";
if (current === "draft" && next === "brief") return "تکمیل بریف";
if (current === "in_production" && next === "internal_review") return "ارسال برای بررسی";
if (current === "internal_review" && next === "client_review") return "ارسال به بررسی مشتری";
if (next === "scheduled") return "زمان‌بندی انتشار";
if (current === "scheduled" && next === "approved") return "ویرایش زمان‌بندی";
if (next === "published") return "انتشار";
if (next === "archived") return "بایگانی";
if (next === "in_production") return "بازگشت به تولید";
return labelOf(CONTENT_STATUS, next);
}
export function personLabel(value?: string | null, directory?: Record<string, string>) {
if (!value) return "تعیین نشده";
if (directory?.[value]) return directory[value];
return displayPerson(value);
}