Files
tgex-frontend/lib/config/placement-columns.ts
2026-02-02 21:01:11 +03:00

149 lines
6.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { PlacementStatus, PlacementPostStatus, CostType, PlacementType, InviteLinkType } from "@/lib/types/api";
export interface ColumnConfig {
id: string;
label: string;
group: string;
editable: boolean;
width?: string;
required?: boolean;
}
export const COLUMN_GROUPS = [
{ id: "basic", label: "Основная информация" },
{ id: "content", label: "Контент" },
{ id: "finance", label: "Финансы" },
{ id: "dates", label: "Даты и время" },
{ id: "metrics", label: "Метрики" },
{ id: "calculated", label: "Расчетные показатели" },
{ id: "technical", label: "Технические детали" },
] as const;
export const ALL_COLUMNS: ColumnConfig[] = [
// Basic
{ id: "checkbox", label: "", group: "basic", editable: false, required: true },
{ id: "number", label: "№", group: "basic", editable: false, required: true },
{ id: "status_deal", label: "Статус сделки", group: "basic", editable: true },
{ id: "status_post", label: "Статус поста", group: "basic", editable: true },
// Content
{ id: "creative", label: "Креатив", group: "content", editable: true },
{ id: "invite_link", label: "Пригласительная ссылка", group: "content", editable: false },
{ id: "post_link", label: "Ссылка на пост", group: "content", editable: false },
// Finance
{ id: "cost", label: "Стоимость", group: "finance", editable: true },
{ id: "cost_before", label: "Стоимость до торга", group: "finance", editable: true },
{ id: "cost_format", label: "Формат оплаты", group: "finance", editable: true },
{ id: "placement_type", label: "Тип закупа", group: "finance", editable: true },
{ id: "discount", label: "% скидки", group: "finance", editable: false },
{ id: "payment_date", label: "Дата оплаты", group: "finance", editable: true },
// Dates
{ id: "planned_date", label: "Плановая дата", group: "dates", editable: true },
{ id: "actual_date", label: "Фактическая дата", group: "dates", editable: false },
{ id: "format", label: "Плановый формат", group: "dates", editable: true },
{ id: "time_top", label: "Время в топе", group: "dates", editable: false },
{ id: "time_in_feed", label: "Время в ленте", group: "dates", editable: false },
{ id: "link_created", label: "Дата ссылки", group: "dates", editable: false },
{ id: "post_deleted", label: "Дата удаления", group: "dates", editable: false },
// Metrics
{ id: "subscriptions", label: "Всего подписок", group: "metrics", editable: false },
{ id: "views", label: "Просмотры", group: "metrics", editable: false },
// Calculated
{ id: "cpf", label: "CPF", group: "calculated", editable: false },
{ id: "cpm", label: "CPM", group: "calculated", editable: false },
{ id: "conversion_24h", label: "Конверсия 24ч", group: "calculated", editable: false },
{ id: "conversion_48h", label: "Конверсия 48ч", group: "calculated", editable: false },
{ id: "conversion_total", label: "Конверсия общ.", group: "calculated", editable: false },
{ id: "total_unsubs", label: "Всего отписок", group: "calculated", editable: false },
{ id: "unsub_percent", label: "% отписок", group: "calculated", editable: false },
{ id: "total_active", label: "Итого подписок", group: "calculated", editable: false },
// Technical
{ id: "invite_type", label: "Тип ссылки", group: "technical", editable: true },
{ id: "comment", label: "Комментарий", group: "technical", editable: true },
] as const;
// Default visible columns
export const DEFAULT_VISIBLE_COLUMNS = new Set([
"checkbox",
"number",
"status_deal",
"status_post",
"creative",
"invite_link",
"cost",
"cost_before",
"cost_format",
"planned_date",
"format",
"subscriptions",
"views",
"cpf",
"cpm",
"comment",
]);
// Status lists
export const PLACEMENT_DEAL_STATUSES: PlacementStatus[] = [
"Без статуса",
"Написать",
"Ждём ответа",
"Согласование условий",
"Оплатить",
"Оплачено",
"Отмена",
"Не подходит цена",
"Неактуально",
"Не отвечает",
];
export const PLACEMENT_POST_STATUSES: PlacementPostStatus[] = [
"Без статуса",
"Отправить пост",
"Согласование поста",
"Ожидание отложки",
"Запланирован",
"Пост вышел",
"Размещение отработало - пост удалён",
"Размещение отработало - пост не удалён",
"Проверить - пост удалён раньше срока",
"Проверить - пост не вышел",
"Размещение отработало",
];
export const COST_FORMATS: CostType[] = ["fixed", "cpm"];
export const PLACEMENT_TYPES: PlacementType[] = ["self_promo", "standard"];
export const INVITE_TYPES: InviteLinkType[] = ["public", "approval"];
// Manual post statuses (user can select before post is published)
export const MANUAL_POST_STATUSES: Set<PlacementPostStatus> = new Set([
"Без статуса",
"Отправить пост",
"Согласование поста",
"Ожидание отложки",
"Запланирован",
]);
// Automatic post statuses (set by backend)
export const AUTOMATIC_POST_STATUSES: Set<PlacementPostStatus> = new Set([
"Пост вышел",
"Размещение отработало - пост удалён",
"Размещение отработало - пост не удалён",
"Проверить - пост удалён раньше срока",
"Проверить - пост не вышел",
"Размещение отработало",
]);
// Helper functions
export const canEditPostStatus = (currentStatus: PlacementPostStatus): boolean => {
return MANUAL_POST_STATUSES.has(currentStatus);
};
export const isAutomaticPostStatus = (status: PlacementPostStatus): boolean => {
return AUTOMATIC_POST_STATUSES.has(status);
};