150 lines
6.3 KiB
TypeScript
150 lines
6.3 KiB
TypeScript
import type { PlacementStatus, PlacementPostStatus, CostType, PlacementType, InviteLinkType } from "@/lib/types/api";
|
||
|
||
export interface ColumnConfig {
|
||
id: string;
|
||
label: string;
|
||
group: string;
|
||
editable: boolean;
|
||
partialEdit?: 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, partialEdit: true },
|
||
{ id: "status_post", label: "Статус поста", group: "basic", editable: true, partialEdit: 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, partialEdit: true },
|
||
{ id: "cost_before", label: "Стоимость до торга", group: "finance", editable: true },
|
||
{ id: "cost_format", label: "Формат оплаты", group: "finance", editable: true, partialEdit: 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: true, partialEdit: true },
|
||
{ 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);
|
||
};
|