finished header notifications
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "no-copy-frontend",
|
"name": "no-copy-frontend",
|
||||||
"version": "0.78.0",
|
"version": "0.79.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev -p 2999",
|
"dev": "next dev -p 2999",
|
||||||
|
|||||||
@@ -0,0 +1,130 @@
|
|||||||
|
'use server'
|
||||||
|
|
||||||
|
import { getSessionData } from '@/app/actions/session';
|
||||||
|
import { API_BASE_URL } from '@/app/actions/definitions';
|
||||||
|
|
||||||
|
export interface NotificationBody {
|
||||||
|
createdAt: string | null,
|
||||||
|
id: number,
|
||||||
|
message: string,
|
||||||
|
status: string | null,
|
||||||
|
type: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchActiveNotifications() {
|
||||||
|
const token = await getSessionData('token');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${API_BASE_URL}/api/v1/data`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
version: 1,
|
||||||
|
msg_id: 30015,
|
||||||
|
message_body: {
|
||||||
|
action: 'active',
|
||||||
|
authToken: token,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Accept': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
let parsed = await response.json();
|
||||||
|
|
||||||
|
if (parsed?.message_body) {
|
||||||
|
return parsed?.message_body
|
||||||
|
} else {
|
||||||
|
throw parsed;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw (`${response.status}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchAllNotifications() {
|
||||||
|
const token = await getSessionData('token');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${API_BASE_URL}/api/v1/data`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
version: 1,
|
||||||
|
msg_id: 30015,
|
||||||
|
message_body: {
|
||||||
|
action: 'list',
|
||||||
|
authToken: token,
|
||||||
|
page: 0,
|
||||||
|
size: 10,
|
||||||
|
sortBy: "createdAt",
|
||||||
|
sortDirection: "DESC",
|
||||||
|
types: [], //"SEARCH_RESULT", "MONITORING_RESULT"
|
||||||
|
statuses: [] //"NEW"
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Accept': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
let parsed = await response.json();
|
||||||
|
|
||||||
|
if (parsed?.message_body) {
|
||||||
|
return parsed?.message_body
|
||||||
|
} else {
|
||||||
|
throw parsed;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw (`${response.status}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function notificationsMarkAsRead(ids: number[]) {
|
||||||
|
const token = await getSessionData('token');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${API_BASE_URL}/api/v1/data`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
version: 1,
|
||||||
|
msg_id: 30015,
|
||||||
|
message_body: {
|
||||||
|
action: 'markRead',
|
||||||
|
authToken: token,
|
||||||
|
notificationIds: ids
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Accept': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
let parsed = await response.json();
|
||||||
|
|
||||||
|
if (parsed?.message_body) {
|
||||||
|
return parsed?.message_body
|
||||||
|
} else {
|
||||||
|
throw parsed;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw (`${response.status}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
success: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
import { fetchActiveNotifications, NotificationBody } from '@/app/actions/notificationActions';
|
||||||
|
|
||||||
|
export interface UseActiveNotifications {
|
||||||
|
notifications: NotificationBody[],
|
||||||
|
unreadCount: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useActiveNotifications = () => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: ['activeNotifications'],
|
||||||
|
queryFn: () => {
|
||||||
|
return fetchActiveNotifications()
|
||||||
|
},
|
||||||
|
select: (data: UseActiveNotifications | null) => {
|
||||||
|
if (!data) {
|
||||||
|
return {
|
||||||
|
notifications: [],
|
||||||
|
unreadCount: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
retry: false,
|
||||||
|
refetchInterval: 10000
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
import { fetchAllNotifications, NotificationBody } from '@/app/actions/notificationActions';
|
||||||
|
|
||||||
|
export interface UseAllNotifications {
|
||||||
|
notifications: NotificationBody[],
|
||||||
|
unreadCount: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useAllNotifications = () => {
|
||||||
|
return useQuery({
|
||||||
|
queryKey: ['allNotifications'],
|
||||||
|
queryFn: () => {
|
||||||
|
return fetchAllNotifications()
|
||||||
|
},
|
||||||
|
select: (data: UseAllNotifications | null) => {
|
||||||
|
if (!data) {
|
||||||
|
return {
|
||||||
|
notifications: [],
|
||||||
|
unreadCount: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
retry: false,
|
||||||
|
refetchInterval: 10000
|
||||||
|
});
|
||||||
|
};
|
||||||
+33
-13
@@ -148,6 +148,10 @@
|
|||||||
color: v.$p-color;
|
color: v.$p-color;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: v.$p-color-hover;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-list {
|
&-list {
|
||||||
@@ -161,7 +165,10 @@
|
|||||||
padding: 5px 10px 5px 10px;
|
padding: 5px 10px 5px 10px;
|
||||||
border-bottom: 1px solid v.$b-color-1;
|
border-bottom: 1px solid v.$b-color-1;
|
||||||
transition: background-color 0.2s;
|
transition: background-color 0.2s;
|
||||||
cursor: pointer;
|
|
||||||
|
&.loading {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-title {
|
&-title {
|
||||||
@@ -180,17 +187,6 @@
|
|||||||
align-items: center; */
|
align-items: center; */
|
||||||
}
|
}
|
||||||
|
|
||||||
&-icon {
|
|
||||||
font-size: 24px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
color: v.$p-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-text {
|
&-text {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: v.$text-s;
|
color: v.$text-s;
|
||||||
@@ -198,7 +194,8 @@
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-data {
|
&-data,
|
||||||
|
&-mark-as-read {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
color: v.$text-m;
|
color: v.$text-m;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -208,10 +205,25 @@
|
|||||||
right: 0px;
|
right: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-mark-as-read {
|
||||||
|
font-size: 12px;
|
||||||
|
bottom: 0px;
|
||||||
|
top: auto;
|
||||||
|
cursor: pointer;
|
||||||
|
height: max-content;
|
||||||
|
|
||||||
|
color: v.$p-color;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: v.$p-color-hover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&-footer {
|
&-footer {
|
||||||
padding: 12px 20px;
|
padding: 12px 20px;
|
||||||
border-top: 1px solid v.$b-color-1;
|
border-top: 1px solid v.$b-color-1;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
.notification-link {
|
.notification-link {
|
||||||
color: v.$p-color;
|
color: v.$p-color;
|
||||||
@@ -219,6 +231,14 @@
|
|||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: v.$p-color-hover;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
$p-color: #6366f1;
|
$p-color: #6366f1;
|
||||||
|
$p-color-hover: #1e0ff0;
|
||||||
$s-color: #8b5cf6;
|
$s-color: #8b5cf6;
|
||||||
$text-p: #1f2937;
|
$text-p: #1f2937;
|
||||||
$text-s: #4b5563;
|
$text-s: #4b5563;
|
||||||
|
|||||||
@@ -5,55 +5,24 @@ import { useClickOutside } from '@/app/hooks/useClickOutside';
|
|||||||
import { useTranslations } from 'next-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { IconNotification } from '@/app/ui/icons/icons';
|
import { IconNotification } from '@/app/ui/icons/icons';
|
||||||
|
import { useActiveNotifications } from '@/app/hooks/react-query/useActiveNotificationsList';
|
||||||
interface Notification {
|
import { NotificationBody, notificationsMarkAsRead } from '@/app/actions/notificationActions';
|
||||||
id: string,
|
import { useQueryClient } from '@tanstack/react-query';
|
||||||
notificationText: string,
|
|
||||||
data: string,
|
|
||||||
link: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function NotificationsButton() {
|
export default function NotificationsButton() {
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [notificationData, setNotificationData] = useState<Notification[] | []>([]);
|
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const menuRef = useRef<HTMLDivElement | null>(null);
|
const menuRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
const [loadingIds, setLoadingIds] = useState<Set<number>>(new Set());
|
||||||
|
const [isMarkingAll, setIsMarkingAll] = useState(false);
|
||||||
const t = useTranslations('Global');
|
const t = useTranslations('Global');
|
||||||
|
|
||||||
|
const { data: notificationList } = useActiveNotifications();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setNotificationData([
|
console.log(notificationList);
|
||||||
{
|
}, [notificationList])
|
||||||
id: '1',
|
|
||||||
notificationText: 'text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1',
|
|
||||||
data: '20.20.20',
|
|
||||||
link: '#'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '2',
|
|
||||||
notificationText: 'text2',
|
|
||||||
data: '20.20.20',
|
|
||||||
link: '#'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '3',
|
|
||||||
notificationText: 'text3',
|
|
||||||
data: '20.20.20',
|
|
||||||
link: '#'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '4',
|
|
||||||
notificationText: 'text4',
|
|
||||||
data: '20.20.20',
|
|
||||||
link: '#'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '5',
|
|
||||||
notificationText: 'text5',
|
|
||||||
data: '20.20.20',
|
|
||||||
link: '#'
|
|
||||||
}
|
|
||||||
])
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
useClickOutside(
|
useClickOutside(
|
||||||
menuRef,
|
menuRef,
|
||||||
@@ -71,12 +40,42 @@ export default function NotificationsButton() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function markAsReadHandler() {
|
async function markAsReadHandler(ids: number[]) {
|
||||||
console.log('click: mark as read');
|
setLoadingIds(prev => {
|
||||||
|
const newSet = new Set(prev);
|
||||||
|
ids.forEach(id => newSet.add(id));
|
||||||
|
return newSet;
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await notificationsMarkAsRead(ids);
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
await queryClient.invalidateQueries({ queryKey: ['activeNotifications'] });
|
||||||
|
await queryClient.invalidateQueries({ queryKey: ['allNotifications'] });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
setError(error instanceof Error ? error.message : 'Failed to mark as read');
|
||||||
|
} finally {
|
||||||
|
setLoadingIds(prev => {
|
||||||
|
const newSet = new Set(prev);
|
||||||
|
ids.forEach(id => newSet.delete(id));
|
||||||
|
return newSet;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function notificationClickHandler(id: string) {
|
async function markAllAsReadHandler() {
|
||||||
console.log(`click: ${id}`);
|
const array = notificationList?.notifications?.map(e => e.id) ?? [];
|
||||||
|
if (array.length === 0) return;
|
||||||
|
|
||||||
|
setIsMarkingAll(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await markAsReadHandler(array);
|
||||||
|
} finally {
|
||||||
|
setIsMarkingAll(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -107,57 +106,79 @@ export default function NotificationsButton() {
|
|||||||
setIsOpen(false);
|
setIsOpen(false);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{t('no-new')} / {t('all')}
|
{notificationList?.unreadCount ? notificationList?.unreadCount : t('no-new')} / {t('all')}
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
{notificationData.length !== 0 ? (
|
{notificationList?.notifications.length !== 0 ? (
|
||||||
<div
|
<>
|
||||||
className="notification-list"
|
<div
|
||||||
>
|
className="notification-list"
|
||||||
{notificationData.map((item) => {
|
>
|
||||||
return (
|
{notificationList?.notifications?.map((item) => {
|
||||||
<div
|
return (
|
||||||
key={item.id}
|
<div
|
||||||
className="notification-item"
|
key={item.id}
|
||||||
onClick={() => {
|
className={`notification-item ${loadingIds.has(item.id) ? 'loading' : ''}`}
|
||||||
notificationClickHandler(item.id);
|
>
|
||||||
}}
|
<div className="notification-content">
|
||||||
>
|
<div className="notification-data">
|
||||||
<div className="notification-icon">
|
{item.createdAt ? item.createdAt : '#'}
|
||||||
<IconNotification />
|
</div>
|
||||||
</div>
|
|
||||||
<div className="notification-content">
|
|
||||||
<div className="notification-data">
|
|
||||||
{item.data}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* <div className="notification-title">
|
{/* <div className="notification-title">
|
||||||
{t('tokens-added')}
|
{t('tokens-added')}
|
||||||
</div> */}
|
</div> */}
|
||||||
|
|
||||||
<div className="notification-text">
|
<div className="notification-text">
|
||||||
{item.notificationText}
|
{item.message}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="notification-mark-as-read"
|
||||||
|
onClick={() => {
|
||||||
|
markAsReadHandler([item.id]);
|
||||||
|
}}
|
||||||
|
disabled={loadingIds.has(item.id)}
|
||||||
|
>
|
||||||
|
{t('mark-as-read')}
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{loadingIds.has(item.id) && (
|
||||||
|
<div className="loading-animation">
|
||||||
|
<div className="global-spinner"></div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)
|
||||||
)
|
})}
|
||||||
})}
|
</div>
|
||||||
</div>
|
|
||||||
|
<div className="notification-footer">
|
||||||
|
<button
|
||||||
|
className="notification-link"
|
||||||
|
onClick={() => {
|
||||||
|
markAllAsReadHandler()
|
||||||
|
}}
|
||||||
|
disabled={isMarkingAll || loadingIds.size > 0}
|
||||||
|
>
|
||||||
|
{isMarkingAll || loadingIds.size > 0 && (
|
||||||
|
<div className="loading-animation">
|
||||||
|
<div className="global-spinner"></div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{t('mark-all-as-read')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
<p>
|
<p
|
||||||
{/* {t('no-data')} */}
|
className="text-center mb-4 mt-4"
|
||||||
|
>
|
||||||
|
{t('no-new-notifications')}
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
<div className="notification-footer">
|
|
||||||
<button
|
|
||||||
className="notification-link"
|
|
||||||
onClick={() => {
|
|
||||||
markAsReadHandler();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t('mark-all-as-read')}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,65 +2,19 @@
|
|||||||
|
|
||||||
import { useTranslations } from 'next-intl';
|
import { useTranslations } from 'next-intl';
|
||||||
import { IconCheck } from '@/app/ui/icons/icons';
|
import { IconCheck } from '@/app/ui/icons/icons';
|
||||||
import { useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
import { useAllNotifications } from '@/app/hooks/react-query/useAllNotificationsList';
|
||||||
interface Notification {
|
|
||||||
id: string,
|
|
||||||
notificationText: string,
|
|
||||||
data: string,
|
|
||||||
link: string,
|
|
||||||
title: string,
|
|
||||||
status: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
const noitficationList: Notification[] = [
|
|
||||||
{
|
|
||||||
id: '1',
|
|
||||||
notificationText: 'text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1 text1',
|
|
||||||
data: '20.20.20',
|
|
||||||
link: '#',
|
|
||||||
title: 'title 1',
|
|
||||||
status: 'status'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '2',
|
|
||||||
notificationText: 'text2 text2 text2 text2 text2 text2 text2 text2 text2 text2 text2 text2 text2 text2 text2 text2 text2 text2 text2 text2 text2 text2 text2 text2 text2 ',
|
|
||||||
data: '20.20.20',
|
|
||||||
link: '#',
|
|
||||||
title: 'title 2',
|
|
||||||
status: 'status'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '3',
|
|
||||||
notificationText: 'text3 text3 text3 text3 text3 text3 text3 text3 text3 text3 text3 text3 text3 text3 text3 text3 text3 text3 text3 text3 text3 text3 text3 text3 ',
|
|
||||||
data: '20.20.20',
|
|
||||||
link: '#',
|
|
||||||
title: 'title 3',
|
|
||||||
status: 'status'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '4',
|
|
||||||
notificationText: 'text4 text4 text4 text4 text4 text4 text4 text4 text4 text4 text4 text4 text4 text4 text4 text4 text4 text4 text4 text4 text4 text4 text4 text4 text4 ',
|
|
||||||
data: '20.20.20',
|
|
||||||
link: '#',
|
|
||||||
title: 'title 4',
|
|
||||||
status: 'status'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '5',
|
|
||||||
notificationText: 'text5 text5 text5 text5 text5 text5 text5 text5 text5 text5 text5 text5 text5 text5 text5 text5 text5 text5 text5 text5 text5 text5 text5 text5 text5 ',
|
|
||||||
data: '20.20.20',
|
|
||||||
link: '#',
|
|
||||||
title: 'title 5',
|
|
||||||
status: 'status'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
export function NotificationsList() {
|
export function NotificationsList() {
|
||||||
const t = useTranslations('Global');
|
const t = useTranslations('Global');
|
||||||
const [selectedFiles, setSelectedFiles] = useState<Set<string>>(new Set());
|
const [selectedFiles, setSelectedFiles] = useState<Set<number>>(new Set());
|
||||||
|
const { data: allNotifications } = useAllNotifications();
|
||||||
|
|
||||||
function selectHandler(fileId: string) {
|
useEffect(() => {
|
||||||
|
console.log(allNotifications);
|
||||||
|
}, [allNotifications])
|
||||||
|
|
||||||
|
function selectHandler(fileId: number) {
|
||||||
setSelectedFiles((prev) => {
|
setSelectedFiles((prev) => {
|
||||||
const newSet = new Set(prev);
|
const newSet = new Set(prev);
|
||||||
|
|
||||||
@@ -78,7 +32,7 @@ export function NotificationsList() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function selectAllHandler() {
|
function selectAllHandler() {
|
||||||
setSelectedFiles(new Set(noitficationList.map(item => item.id)));
|
setSelectedFiles(new Set(allNotifications?.notifications.map(item => item.id)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -129,8 +83,8 @@ export function NotificationsList() {
|
|||||||
<div
|
<div
|
||||||
className="notifications-list-body"
|
className="notifications-list-body"
|
||||||
>
|
>
|
||||||
{(noitficationList.length !== 0) && (
|
{(allNotifications?.notifications.length !== 0) && (
|
||||||
noitficationList.map(item => {
|
allNotifications?.notifications.map(item => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="notification-item"
|
className="notification-item"
|
||||||
@@ -159,7 +113,7 @@ export function NotificationsList() {
|
|||||||
<div
|
<div
|
||||||
className="notification-title"
|
className="notification-title"
|
||||||
>
|
>
|
||||||
{item.title}
|
{item.type}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="notification-status"
|
className="notification-status"
|
||||||
@@ -170,7 +124,7 @@ export function NotificationsList() {
|
|||||||
<div
|
<div
|
||||||
className="notification-text"
|
className="notification-text"
|
||||||
>
|
>
|
||||||
{item.notificationText}
|
{item.message}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="notification-footer"
|
className="notification-footer"
|
||||||
@@ -178,7 +132,7 @@ export function NotificationsList() {
|
|||||||
<div
|
<div
|
||||||
className="notification-date"
|
className="notification-date"
|
||||||
>
|
>
|
||||||
{item.data}
|
{item.createdAt}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -385,6 +385,7 @@
|
|||||||
"all-statuses": "All statuses",
|
"all-statuses": "All statuses",
|
||||||
"all": "All",
|
"all": "All",
|
||||||
"mark-all-as-read": "Mark all as read",
|
"mark-all-as-read": "Mark all as read",
|
||||||
|
"mark-as-read": "Mark as read",
|
||||||
"all-notifications": "All notifications",
|
"all-notifications": "All notifications",
|
||||||
"deselect": "Deselect",
|
"deselect": "Deselect",
|
||||||
"select-all": "Select all",
|
"select-all": "Select all",
|
||||||
@@ -400,7 +401,8 @@
|
|||||||
"when-you-pay-for-a-subscription-your-card-is-saved-for-automatic-renewal": "When you pay for a subscription, your card is saved for automatic renewal.",
|
"when-you-pay-for-a-subscription-your-card-is-saved-for-automatic-renewal": "When you pay for a subscription, your card is saved for automatic renewal.",
|
||||||
"the-debit-occurs-1-day-before-the-end-of-the-subscription": "The debit occurs 1 day before the end of the subscription.",
|
"the-debit-occurs-1-day-before-the-end-of-the-subscription": "The debit occurs 1 day before the end of the subscription.",
|
||||||
"you-can-unlink-your-card-and-cancel-auto-renewal-at-any-time": "You can unlink your card and cancel auto-renewal at any time.",
|
"you-can-unlink-your-card-and-cancel-auto-renewal-at-any-time": "You can unlink your card and cancel auto-renewal at any time.",
|
||||||
"delete-a-bank-card": "Delete a bank card"
|
"delete-a-bank-card": "Delete a bank card",
|
||||||
|
"no-new-notifications": "There are no new notifications"
|
||||||
},
|
},
|
||||||
"Login-register-form": {
|
"Login-register-form": {
|
||||||
"and": "and",
|
"and": "and",
|
||||||
|
|||||||
@@ -385,6 +385,7 @@
|
|||||||
"all-statuses": "Все статусы",
|
"all-statuses": "Все статусы",
|
||||||
"all": "Все",
|
"all": "Все",
|
||||||
"mark-all-as-read": "Отметить все как прочитанное",
|
"mark-all-as-read": "Отметить все как прочитанное",
|
||||||
|
"mark-as-read": "Отметить как прочитанное",
|
||||||
"all-notifications": "Все уведомления",
|
"all-notifications": "Все уведомления",
|
||||||
"deselect": "Снять выделение",
|
"deselect": "Снять выделение",
|
||||||
"select-all": "Выбрать все",
|
"select-all": "Выбрать все",
|
||||||
@@ -400,7 +401,8 @@
|
|||||||
"when-you-pay-for-a-subscription-your-card-is-saved-for-automatic-renewal": "При оплате подписки ваша карта сохраняется для автоматического продления.",
|
"when-you-pay-for-a-subscription-your-card-is-saved-for-automatic-renewal": "При оплате подписки ваша карта сохраняется для автоматического продления.",
|
||||||
"the-debit-occurs-1-day-before-the-end-of-the-subscription": "Списание происходит за 1 день до окончания подписки.",
|
"the-debit-occurs-1-day-before-the-end-of-the-subscription": "Списание происходит за 1 день до окончания подписки.",
|
||||||
"you-can-unlink-your-card-and-cancel-auto-renewal-at-any-time": "Вы можете отвязать карту и отменить автопродление в любой момент.",
|
"you-can-unlink-your-card-and-cancel-auto-renewal-at-any-time": "Вы можете отвязать карту и отменить автопродление в любой момент.",
|
||||||
"delete-a-bank-card": "Удалить банковскую карту"
|
"delete-a-bank-card": "Удалить банковскую карту",
|
||||||
|
"no-new-notifications": "Новых уведомлений нет"
|
||||||
},
|
},
|
||||||
"Login-register-form": {
|
"Login-register-form": {
|
||||||
"and": "и",
|
"and": "и",
|
||||||
|
|||||||
Reference in New Issue
Block a user