diff --git a/rair-front/src/App.tsx b/rair-front/src/App.tsx index 74aff8ccb..b880186fc 100644 --- a/rair-front/src/App.tsx +++ b/rair-front/src/App.tsx @@ -105,7 +105,6 @@ function App() { const [tabIndexItems, setTabIndexItems] = useState(0); const [tokenNumber, setTokenNumber] = useState(undefined); const navigate = useNavigate(); - const [notificationCount, setNotificationCount] = useState(0); // Redux const { @@ -171,21 +170,6 @@ function App() { } }, [dispatch, logoutUser, blockchainSettings]); - const getNotificationsCount = useCallback(async () => { - if (isLoggedIn && currentUserAddress) { - const result = await rFetch(`/api/notifications?onlyUnread=true`); - if (result.success && result.totalCount >= 0) { - setNotificationCount(result.totalCount); - } - } else { - setNotificationCount(0); - } - }, [isLoggedIn, currentUserAddress]); - - useEffect(() => { - getNotificationsCount(); - }, [getNotificationsCount]); - // gtag useEffect(() => { @@ -306,8 +290,6 @@ function App() { showAlert={showAlert} setTabIndexItems={setTabIndexItems} isAboutPage={isAboutPage} - notificationCount={notificationCount} - getNotificationsCount={getNotificationsCount} /> ) )} diff --git a/rair-front/src/components/DemoMediaUpload/MediaItemChange/MediaItemChange.tsx b/rair-front/src/components/DemoMediaUpload/MediaItemChange/MediaItemChange.tsx index c08298745..cb172ca1d 100644 --- a/rair-front/src/components/DemoMediaUpload/MediaItemChange/MediaItemChange.tsx +++ b/rair-front/src/components/DemoMediaUpload/MediaItemChange/MediaItemChange.tsx @@ -1,3 +1,4 @@ +//@ts-nocheck import React, { useCallback, useState } from 'react'; import { faCheck, diff --git a/rair-front/src/components/DemoMediaUpload/PopUpChangeVideo/PopUpChangeVideo.tsx b/rair-front/src/components/DemoMediaUpload/PopUpChangeVideo/PopUpChangeVideo.tsx index 28567595d..32d26655b 100644 --- a/rair-front/src/components/DemoMediaUpload/PopUpChangeVideo/PopUpChangeVideo.tsx +++ b/rair-front/src/components/DemoMediaUpload/PopUpChangeVideo/PopUpChangeVideo.tsx @@ -1,3 +1,4 @@ +//@ts-nocheck import React, { useCallback, useEffect, useState } from 'react'; import Modal from 'react-modal'; @@ -22,9 +23,8 @@ const PopUpChangeVideo: React.FC = ({ mediaList, index }) => { - const { primaryColor, textColor, primaryButtonColor } = useAppSelector( - (store) => store.colors - ); + const { primaryColor, textColor, primaryButtonColor, isDarkMode } = + useAppSelector((store) => store.colors); const { categories } = useAppSelector((store) => store.settings); const rSwal = useSwal(); @@ -122,7 +122,7 @@ const PopUpChangeVideo: React.FC = ({ color: textColor }, labelCSS: { - color: `${primaryColor === 'rhyno' ? 'rgb(41, 41, 41)' : '#fff'}`, + color: textColor, marginTop: 5, marginBottom: 5 } @@ -133,7 +133,9 @@ const PopUpChangeVideo: React.FC = ({ zIndex: '1' }, content: { - background: primaryColor === 'rhyno' ? '#F2F2F2' : '#383637', + background: isDarkMode + ? `color-mix(in srgb, ${primaryColor}, #2D2D2D)` + : 'var(--rhyno)', top: '50%', left: '50%', right: 'auto', @@ -191,7 +193,7 @@ const PopUpChangeVideo: React.FC = ({ label="Title" customClass="form-control input-select-custom-style" placeholder="Select a description" - // {...selectCommonInfoNFT} + {...selectCommonInfoNFT} /> = ({ label="Description" customClass="form-control input-select-custom-style" placeholder="Select a description" - // {...selectCommonInfoNFT} + {...selectCommonInfoNFT} /> = ({ className="medialist-box" key={index} style={{ - backgroundColor: `color-mix(in srgb, ${primaryColor}, #888888)`, + backgroundColor: isDarkMode ? `color-mix(in srgb, ${primaryColor}, #888888)` : 'var(--rhyno)', color: textColor, borderRadius: '15px', marginTop: '20px' diff --git a/rair-front/src/components/Header/MainHeader.tsx b/rair-front/src/components/Header/MainHeader.tsx index c11d3cb37..36bf1010f 100644 --- a/rair-front/src/components/Header/MainHeader.tsx +++ b/rair-front/src/components/Header/MainHeader.tsx @@ -16,7 +16,7 @@ import useConnectUser from '../../hooks/useConnectUser'; import { useAppDispatch, useAppSelector } from '../../hooks/useReduxHooks'; import { dataStatuses } from '../../redux/commonTypes'; import { clearResults, startSearch } from '../../redux/searchbarSlice'; -import { rFetch } from '../../utils/rFetch'; +import { fetchNotifications } from '../../redux/notificationsSlice'; import InputField from '../common/InputField'; import { TooltipBox } from '../common/Tooltip/TooltipBox'; import MainLogo from '../GroupLogos/MainLogo'; @@ -63,11 +63,11 @@ const MainHeader: FC = ({ (store) => store.user ); + const { totalCount: notificationCount, notifications } = useAppSelector(store => store.notifications); + const { currentUserAddress } = useAppSelector((store) => store.web3); const hotdropsVar = import.meta.env.VITE_TESTNET; - const [realDataNotification, setRealDataNotification] = useState([]); - const [notificationCount, setNotificationCount] = useState(0); const [textSearch, setTextSearch] = useState(''); const [adminPanel, setAdminPanel] = useState(false); @@ -120,51 +120,12 @@ const MainHeader: FC = ({ setTextSearch(''); }; - const getNotifications = useCallback( - async (pageNum?: number) => { - if (currentUserAddress && isLoggedIn) { - const result = await rFetch( - `/api/notifications${pageNum ? `?pageNum=${Number(pageNum)}` : ''}` - ); - - if (result.success) { - const sortedNotifications = result.notifications.sort((a, b) => { - if (!a.read && b.read) return -1; - if (a.read && !b.read) return 1; - - const dateA = new Date(a.createdAt).getTime(); - const dateB = new Date(b.createdAt).getTime(); - - return dateB - dateA; - }); - setRealDataNotification(sortedNotifications); - } - } else { - setRealDataNotification([]); - } - }, - [currentUserAddress, isLoggedIn] - ); - - const getNotificationsCount = useCallback(async () => { - if (currentUserAddress && isLoggedIn) { - const result = await rFetch(`/api/notifications?onlyUnread=true`); - if (result.success && result.totalCount >= 0) { - setNotificationCount(result.totalCount); - } - } else { - setNotificationCount(0); + useEffect(() => { + if(currentUserAddress && isLoggedIn) { + dispatch(fetchNotifications(0)); } }, [currentUserAddress, isLoggedIn]); - useEffect(() => { - getNotificationsCount(); - }, [getNotificationsCount]); - - useEffect(() => { - getNotifications(0); - }, [getNotifications]); - const Highlight = (props) => { const { filter, str } = props; if (!filter) return str; @@ -203,6 +164,10 @@ const MainHeader: FC = ({ } }, [dispatch, textSearch]); + useEffect(() => { + dispatch(fetchNotifications()); + }, []) + return ( = ({ {currentUserAddress && ( )} diff --git a/rair-front/src/components/MockUpPage/FilteringBlock/FilteringBlockItems/FilteringBlockItems.tsx b/rair-front/src/components/MockUpPage/FilteringBlock/FilteringBlockItems/FilteringBlockItems.tsx index 14cb8fb8f..a5e8bd80f 100644 --- a/rair-front/src/components/MockUpPage/FilteringBlock/FilteringBlockItems/FilteringBlockItems.tsx +++ b/rair-front/src/components/MockUpPage/FilteringBlock/FilteringBlockItems/FilteringBlockItems.tsx @@ -82,15 +82,14 @@ export const SelectSortPopUp = styled.div.withConfig({ })` background-color: ${({ isDarkMode, primaryColor }) => isDarkMode - ? 'var(--rhyno)' - : `color-mix(in srgb, ${primaryColor}, #2d2d2d)`}; + ? `color-mix(in srgb, ${primaryColor}, #2d2d2d)` : 'var(--rhyno)'}; color: ${({ textColor }) => textColor}; &:after { content: ''; width: 20px; height: 20px; background-color: ${({ primaryColor, isDarkMode }) => - isDarkMode + !isDarkMode ? 'var(--rhyno)' : `color-mix(in srgb, ${primaryColor}, #2d2d2d)`}; position: absolute; diff --git a/rair-front/src/components/MockUpPage/PaginationBox/PaginationBox.tsx b/rair-front/src/components/MockUpPage/PaginationBox/PaginationBox.tsx index 44b992283..c383d868f 100644 --- a/rair-front/src/components/MockUpPage/PaginationBox/PaginationBox.tsx +++ b/rair-front/src/components/MockUpPage/PaginationBox/PaginationBox.tsx @@ -7,20 +7,34 @@ import { IPaginationBox } from '../mockupPage.types'; const PaginationBox: React.FC = ({ changePage, + currentPage, totalPageForPagination, whatPage, itemsPerPageNotifications }) => { - const { itemsPerPage, currentPage } = useAppSelector((store) => store.tokens); - + const { itemsPerPage } = useAppSelector((store) => store.tokens); const { isDarkMode, primaryButtonColor } = useAppSelector( (store) => store.colors ); const [page, setPage] = useState(currentPage); - const [pagesArray, setPagesArray] = useState>([]); + const [totalPage, setTotalPages] = useState(); + const [totalPageVideo, setTotalPagesVideo] = useState(); - // const hotdropsVar = import.meta.env.VITE_TESTNET; + const pagesArray: number[] = []; + if (whatPage && whatPage === 'nft' && totalPage) { + for (let i = 0; i < totalPage; i++) { + pagesArray.push(i + 1); + } + } else if (whatPage && whatPage === 'video' && totalPageVideo) { + for (let i = 0; i < totalPageVideo; i++) { + pagesArray.push(i + 1); + } + } else if (whatPage && whatPage === 'notifications' && totalPage) { + for (let i = 0; i < totalPage; i++) { + pagesArray.push(i + 1); + } + } const getPagesCount = (totalCount: number, itemsPerPage: number) => { return Math.ceil(totalCount / itemsPerPage); @@ -34,30 +48,21 @@ const PaginationBox: React.FC = ({ }; useEffect(() => { - if (!totalPageForPagination) { - return; - } - let totalPages = 0; - switch (whatPage) { - case 'nft': - totalPages = getPagesCount(totalPageForPagination, itemsPerPage); - break; - case 'video': - totalPages = getPagesCount(totalPageForPagination, itemsPerPage); - break; - case 'notifications': - totalPages = getPagesCount( - totalPageForPagination, - itemsPerPageNotifications || 0 - ); - break; - } - const pageArray: Array = []; - for (let i = 0; i < totalPages; i++) { - pageArray.push(i + 1); + if (totalPageForPagination && whatPage === 'nft') { + setTotalPages(getPagesCount(totalPageForPagination, itemsPerPage)); + } else if (totalPageForPagination && whatPage === 'video') { + setTotalPagesVideo(getPagesCount(totalPageForPagination, itemsPerPage)); + } else if ( + totalPageForPagination && + whatPage === 'notifications' && + itemsPerPageNotifications + ) { + setTotalPages( + getPagesCount(totalPageForPagination, itemsPerPageNotifications) + ); } - setPagesArray(pageArray); }, [ + setTotalPages, totalPageForPagination, itemsPerPage, whatPage, @@ -79,8 +84,9 @@ const PaginationBox: React.FC = ({ primaryButtonColor={primaryButtonColor} count={pagesArray.length} page={page} - showFirstButton={false} onChange={handlePage} + // hideNextButton={true} + // hidePrevButton={true} shape="rounded" /> )} diff --git a/rair-front/src/components/MockUpPage/PaginationBox/PaginationBoxStyled.tsx b/rair-front/src/components/MockUpPage/PaginationBox/PaginationBoxStyled.tsx index b36e15a1a..042c55b34 100644 --- a/rair-front/src/components/MockUpPage/PaginationBox/PaginationBoxStyled.tsx +++ b/rair-front/src/components/MockUpPage/PaginationBox/PaginationBoxStyled.tsx @@ -6,9 +6,7 @@ interface IPaginationBoxStyled { isDarkMode?: boolean; } -export const PaginationBoxStyled = styled(Pagination).withConfig({ - shouldForwardProp: () => true -})` +export const PaginationBoxStyled = styled(Pagination)` ul { li { button { @@ -20,12 +18,7 @@ export const PaginationBoxStyled = styled(Pagination).withConfig({ ${({ isDarkMode }) => (!isDarkMode ? '#2d2d2d' : '#fff')}; &.Mui-selected { - background: ${({ primaryButtonColor }) => - `${ - import.meta.env.VITE_TESTNET - ? 'var(--hot-drops)' - : primaryButtonColor - }`}; + background: ${({ primaryButtonColor }) => `${primaryButtonColor}`}; color: #fff; border: none; -webkit-box-shadow: 0px 0px 7px 0.4px #b278a7; @@ -33,12 +26,7 @@ export const PaginationBoxStyled = styled(Pagination).withConfig({ box-shadow: 0px 0px 7px 0.4px #b278a7; } &:hover { - background: ${({ primaryButtonColor }) => - `${ - import.meta.env.VITE_TESTNET === 'true' - ? 'var(--hot-drops)' - : primaryButtonColor - }`}; + background: ${({ primaryButtonColor }) => `${primaryButtonColor}`}; color: #fff; } } diff --git a/rair-front/src/components/Navigation/Menu.tsx b/rair-front/src/components/Navigation/Menu.tsx index d3dee6cb4..75a0f9e15 100644 --- a/rair-front/src/components/Navigation/Menu.tsx +++ b/rair-front/src/components/Navigation/Menu.tsx @@ -8,7 +8,7 @@ import { formatEther, isAddress, ZeroAddress } from 'ethers'; import { TUserResponse } from '../../axios.responseTypes'; import useConnectUser from '../../hooks/useConnectUser'; import useContracts from '../../hooks/useContracts'; -import { useAppSelector } from '../../hooks/useReduxHooks'; +import { useAppDispatch, useAppSelector } from '../../hooks/useReduxHooks'; import useServerSettings from '../../hooks/useServerSettings'; import { BellIcon, @@ -39,6 +39,7 @@ import { } from './NavigationItems/NavigationItems'; import './Menu.css'; +import { fetchNotifications } from '../../redux/notificationsSlice'; interface IMenuNavigation { renderBtnConnect: boolean; @@ -48,8 +49,6 @@ interface IMenuNavigation { isSplashPage: boolean; isAboutPage: boolean; realChainId: string | undefined; - notificationCount?: number; - getNotificationsCount?: any; } const MenuNavigation: React.FC = ({ @@ -57,9 +56,7 @@ const MenuNavigation: React.FC = ({ setTabIndexItems, isSplashPage, isAboutPage, - realChainId, - notificationCount, - getNotificationsCount + realChainId }) => { const [click, setClick] = useState(false); const [userData, setUserData] = useState(null); @@ -70,22 +67,24 @@ const MenuNavigation: React.FC = ({ const [userBalance, setUserBalance] = useState(''); const [activeSearch, setActiveSearch] = useState(false); const [isLoadingBalance, setIsLoadingBalance] = useState(false); + const dispatch = useAppDispatch(); const [messageAlert, setMessageAlert] = useState(null); const { isLoggedIn, loginStatus, ageVerified } = useAppSelector( (store) => store.user ); - const [realDataNotification, setRealDataNotification] = useState([]); const { mainTokenInstance } = useContracts(); const { currentUserAddress, connectedChain } = useAppSelector( (state) => state.web3 ); + const { totalUnreadCount } = useAppSelector((store) => store.notifications); const { primaryButtonColor, textColor, iconColor, secondaryColor, - primaryColor + primaryColor, + isDarkMode } = useAppSelector((store) => store.colors); const hotdropsVar = import.meta.env.VITE_TESTNET; @@ -98,25 +97,6 @@ const MenuNavigation: React.FC = ({ setActiveSearch((prev) => !prev); }; - const getNotifications = useCallback(async () => { - if (currentUserAddress && isLoggedIn) { - const result = await rFetch(`/api/notifications`); - if (result.success) { - setRealDataNotification(result.notifications); - } - } else { - setRealDataNotification([]); - } - }, [currentUserAddress, isLoggedIn]); - - useEffect(() => { - getNotificationsCount(); - }, [click]); - - useEffect(() => { - getNotifications(); - }, []); - const toggleMenu = (otherPage?: string | undefined) => { if (otherPage === 'nav') { setClick(true); @@ -201,6 +181,12 @@ const MenuNavigation: React.FC = ({ getBalance(); }, [getBalance]); + useEffect(() => { + if (currentUserAddress && isLoggedIn) { + dispatch(fetchNotifications()); + } + }, [currentUserAddress, isLoggedIn]); + return ( = ({ height="40px" marginLeft={'17px'}> - {notificationCount && notificationCount > 0 ? ( + {totalUnreadCount > 0 ? (
= ({ fontWeight: 'bold', color: '#fff' }}> - {notificationCount > 9 ? '9+' : notificationCount} + {totalUnreadCount > 9 ? '9+' : totalUnreadCount}
) : ( '' @@ -366,10 +352,9 @@ const MenuNavigation: React.FC = ({ }} className="mobileAikonWidget" style={{ - backgroundColor: - primaryColor === 'rhyno' - ? 'var(--rhyno-20)' - : 'var(--charcoal-80)' + backgroundColor: !isDarkMode + ? 'var(--rhyno-20)' + : 'var(--charcoal-80)' }}>
= ({ const { nickName, isLoggedIn, avatar } = useAppSelector( (state) => state.user ); - const [notificationCount, setNotificationCount] = useState(0); - const getNotificationsCount = useCallback(async () => { - if (currentUserAddress && isLoggedIn) { - const result = await rFetch(`/api/notifications?onlyUnread=true`); - if (result.success && result.totalCount >= 0) { - setNotificationCount(result.totalCount); - } - } else { - setNotificationCount(0); - } - }, [currentUserAddress, isLoggedIn]); - - useEffect(() => { - getNotificationsCount(); - }, [getNotificationsCount]); + const {totalUnreadCount} = useAppSelector(store => store.notifications); return (
@@ -88,7 +74,7 @@ const MobileChoiseNav: React.FC = ({ height="40px" marginLeft={'17px'}> - {notificationCount > 0 && ( + {totalUnreadCount > 0 && (
= ({ color: '#fff' }} className="red-circle-notifications"> - {notificationCount > 9 ? '9+' : notificationCount} + {totalUnreadCount > 9 ? '9+' : totalUnreadCount}
)} diff --git a/rair-front/src/components/Navigation/MenuComponents/MobileListMenu.tsx b/rair-front/src/components/Navigation/MenuComponents/MobileListMenu.tsx index 2a9ccd8da..e14a116cf 100644 --- a/rair-front/src/components/Navigation/MenuComponents/MobileListMenu.tsx +++ b/rair-front/src/components/Navigation/MenuComponents/MobileListMenu.tsx @@ -39,7 +39,7 @@ const MobileListMenu: React.FC = ({ const { searchResults } = useAppSelector((store) => store.searchbar); const hotdropsVar = import.meta.env.VITE_TESTNET; - const { iconColor, primaryColor, secondaryColor } = useAppSelector( + const { iconColor, primaryColor, secondaryColor, isDarkMode } = useAppSelector( (store) => store.colors ); @@ -142,7 +142,9 @@ const MobileListMenu: React.FC = ({ secondaryColor={secondaryColor} hotdrops={hotdropsVar} primaryColor={primaryColor} - click={click}> + click={click} + isDarkMode={isDarkMode} + >
{activeSearch && ( <> diff --git a/rair-front/src/components/Navigation/MenuComponents/MobileNavigationList.tsx b/rair-front/src/components/Navigation/MenuComponents/MobileNavigationList.tsx index 8c7fd3977..49ff058b7 100644 --- a/rair-front/src/components/Navigation/MenuComponents/MobileNavigationList.tsx +++ b/rair-front/src/components/Navigation/MenuComponents/MobileNavigationList.tsx @@ -6,7 +6,7 @@ import { formatEther } from 'ethers'; import useConnectUser from '../../../hooks/useConnectUser'; import useContracts from '../../../hooks/useContracts'; -import { useAppSelector } from '../../../hooks/useReduxHooks'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; import useServerSettings from '../../../hooks/useServerSettings'; import useSwal from '../../../hooks/useSwal'; import useWeb3Tx from '../../../hooks/useWeb3Tx'; @@ -18,6 +18,7 @@ import { NavFooter, NavFooterBox } from '../../Footer/FooterItems/FooterItems'; import PaginationBox from '../../MockUpPage/PaginationBox/PaginationBox'; import NotificationBox from '../../UserProfileSettings/PopUpNotification/NotificationBox/NotificationBox'; import { BackBtnMobileNav } from '../NavigationItems/NavigationItems'; +import { fetchNotifications } from '../../../redux/notificationsSlice'; interface IMobileNavigationList { messageAlert: string | null; @@ -34,6 +35,7 @@ const MobileNavigationList: React.FC = ({ toggleMenu, click }) => { + const dispatch = useAppDispatch(); const [userBalance, setUserBalance] = useState(''); const [userRairBalance, setUserRairBalance] = useState(BigInt(0)); const { primaryColor, primaryButtonColor, textColor, isDarkMode } = @@ -87,58 +89,18 @@ const MobileNavigationList: React.FC = ({ ]); const [copyEth, setCopyEth] = useState(false); - const [notificationArray, setNotificationArray] = useState(); - const [notificationCount, setNotificationCount] = useState(0); const [flagLoading, setFlagLoading] = useState(false); + const {notifications, totalCount} = useAppSelector(store => store.notifications); const [currentPageNotification, setCurrentPageNotification] = useState(1); const reactSwal = useSwal(); const { logoutUser } = useConnectUser(); - const getNotifications = useCallback( - async (pageNum?: number) => { - if (isLoggedIn && messageAlert && currentUserAddress) { - setFlagLoading(true); - const result = await rFetch( - `/api/notifications${pageNum ? `?pageNum=${Number(pageNum)}` : ''}` - ); - if (result.success) { - const sortedNotifications = result.notifications.sort((a, b) => { - if (!a.read && b.read) return -1; - if (a.read && !b.read) return 1; - - const dateA = new Date(a.createdAt).getTime(); - const dateB = new Date(b.createdAt).getTime(); - - return dateB - dateA; - }); - setNotificationArray(sortedNotifications); - } - } else { - setNotificationArray([]); - } - }, - [messageAlert, currentUserAddress, isLoggedIn] - ); - - const getNotificationsCount = useCallback(async () => { - if (isLoggedIn && currentUserAddress) { - setFlagLoading(true); - const result = await rFetch(`/api/notifications`); - if (result.success && result.totalCount >= 0) { - setNotificationCount(result.totalCount); - } - setFlagLoading(false); - } else { - setNotificationCount(0); - } - }, [currentUserAddress, isLoggedIn]); - const changePageForVideo = (currentPage: number) => { setCurrentPageNotification(currentPage); const currentPageNumber = currentPage === 0 ? currentPage : currentPage - 1; - getNotifications(Number(currentPageNumber)); + dispatch(fetchNotifications(Number(currentPageNumber))); }; const deleteAllNotificaiton = useCallback(async () => { @@ -150,8 +112,7 @@ const MobileNavigationList: React.FC = ({ }); if (result.success) { - getNotifications(); - getNotificationsCount(); + dispatch(fetchNotifications()); reactSwal.fire({ title: 'Success', icon: 'success' @@ -160,15 +121,13 @@ const MobileNavigationList: React.FC = ({ } setFlagLoading(false); } - }, [currentUserAddress, getNotifications, getNotificationsCount, reactSwal]); + }, [currentUserAddress, dispatch, reactSwal]); useEffect(() => { - getNotificationsCount(); - }, [getNotificationsCount]); - - useEffect(() => { - getNotifications(0); - }, [getNotifications]); + if(currentUserAddress && isLoggedIn) { + dispatch(fetchNotifications(0)); + } + }, [currentUserAddress, isLoggedIn]); useEffect(() => { getBalance(); @@ -225,15 +184,13 @@ const MobileNavigationList: React.FC = ({
{flagLoading ? ( - ) : notificationArray && notificationArray.length > 0 ? ( - notificationArray.map((el) => { + ) : notifications && notifications.length > 0 ? ( + notifications.map((el) => { return ( ); }) @@ -246,9 +203,9 @@ const MobileNavigationList: React.FC = ({
)}
- {notificationCount > 0 && ( + {totalCount > 0 && ( emotionIsPropValid(prop) })` - background: ${({ secondaryColor }) => - `color-mix(in srgb, ${secondaryColor}, #888888)`}; +background: ${({ isDarkMode, secondaryColor }) => +!isDarkMode ? '#fff' : `color-mix(in srgb, ${secondaryColor}, #888888)`}; + overflow: ${(props) => props.click && 'hidden'}; border-bottom-right-radius: 16px; border-bottom-left-radius: 16px; diff --git a/rair-front/src/components/UserProfileSettings/PopUpNotification/NotificationBox/NotificationBox.tsx b/rair-front/src/components/UserProfileSettings/PopUpNotification/NotificationBox/NotificationBox.tsx index 0c8e9fd34..d2aeaf542 100644 --- a/rair-front/src/components/UserProfileSettings/PopUpNotification/NotificationBox/NotificationBox.tsx +++ b/rair-front/src/components/UserProfileSettings/PopUpNotification/NotificationBox/NotificationBox.tsx @@ -1,9 +1,11 @@ import { useCallback } from 'react'; import { Provider, useStore } from 'react-redux'; -import { useAppSelector } from '../../../../hooks/useReduxHooks'; +import { useAppDispatch, useAppSelector } from '../../../../hooks/useReduxHooks'; import useSwal from '../../../../hooks/useSwal'; +import useWindowDimensions from '../../../../hooks/useWindowDimensions'; import { CloseIconMobile } from '../../../../images'; +import { fetchNotifications } from '../../../../redux/notificationsSlice'; import { SocialMenuMobile } from '../../../../styled-components/SocialLinkIcons/SocialLinkIcons'; import { rFetch } from '../../../../utils/rFetch'; import NotificationPage from '../../NotificationPage/NotificationPage'; @@ -13,14 +15,16 @@ import './NotificationBox.css'; const NotificationBox = ({ title, el, - getNotifications, - getNotificationsCount }) => { - const { headerLogoMobile, primaryColor } = useAppSelector( + const { headerLogoMobile, primaryColor, isDarkMode } = useAppSelector( (store) => store.colors ); const { currentUserAddress } = useAppSelector((store) => store.web3); + const { width } = useWindowDimensions(); + + const dispatch = useAppDispatch(); + const reactSwal = useSwal(); const store = useStore(); @@ -37,30 +41,30 @@ const NotificationBox = ({ }); if (result.success) { - getNotifications(); - getNotificationsCount(); + dispatch(fetchNotifications(0)); } } - }, [currentUserAddress, el._id, getNotifications, getNotificationsCount]); + }, [currentUserAddress, el._id]); const readNotification = useCallback(async () => { if (currentUserAddress) { - const result = await rFetch(`/api/notifications`, { - method: 'PUT', - body: JSON.stringify({ - ids: [el._id] - }), - headers: { - 'Content-Type': 'application/json' - } - }); + if(!el.read) { + const result = await rFetch(`/api/notifications`, { + method: 'PUT', + body: JSON.stringify({ + ids: [el._id] + }), + headers: { + 'Content-Type': 'application/json' + } + }); - if (result.success) { - getNotifications(); - getNotificationsCount(); + if (result.success) { + dispatch(fetchNotifications(0)); + } } } - }, [currentUserAddress, el._id, getNotifications, getNotificationsCount]); + }, [currentUserAddress, el._id]); const showMoreDetails = () => { reactSwal.fire({ @@ -75,15 +79,14 @@ const NotificationBox = ({ }, showConfirmButton: false, showCloseButton: true - // cancelButtonText: - // '', - // cancelButtonAriaLabel: 'Thumbs down' }); }; return (
-
+
{!el.read &&
}
@@ -93,7 +96,6 @@ const NotificationBox = ({
{ - // readNotification(); showMoreDetails(); readNotification(); }} diff --git a/rair-front/src/components/UserProfileSettings/PopUpNotification/PopUpNotification.tsx b/rair-front/src/components/UserProfileSettings/PopUpNotification/PopUpNotification.tsx index cf5e4ab81..0d76fd8f1 100644 --- a/rair-front/src/components/UserProfileSettings/PopUpNotification/PopUpNotification.tsx +++ b/rair-front/src/components/UserProfileSettings/PopUpNotification/PopUpNotification.tsx @@ -1,102 +1,85 @@ import { useCallback, useEffect, useState } from 'react'; import { Popup } from 'reactjs-popup'; -import { useAppSelector } from '../../../hooks/useReduxHooks'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; import useSwal from '../../../hooks/useSwal'; import { BellIcon } from '../../../images'; +import { fetchNotifications } from '../../../redux/notificationsSlice'; import { SocialBox } from '../../../styled-components/SocialLinkIcons/SocialLinkIcons'; import { rFetch } from '../../../utils/rFetch'; import PaginationBox from '../../MockUpPage/PaginationBox/PaginationBox'; import NotificationBox from './NotificationBox/NotificationBox'; -const PopUpNotification = ({ - getNotifications, - realDataNotification, - notificationCount, - getNotificationsCount -}) => - // props was - isNotification - { - const [openModal, setOpenModal] = useState(false); - const reactSwal = useSwal(); - const { currentUserAddress } = useAppSelector((state) => state.web3); - const [totalPageForPagination, setTotalPageForPagination] = useState(0); - const [currentPageForNotification, setCurrentPageNotification] = - useState(1); - const { primaryColor, primaryButtonColor, textColor } = useAppSelector( - (store) => store.colors - ); - const { email, isLoggedIn } = useAppSelector((store) => store.user); +const PopUpNotification = ({ realDataNotification, notificationCount }) => { + const [openModal, setOpenModal] = useState(false); + const dispatch = useAppDispatch(); + const reactSwal = useSwal(); + const { currentUserAddress } = useAppSelector((state) => state.web3); + const { isLoggedIn } = useAppSelector((store) => store.user); + const { totalUnreadCount } = useAppSelector((store) => store.notifications); + const [totalPageForPagination, setTotalPageForPagination] = useState(0); + const [currentPageForNotification, setCurrentPageNotification] = + useState(1); + const { primaryColor, primaryButtonColor, textColor } = useAppSelector( + (store) => store.colors + ); + const { email } = useAppSelector((store) => store.user); - const changePageForVideo = (currentPage: number) => { - setCurrentPageNotification(currentPage); - const currentPageNumber = - currentPage === 0 ? currentPage : currentPage - 1; - getNotifications(Number(currentPageNumber)); - }; + const changePageForNotification = (currentPage: number) => { + setCurrentPageNotification(currentPage); + const currentPageNumber = currentPage === 0 ? currentPage : currentPage - 1; + dispatch(fetchNotifications(Number(currentPageNumber))); + }; - const getNotificationsCountPagitation = useCallback(async () => { - if (currentUserAddress && isLoggedIn) { - const result = await rFetch(`/api/notifications`); - if (result.success && result.totalCount > 0) { - setTotalPageForPagination(result.totalCount); - } - } else { - setTotalPageForPagination(0); - } - }, [currentUserAddress, isLoggedIn]); + const getNotificationsCountPagitation = useCallback(async () => { + if (currentUserAddress && isLoggedIn) { + setTotalPageForPagination(notificationCount); + } else { + setTotalPageForPagination(0); + } + }, [currentUserAddress, isLoggedIn, notificationCount]); - const deleteAllNotificaiton = useCallback(async () => { - if (currentUserAddress) { - const result = await rFetch(`/api/notifications`, { - method: 'DELETE', - body: JSON.stringify([]) - }); + const deleteAllNotificaiton = useCallback(async () => { + if (currentUserAddress) { + const result = await rFetch(`/api/notifications`, { + method: 'DELETE', + body: JSON.stringify([]) + }); - if (result.success) { - getNotifications(); - getNotificationsCount(); - reactSwal.fire({ - title: 'Success', - icon: 'success' - }); - } + if (result.success) { + dispatch(fetchNotifications(0)); + reactSwal.fire({ + title: 'Success', + icon: 'success' + }); } - }, [ - currentUserAddress, - getNotifications, - getNotificationsCount, - reactSwal - ]); + } + }, [currentUserAddress, reactSwal]); - useEffect(() => { - if (openModal) { - getNotifications(0); - getNotificationsCount(); - } - }, [getNotifications, getNotificationsCount, openModal]); + useEffect(() => { + if (openModal) { + dispatch(fetchNotifications(0)); + } + }, [dispatch, openModal]); - useEffect(() => { - getNotificationsCount(); - }, [getNotificationsCount]); + useEffect(() => { + getNotificationsCountPagitation(); + }, [getNotificationsCountPagitation]); - useEffect(() => { - getNotificationsCountPagitation(); - }, [getNotificationsCountPagitation]); + const onCloseNext = useCallback(() => { + if (!openModal) { + setOpenModal(false); + } + }, [openModal]); - const onCloseNext = useCallback(() => { - if (!openModal) { - setOpenModal(false); - } - }, [openModal]); + useEffect(() => { + onCloseNext(); + }, [onCloseNext]); - useEffect(() => { - onCloseNext(); - }, [onCloseNext]); - - return ( - <> + return ( + <> + {currentUserAddress && isLoggedIn && ( setOpenModal((prev) => !prev)} className="social-bell-icon notifications" @@ -104,7 +87,7 @@ const PopUpNotification = ({ notification={true}> {email && } - {notificationCount > 0 && ( + {totalUnreadCount > 0 && (
- {notificationCount > 9 ? '9+' : notificationCount} + {totalUnreadCount > 9 ? '9+' : totalUnreadCount}
)}
- { - setOpenModal(false); - }}> - {openModal && ( + )} + { + setOpenModal(false); + }}> + {openModal && ( +
+
+
Notifications
+ +
-
-
Notifications
- -
-
- {realDataNotification && realDataNotification.length > 0 ? ( - realDataNotification.map((el) => { - return ( - - ); - }) - ) : ( -
- {"You don't have any notifications now"} -
- )} -
- {notificationCount > 0 && totalPageForPagination && ( - - )} + {"You don't have any notifications now"}
+ )} +
+ {notificationCount > 0 && totalPageForPagination && ( + + )}
- )} - - - ); - }; +
+ )} + + + ); +}; export default PopUpNotification; diff --git a/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyNftTab/ResaleModal/ResaleModal.tsx b/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyNftTab/ResaleModal/ResaleModal.tsx index 570bdd3e6..1c4a8c393 100644 --- a/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyNftTab/ResaleModal/ResaleModal.tsx +++ b/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyNftTab/ResaleModal/ResaleModal.tsx @@ -305,10 +305,18 @@ const ResaleModal: React.FC = ({
{item && item.metadata && item.metadata.name}
-
+
{chainData && ( <> -
{chainData.symbol}
+
{chainData?.viem?.nativeCurrency?.symbol}
blockchain )} diff --git a/rair-front/src/images/index.tsx b/rair-front/src/images/index.tsx index 6135fc8ef..ced95ee51 100644 --- a/rair-front/src/images/index.tsx +++ b/rair-front/src/images/index.tsx @@ -321,7 +321,6 @@ export const MenuIcon = ({ primaryColor }) => { }; export const CloseIconMobile = ({ primaryColor }) => { - console.info(primaryColor, 'primaryColor') return ( ; + totalCount: number; + totalUnreadCount: number; + notificationsStatus: dataStatuses; +} + +interface NotificaitonItem { + createdAt: string; + data: Array; + read: boolean; + tokenData: Array; + type: string; + updatedAt: string; + user: string; + _id: string; +} + +const initialState: NotificationState = { + notifications: [], + totalCount: 0, + totalUnreadCount: 0, + notificationsStatus: dataStatuses.Uninitialized +}; + +export const fetchNotifications = createAsyncThunk( + 'notifications/fetchData', + async (pageNum?: number) => { + const responseData = await axios.get( + `/api/notifications${pageNum ? `?pageNum=${Number(pageNum)}` : ''}` + ); + + const responseUnreadData = await axios.get( + `/api/notifications?onlyUnread=true` + ); + + return { + data: responseData, + unreadData: responseUnreadData + }; + } +); + +export const notificationsSlice = createSlice({ + name: 'notifications', + initialState, + reducers: { + clearResults: (state) => { + state.notificationsStatus = {}; + } + }, + extraReducers: (builder) => { + builder + .addCase(fetchNotifications.pending, (state) => { + state.notificationsStatus = dataStatuses.Loading; + }) + .addCase(fetchNotifications.fulfilled, (state, action: PayloadAction) => { + state.notificationsStatus = dataStatuses.Complete; + const sortedNotifications = action.payload.data.data.notifications.sort( + (a, b) => { + if (!a.read && b.read) return -1; + if (a.read && !b.read) return 1; + + const dateA = new Date(a.createdAt).getTime(); + const dateB = new Date(b.createdAt).getTime(); + + return dateB - dateA; + } + ); + + state.notifications = sortedNotifications; + state.totalCount = action.payload.data.data.totalCount; + state.totalUnreadCount = action.payload.unreadData.data.totalCount; + }) + .addCase(fetchNotifications.rejected, (state) => { + state.notificationsStatus = dataStatuses.Failed; + }); + } +}); + +export const { clearResults } = notificationsSlice.actions; +export default notificationsSlice.reducer; diff --git a/rair-front/src/redux/store.ts b/rair-front/src/redux/store.ts index b42ca091b..02ffda718 100644 --- a/rair-front/src/redux/store.ts +++ b/rair-front/src/redux/store.ts @@ -2,6 +2,7 @@ import type { Action, ThunkAction } from '@reduxjs/toolkit'; import { configureStore } from '@reduxjs/toolkit'; import colorSlice from './colorSlice'; +import notificationsSlice from './notificationsSlice'; import searchbarSlice from './searchbarSlice'; import seoSlice from './seoSlice'; import settingsSlice from './settingsSlice'; @@ -19,7 +20,8 @@ export const store = configureStore({ seo: seoSlice, user: userSlice, videos: videoSlice, - searchbar: searchbarSlice + searchbar: searchbarSlice, + notifications: notificationsSlice } }); diff --git a/rair-front/src/styled-components/SocialLinkIcons/SocialLinkIcons.tsx b/rair-front/src/styled-components/SocialLinkIcons/SocialLinkIcons.tsx index 30e918b46..4178feb7c 100644 --- a/rair-front/src/styled-components/SocialLinkIcons/SocialLinkIcons.tsx +++ b/rair-front/src/styled-components/SocialLinkIcons/SocialLinkIcons.tsx @@ -36,12 +36,12 @@ export const SocialBox = styled.div.withConfig({ span { width: 7px; height: 7px; - background: red; + // background: red; position: absolute; top: 0px; right: 0; border-radius: 50%; - background: #f63419; + // background: #f63419; } &.social-sun-icon {