change notification styles

This commit is contained in:
smanylov
2026-04-15 15:31:01 +07:00
parent 00084d769a
commit 0d2cb18745
4 changed files with 200 additions and 74 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ export interface NotificationBody {
id: number,
message: string,
status: string | null,
type: string | null
type: string
}
export async function fetchActiveNotifications() {
+42 -29
View File
@@ -51,7 +51,7 @@
height: 30px;
}
/* &.active {
/* &.active {
background: v.$color-warning;
} */
}
@@ -115,7 +115,7 @@
background: v.$white;
border-radius: 12px;
box-shadow: 10px 10px 20px 10px v.$shadow-1;
min-width: 320px;
min-width: 350px;
opacity: 0;
visibility: hidden;
transform: translateY(-10px);
@@ -148,14 +148,14 @@
}
&-count {
font-size: 12px;
color: v.$p-color;
font-size: 10px;
background: v.$p-color;
padding: 5px;
color: v.$white;
font-weight: 500;
cursor: pointer;
&:hover {
color: v.$p-color-hover;
}
border-radius: 5px;
margin-left: 5px;
user-select: none;
}
&-list {
@@ -166,9 +166,10 @@
&-item {
display: flex;
gap: 4px;
padding: 5px 10px 5px 10px;
padding: 10px 14px;
border-bottom: 1px solid v.$b-color-1;
transition: background-color 0.2s;
align-items: center;
&.loading {
opacity: 0.5;
@@ -177,7 +178,7 @@
&-title {
display: block;
font-size: 15px;
font-size: 13px;
font-weight: 700;
color: v.$text-p;
margin-bottom: 6px;
@@ -186,53 +187,65 @@
&-content {
width: 100%;
position: relative;
padding: 15px 5px;
/* display: flex;
align-items: center; */
padding: 5px;
}
&-item-header {
display: flex;
justify-content: space-between;
}
&-text {
font-size: 13px;
color: v.$text-s;
/* margin-bottom: 4px; */
font-weight: 500;
}
&-data,
&-mark-as-read {
&-data {
font-size: 10px;
color: v.$text-m;
display: flex;
justify-content: end;
position: absolute;
top: 0px;
right: 0px;
}
&-mark-as-read {
&-icon {
font-size: 12px;
bottom: 0px;
top: auto;
cursor: pointer;
height: max-content;
color: v.$p-color;
svg {
fill: v.$p-color;
&:hover {
fill: v.$p-color-hover;
}
}
&:hover {
color: v.$p-color-hover;
}
}
&-mark-all-as-read {
font-size: 10px;
color: v.$p-color;
text-align: end;
cursor: pointer;
&:hover {
color: v.$p-color-hover;
}
}
&-footer {
padding: 12px 20px;
padding: 8px 20px;
border-top: 1px solid v.$b-color-1;
text-align: center;
position: relative;
.notification-link {
color: v.$p-color;
font-size: 14px;
font-weight: 500;
font-size: 16px;
font-weight: 600;
text-decoration: none;
cursor: pointer;
+121 -44
View File
@@ -4,7 +4,7 @@ import { useState, useRef, useEffect } from 'react';
import { useClickOutside } from '@/app/hooks/useClickOutside';
import { useTranslations } from 'next-intl';
import Link from 'next/link';
import { IconNotification } 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 { NotificationBody, notificationsMarkAsRead } from '@/app/actions/notificationActions';
import { useQueryClient } from '@tanstack/react-query';
@@ -76,6 +76,51 @@ export default function NotificationsButton() {
}
}
const getNotificationIcon = (type: string) => {
switch (type) {
case 'SEARCH_RESULT':
case 'MONITORING_RESULT':
case 'SEARCH_OPERATION_FAILED':
return <IconPolicy />;
case 'FILE_MODERATION_EVENT':
case 'FILE_ADDED_TO_SYSTEM':
return <IconFiles />;
case 'PAYOUT_RESULT':
case 'PAYMENT_RESULT':
case 'REFERRAL_DEPOSIT':
return <IconAccountBalanceWallet />;
case 'REFERRAL_REGISTERED':
case 'REFERRAL_ACTIVATED':
return <IconCheckbook />;
case 'COMPLAINT_STATUS_CHANGED':
case 'CASE_STATUS_CHANGED':
return <IconGavel />;
case 'OPERATION_IMPOSSIBLE':
case 'START_FAILED_NOW':
case 'START_FAILED_NEXT':
case 'TOKEN_NOT_FOUND':
case 'USER_NOT_VERIFIED':
return <IconInfoMessage />;
case 'USER_VERIFIED':
return <IconPolicy />;
case 'INCOMING_MESSAGE':
return <IconInfoMessage />;
case 'TARIFF_EXPIRING':
return <IconInfoMessage />;
default:
return <IconInfoMessage />;
}
};
return (
<div className="notification-wrapper" ref={menuRef}>
<button
@@ -103,16 +148,35 @@ export default function NotificationsButton() {
<div className='notification-header'>
<h4>
{t('notifications')}
{notificationList?.notifications?.length !== 0 ? (
<span
className="notification-count"
>
{notificationList?.unreadCount ? notificationList?.unreadCount : ''}
</span>
) : null}
</h4>
<Link
href={'/pages/notifications'}
className="notification-count"
onClick={() => {
setIsOpen(false);
}}
>
{notificationList?.unreadCount ? notificationList?.unreadCount : t('no-new')} / {t('all')}
</Link>
{notificationList?.notifications?.length ? (
<button
className="notification-mark-all-as-read"
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>
) : null}
</div>
{notificationList?.notifications?.length !== 0 ? (
<>
@@ -125,28 +189,33 @@ export default function NotificationsButton() {
key={item.id}
className={`notification-item ${loadingIds.has(item.id) ? 'loading' : ''}`}
>
<div className="notification-content">
<div className="notification-data">
{item.createdAt ? formatDate(item.createdAt) : '#'}
</div>
<button
className="notification-icon"
onClick={() => {
markAsReadHandler([item.id]);
}}
disabled={loadingIds.has(item.id)}
>
{getNotificationIcon(item.type)}
</button>
{/* <div className="notification-title">
{t('tokens-added')}
</div> */}
<div className="notification-content">
<div
className="notification-item-header"
>
<div className="notification-title">
{norificationTranslate.has(item.type) ? norificationTranslate(item.type) : item.type}
</div>
<div className="notification-data">
{item.createdAt ? formatDate(item.createdAt) : '#'}
</div>
</div>
<div className="notification-text">
{norificationTranslate.has(item.message) ? norificationTranslate(item.message): item.message}
{norificationTranslate.has(item.message) ? norificationTranslate(item.message) : 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">
@@ -160,33 +229,41 @@ export default function NotificationsButton() {
</div>
<div className="notification-footer">
<button
<Link
href={'/pages/notifications'}
className="notification-link"
onClick={() => {
markAllAsReadHandler()
setIsOpen(false);
}}
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>
{t('all-notifications')}
</Link>
</div>
</>
) : (
<p
className="text-center mb-4 mt-4"
>
{t('no-new-notifications')}
</p>
<div>
<p
className="text-center mb-4 mt-4"
>
{t('no-new-notifications')}
</p>
<div className="notification-footer">
<Link
href={'/pages/notifications'}
className="notification-link"
onClick={() => {
setIsOpen(false);
}}
>
{t('all-notifications')}
</Link>
</div>
</div>
)}
</>
)}
</div>
</div>
</div >
)
}
+36
View File
@@ -206,4 +206,40 @@ export function IconCheck() {
return (
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" className="icon"><path fill="currentColor" d="m9.55 15.15l8.475-8.475q.3-.3.7-.3t.7.3t.3.713t-.3.712l-9.175 9.2q-.3.3-.7.3t-.7-.3L4.55 13q-.3-.3-.288-.712t.313-.713t.713-.3t.712.3z" /></svg>
)
}
export function IconPolicy() {
return (
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" ><path d="M480-80q-139-35-229.5-159.5T160-516v-244l320-120 320 120v244q0 85-29 163.5T688-214L560-342q-18 11-38.5 16.5T480-320q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 22-5.5 42.5T618-398l60 60q20-41 31-86t11-92v-189l-240-90-240 90v189q0 121 68 220t172 132q26-8 49.5-20.5T576-214l56 56q-33 27-71.5 47T480-80Zm56.5-343.5Q560-447 560-480t-23.5-56.5Q513-560 480-560t-56.5 23.5Q400-513 400-480t23.5 56.5Q447-400 480-400t56.5-23.5ZM488-477Z" /></svg>
)
}
export function IconFiles() {
return (
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" ><path d="M160-160q-33 0-56.5-23.5T80-240v-400q0-33 23.5-56.5T160-720h240l80-80h320q33 0 56.5 23.5T880-720v480q0 33-23.5 56.5T800-160H160Zm73-280h207v-207L233-440Zm-73-40 160-160H160v160Zm0 120v120h640v-480H520v280q0 33-23.5 56.5T440-360H160Zm280-160Z" /></svg>
)
}
export function IconAccountBalanceWallet() {
return (
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" ><path d="M200-200v-560 560Zm0 80q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v100h-80v-100H200v560h560v-100h80v100q0 33-23.5 56.5T760-120H200Zm320-160q-33 0-56.5-23.5T440-360v-240q0-33 23.5-56.5T520-680h280q33 0 56.5 23.5T880-600v240q0 33-23.5 56.5T800-280H520Zm280-80v-240H520v240h280Zm-117.5-77.5Q700-455 700-480t-17.5-42.5Q665-540 640-540t-42.5 17.5Q580-505 580-480t17.5 42.5Q615-420 640-420t42.5-17.5Z" /></svg>
)
}
export function IconCheckbook() {
return (
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" ><path d="M240-360h280l80-80H240v80Zm0-160h240v-80H240v80Zm-80-160v400h280l-80 80H80v-560h800v120h-80v-40H160Zm756 212q5 5 5 11t-5 11l-36 36-70-70 36-36q5-5 11-5t11 5l48 48ZM520-120v-70l266-266 70 70-266 266h-70ZM160-680v400-400Z" /></svg>
)
}
export function IconGavel() {
return (
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" ><path d="M160-120v-80h480v80H160Zm226-194L160-540l84-86 228 226-86 86Zm254-254L414-796l86-84 226 226-86 86Zm184 408L302-682l56-56 522 522-56 56Z" /></svg>
)
}
export function IconInfoMessage() {
return (
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" ><path d="M440-280h80v-240h-80v240Zm68.5-331.5Q520-623 520-640t-11.5-28.5Q497-680 480-680t-28.5 11.5Q440-657 440-640t11.5 28.5Q463-600 480-600t28.5-11.5ZM480-80q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z" /></svg>
)
}