From 13a5db6313298e210989ba3e633c529527d10ee2 Mon Sep 17 00:00:00 2001 From: smanylov Date: Thu, 14 May 2026 14:30:20 +0700 Subject: [PATCH] add notification context --- src/app/actions/notificationActions.ts | 3 +- .../components/NotificationTextHandler.tsx | 103 ++++++++++++++++++ src/app/ui/header/notificationsButton.tsx | 7 +- .../ui/notifications/notifications-list.tsx | 16 ++- src/i18n/messages/en.json | 22 +++- src/i18n/messages/ru.json | 26 ++++- 6 files changed, 162 insertions(+), 15 deletions(-) create mode 100644 src/app/components/NotificationTextHandler.tsx diff --git a/src/app/actions/notificationActions.ts b/src/app/actions/notificationActions.ts index 17ed20d..b96c0a2 100644 --- a/src/app/actions/notificationActions.ts +++ b/src/app/actions/notificationActions.ts @@ -8,7 +8,8 @@ export interface NotificationBody { id: number, message: string, status: string | null, - type: string + type: string, + context: Record } export async function fetchActiveNotifications() { diff --git a/src/app/components/NotificationTextHandler.tsx b/src/app/components/NotificationTextHandler.tsx new file mode 100644 index 0000000..1f9c8a3 --- /dev/null +++ b/src/app/components/NotificationTextHandler.tsx @@ -0,0 +1,103 @@ +'use client' + +import { useTranslations } from 'next-intl' + +interface NotificationTextHandlerProps { + notificationType: string + notificationMessage: string + notificationContext: Record +} + +export function NotificationTextHandler({ + notificationType, + notificationMessage, + notificationContext +}: NotificationTextHandlerProps) { + const t = useTranslations('Notifications'); + + const getNotificationText = () => { + if (!notificationType) { + return t.has(notificationMessage) ? t(notificationMessage) : notificationMessage + } + + switch (notificationType) { + case 'USER_VERIFIED': + return t('user-verified', { + status: notificationContext?.status || t('not-specified'), + updateDate: notificationContext?.update_date || t('not-specified-date') + }); + + case 'MONITORING_RESULT': + return t('monitoring-result', { + message: notificationContext?.message || t('message-missing') + }); + + case 'COMPLAINT_STATUS_CHANGED': + return t('complaint-status-changed', { + newStatus: notificationContext?.new_status || t('not-specified'), + oldStatus: notificationContext?.old_status || t('not-specified'), + violation: notificationContext?.violation || t('not-specified'), + file: notificationContext?.file || t('not-specified') + }); + + case 'FILE_ADDED_TO_SYSTEM': + return t('file-added-to-system', { + status: notificationContext?.status || t('not-specified'), + fileName: notificationContext?.file_name || t('not-specified-file-name') + }); + + case 'FILE_MODERATION_EVENT': + return t('file-moderation-event', { + fileName: notificationContext?.file_name || t('not-specified-file-name'), + oldStatus: notificationContext?.old_status || t('not-specified'), + newStatus: notificationContext?.new_status || t('not-specified'), + comment: notificationContext?.comment || t('no-comment') + }); + + case 'PAYMENT_RESULT': + return t('payment-result', { + status: notificationContext?.status || t('not-specified'), + amount: notificationContext?.amount || '0' + }); + + case 'REFERRAL_REGISTERED': + return t('referral-registered', { + referralUser: notificationContext?.referral_user || t('unknown-user') + }); + + case 'SEARCH_RESULT': + return t('search-result', { + startDate: notificationContext?.start_date || t('not-specified-date'), + endDate: notificationContext?.end_date || t('not-specified-date'), + searchType: notificationContext?.search_type || t('not-specified'), + count: notificationContext?.count || '0' + }); + + case 'SEARCH_OPERATION_FAILED': + return t('search-operation-failed', { + status: notificationContext?.status || t('not-specified'), + errorMessage: notificationContext?.error_message || t('error-not-described'), + message: notificationContext?.message || t('message-missing'), + reason: notificationContext?.reason || t('reason-not-specified'), + nextRun: notificationContext?.next_run || t('not-scheduled') + }); + + case 'TOKEN_NOT_FOUND': + return t('token-not-found', { + currentTokens: notificationContext?.current_tokens || '0', + needTokens: notificationContext?.need_tokens || t('not-specified'), + message: notificationContext?.message || t('message-missing'), + nextRun: notificationContext?.next_run || t('not-scheduled') + }); + + default: + return notificationMessage || t('notification-without-text'); + } + }; + + return ( +
+ {getNotificationText()} +
+ ); +} \ No newline at end of file diff --git a/src/app/ui/header/notificationsButton.tsx b/src/app/ui/header/notificationsButton.tsx index 04554ae..e76a921 100644 --- a/src/app/ui/header/notificationsButton.tsx +++ b/src/app/ui/header/notificationsButton.tsx @@ -6,9 +6,10 @@ import { useTranslations } from 'next-intl'; import Link from 'next/link'; import { IconInfoMessage, IconPolicy, IconFiles, IconAccountBalanceWallet, IconCheckbook, IconGavel } from '@/app/ui/icons/icons'; import { useActiveNotifications } from '@/app/hooks/react-query/useActiveNotificationsList'; -import { NotificationBody, notificationsMarkAsRead } from '@/app/actions/notificationActions'; +import { notificationsMarkAsRead } from '@/app/actions/notificationActions'; import { useQueryClient } from '@tanstack/react-query'; import { formatDate } from '@/app/lib/formatDate'; +import { NotificationTextHandler } from '@/app/components/NotificationTextHandler'; export default function NotificationsButton() { const t = useTranslations('Global'); @@ -220,7 +221,7 @@ export default function NotificationsButton() { className="notification-item-header" >
- {norificationTranslate.has(item.type) ? norificationTranslate(item.type) : item.type} + {norificationTranslate.has(item.message) ? norificationTranslate(item.message) : item.message}
@@ -229,7 +230,7 @@ export default function NotificationsButton() {
- {norificationTranslate.has(item.message) ? norificationTranslate(item.message) : item.message} +
diff --git a/src/app/ui/notifications/notifications-list.tsx b/src/app/ui/notifications/notifications-list.tsx index aab28c9..4e016e9 100644 --- a/src/app/ui/notifications/notifications-list.tsx +++ b/src/app/ui/notifications/notifications-list.tsx @@ -16,7 +16,7 @@ import { createColumnHelper, RowSelectionState, } from '@tanstack/react-table'; - +import { NotificationTextHandler } from '@/app/components/NotificationTextHandler'; export function NotificationsList() { const t = useTranslations('Global'); @@ -137,18 +137,22 @@ export function NotificationsList() { }), columnHelper.accessor('message', { id: 'message', - header: () => null, // No header text, using custom header above + header: () => null, cell: ({ row }) => { const item = row.original; return (
- {/* Optional header content */} +
+ {norificationTranslate.has(item.message) + ? norificationTranslate(item.message) + : item.message} ({item.id}) +
- {norificationTranslate.has(item.message) - ? norificationTranslate(item.message) - : item.message} ({item.id}) +
diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index e1d5792..97dd619 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -605,7 +605,27 @@ "notification-token-not-found": "Token not found", "notification-file-moderation": "File moderation event", "notification-file-added": "File added to system", - "notification-search-operation-filed": "Search operation failed" + "notification-search-operation-filed": "Search operation failed", + "not-specified": "not specified", + "not-specified-date": "not specified", + "not-specified-file-name": "not specified", + "message-missing": "message missing", + "reason-not-specified": "reason not specified", + "no-comment": "no comment", + "unknown-user": "unknown user", + "error-not-described": "error not described", + "not-scheduled": "not scheduled", + "notification-without-text": "Notification without text", + "user-verified": "Status: {status}. Update date: {updateDate}", + "monitoring-result": "Monitoring result: {message}", + "complaint-status-changed": "Complaint status changed from {oldStatus} to {newStatus}. Violation: {violation}. File: {file}", + "file-added-to-system": "Status: {status}. File name: {fileName}", + "file-moderation-event": "File moderation for '{fileName}'. Status changed from {oldStatus} to {newStatus}. Comment: {comment}", + "payment-result": "Payment result: {status}. Amount: {amount}", + "referral-registered": "Referral registered: {referralUser}", + "search-result": "Search results from {startDate} to {endDate}. Type: {searchType}. Files found: {count}", + "search-operation-failed": "Status: {status}. Message: {message}. Reason: {reason}. Next run: {nextRun}", + "token-not-found": "Current: {currentTokens}, needed: {needTokens}. Message: {message}. Next run: {nextRun}" }, "User-status": { "under-moderation": "Under moderation", diff --git a/src/i18n/messages/ru.json b/src/i18n/messages/ru.json index f04c0d3..c554d6c 100644 --- a/src/i18n/messages/ru.json +++ b/src/i18n/messages/ru.json @@ -605,7 +605,27 @@ "notification-token-not-found": "Токен не найден", "notification-file-moderation": "Модерация файла", "notification-file-added": "Файл добавлен в систему", - "notification-search-operation-filed": "Ошибка операции поиска" + "notification-search-operation-filed": "Ошибка операции поиска", + "not-specified": "не указан", + "not-specified-date": "не указана", + "not-specified-file-name": "не указано", + "message-missing": "сообщение отсутствует", + "reason-not-specified": "причина не указана", + "no-comment": "без комментария", + "unknown-user": "неизвестный пользователь", + "error-not-described": "ошибка не описана", + "not-scheduled": "не запланирован", + "notification-without-text": "Уведомление без текста", + "user-verified": "Статус: {status}. Дата обновления: {updateDate}", + "monitoring-result": "Результат мониторинга: {message}", + "complaint-status-changed": "Статус жалобы изменён с {oldStatus} на {newStatus}. Нарушение: {violation}. Файл: {file}", + "file-added-to-system": "Статус: {status}. Имя файла: {fileName}", + "file-moderation-event": "Модерация файла '{fileName}'. Статус изменён с {oldStatus} на {newStatus}. Комментарий: {comment}", + "payment-result": "Результат платежа: {status}. Сумма: {amount}", + "referral-registered": "Зарегистрирован реферал: {referralUser}", + "search-result": "Результаты поиска с {startDate} по {endDate}. Тип: {searchType}. Найдено файлов: {count}", + "search-operation-failed": "Статус: {status}. Сообщение: {message}. Причина: {reason}. Следующий запуск: {nextRun}", + "token-not-found": "Текущие: {currentTokens}, необходимо: {needTokens}. Сообщение: {message}. Следующий запуск: {nextRun}" }, "User-status": { "under-moderation": "На модерации", @@ -616,7 +636,5 @@ "user-verification": "Верификация пользователя", "Status": "Статус" }, - "Countryes": { - - } + "Countryes": {} } \ No newline at end of file