add notification context
This commit is contained in:
@@ -8,7 +8,8 @@ export interface NotificationBody {
|
|||||||
id: number,
|
id: number,
|
||||||
message: string,
|
message: string,
|
||||||
status: string | null,
|
status: string | null,
|
||||||
type: string
|
type: string,
|
||||||
|
context: Record<string, string>
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchActiveNotifications() {
|
export async function fetchActiveNotifications() {
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useTranslations } from 'next-intl'
|
||||||
|
|
||||||
|
interface NotificationTextHandlerProps {
|
||||||
|
notificationType: string
|
||||||
|
notificationMessage: string
|
||||||
|
notificationContext: Record<string, string>
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (
|
||||||
|
<div>
|
||||||
|
{getNotificationText()}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -6,9 +6,10 @@ import { useTranslations } from 'next-intl';
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { IconInfoMessage, IconPolicy, IconFiles, IconAccountBalanceWallet, IconCheckbook, IconGavel } from '@/app/ui/icons/icons';
|
import { IconInfoMessage, IconPolicy, IconFiles, IconAccountBalanceWallet, IconCheckbook, IconGavel } from '@/app/ui/icons/icons';
|
||||||
import { useActiveNotifications } from '@/app/hooks/react-query/useActiveNotificationsList';
|
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 { useQueryClient } from '@tanstack/react-query';
|
||||||
import { formatDate } from '@/app/lib/formatDate';
|
import { formatDate } from '@/app/lib/formatDate';
|
||||||
|
import { NotificationTextHandler } from '@/app/components/NotificationTextHandler';
|
||||||
|
|
||||||
export default function NotificationsButton() {
|
export default function NotificationsButton() {
|
||||||
const t = useTranslations('Global');
|
const t = useTranslations('Global');
|
||||||
@@ -220,7 +221,7 @@ export default function NotificationsButton() {
|
|||||||
className="notification-item-header"
|
className="notification-item-header"
|
||||||
>
|
>
|
||||||
<div className="notification-title">
|
<div className="notification-title">
|
||||||
{norificationTranslate.has(item.type) ? norificationTranslate(item.type) : item.type}
|
{norificationTranslate.has(item.message) ? norificationTranslate(item.message) : item.message}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="notification-data">
|
<div className="notification-data">
|
||||||
@@ -229,7 +230,7 @@ export default function NotificationsButton() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="notification-text">
|
<div className="notification-text">
|
||||||
{norificationTranslate.has(item.message) ? norificationTranslate(item.message) : item.message}
|
<NotificationTextHandler notificationType={item.type} notificationMessage={item.message} notificationContext={item.context} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
createColumnHelper,
|
createColumnHelper,
|
||||||
RowSelectionState,
|
RowSelectionState,
|
||||||
} from '@tanstack/react-table';
|
} from '@tanstack/react-table';
|
||||||
|
import { NotificationTextHandler } from '@/app/components/NotificationTextHandler';
|
||||||
|
|
||||||
export function NotificationsList() {
|
export function NotificationsList() {
|
||||||
const t = useTranslations('Global');
|
const t = useTranslations('Global');
|
||||||
@@ -137,18 +137,22 @@ export function NotificationsList() {
|
|||||||
}),
|
}),
|
||||||
columnHelper.accessor('message', {
|
columnHelper.accessor('message', {
|
||||||
id: 'message',
|
id: 'message',
|
||||||
header: () => null, // No header text, using custom header above
|
header: () => null,
|
||||||
cell: ({ row }) => {
|
cell: ({ row }) => {
|
||||||
const item = row.original;
|
const item = row.original;
|
||||||
return (
|
return (
|
||||||
<div className="notification-body">
|
<div className="notification-body">
|
||||||
<div className="notification-header">
|
<div className="notification-header">
|
||||||
{/* Optional header content */}
|
<div
|
||||||
|
className="notification-title"
|
||||||
|
>
|
||||||
|
{norificationTranslate.has(item.message)
|
||||||
|
? norificationTranslate(item.message)
|
||||||
|
: item.message} ({item.id})
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="notification-text">
|
<div className="notification-text">
|
||||||
{norificationTranslate.has(item.message)
|
<NotificationTextHandler notificationType={item.type} notificationMessage={item.message} notificationContext={item.context} />
|
||||||
? norificationTranslate(item.message)
|
|
||||||
: item.message} ({item.id})
|
|
||||||
</div>
|
</div>
|
||||||
<div className="notification-footer">
|
<div className="notification-footer">
|
||||||
<div className="notification-date">
|
<div className="notification-date">
|
||||||
|
|||||||
@@ -605,7 +605,27 @@
|
|||||||
"notification-token-not-found": "Token not found",
|
"notification-token-not-found": "Token not found",
|
||||||
"notification-file-moderation": "File moderation event",
|
"notification-file-moderation": "File moderation event",
|
||||||
"notification-file-added": "File added to system",
|
"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": {
|
"User-status": {
|
||||||
"under-moderation": "Under moderation",
|
"under-moderation": "Under moderation",
|
||||||
|
|||||||
@@ -605,7 +605,27 @@
|
|||||||
"notification-token-not-found": "Токен не найден",
|
"notification-token-not-found": "Токен не найден",
|
||||||
"notification-file-moderation": "Модерация файла",
|
"notification-file-moderation": "Модерация файла",
|
||||||
"notification-file-added": "Файл добавлен в систему",
|
"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": {
|
"User-status": {
|
||||||
"under-moderation": "На модерации",
|
"under-moderation": "На модерации",
|
||||||
@@ -616,7 +636,5 @@
|
|||||||
"user-verification": "Верификация пользователя",
|
"user-verification": "Верификация пользователя",
|
||||||
"Status": "Статус"
|
"Status": "Статус"
|
||||||
},
|
},
|
||||||
"Countryes": {
|
"Countryes": {}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user