From 362a69812fb57a8615750d367f73b3a29fda665b Mon Sep 17 00:00:00 2001 From: c0mrade Date: Fri, 10 Apr 2026 17:04:22 +0300 Subject: [PATCH] feat: add broadcast category selector (system/news/promo) in admin UI --- src/api/adminBroadcasts.ts | 4 ++++ src/pages/AdminBroadcastCreate.tsx | 37 ++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/api/adminBroadcasts.ts b/src/api/adminBroadcasts.ts index 4e6fb0a..dfc77ff 100644 --- a/src/api/adminBroadcasts.ts +++ b/src/api/adminBroadcasts.ts @@ -76,6 +76,8 @@ export interface EmailBroadcastCreateRequest { export interface CombinedBroadcastCreateRequest { channel: BroadcastChannel; target: string; + // Broadcast category for user notification preference filtering + category?: 'system' | 'news' | 'promo'; // Telegram fields message_text?: string; selected_buttons?: string[]; @@ -111,6 +113,8 @@ export interface Broadcast { created_at: string; completed_at: string | null; progress_percent: number; + // Broadcast category + category?: 'system' | 'news' | 'promo'; // New fields for channel support channel?: BroadcastChannel; email_subject?: string | null; diff --git a/src/pages/AdminBroadcastCreate.tsx b/src/pages/AdminBroadcastCreate.tsx index 1709aab..de04726 100644 --- a/src/pages/AdminBroadcastCreate.tsx +++ b/src/pages/AdminBroadcastCreate.tsx @@ -128,6 +128,9 @@ export default function AdminBroadcastCreate() { const [showTelegramFilters, setShowTelegramFilters] = useState(false); const [showEmailFilters, setShowEmailFilters] = useState(false); + // Broadcast category (system/news/promo) + const [category, setCategory] = useState<'system' | 'news' | 'promo'>('system'); + // Telegram-specific state const [messageText, setMessageText] = useState(''); const [selectedButtons, setSelectedButtons] = useState(['home']); @@ -395,6 +398,7 @@ export default function AdminBroadcastCreate() { message_text: messageText, selected_buttons: selectedButtons, custom_buttons: customButtons.length > 0 ? customButtons : undefined, + category, }; if (uploadedFileId) { data.media = { type: mediaType, file_id: uploadedFileId }; @@ -409,6 +413,7 @@ export default function AdminBroadcastCreate() { target: emailTarget, email_subject: emailSubject, email_html_content: emailContent, + category, }; createMutation.mutate(data); return; @@ -423,6 +428,7 @@ export default function AdminBroadcastCreate() { message_text: messageText, selected_buttons: selectedButtons, custom_buttons: customButtons.length > 0 ? customButtons : undefined, + category, }; if (uploadedFileId) { telegramData.media = { type: mediaType, file_id: uploadedFileId }; @@ -433,6 +439,7 @@ export default function AdminBroadcastCreate() { target: emailTarget, email_subject: emailSubject, email_html_content: emailContent, + category, }; await adminBroadcastsApi.createCombined(telegramData); @@ -583,6 +590,36 @@ export default function AdminBroadcastCreate() { )} + {/* Broadcast category */} +
+ +

+ {t( + 'admin.broadcasts.categoryDesc', + 'Пользователи могут отключить получение новостей и промо в настройках профиля. Системные рассылки доставляются всем.', + )} +

+
+ {(['system', 'news', 'promo'] as const).map((cat) => ( + + ))} +
+
+ {/* Telegram section */} {telegramEnabled && (