diff --git a/docker-compose-prod.yaml b/docker-compose-prod.yaml index 88945b590..ec280b3ce 100644 --- a/docker-compose-prod.yaml +++ b/docker-compose-prod.yaml @@ -1,5 +1,3 @@ -version: '3.9' - services: rairnode: container_name: 'rairnode' diff --git a/docker-compose-web.yml b/docker-compose-web.yml index 71935fbd6..8c886be28 100644 --- a/docker-compose-web.yml +++ b/docker-compose-web.yml @@ -1,5 +1,3 @@ -version: '3.9' - services: rair-node: container_name: 'rair-node' diff --git a/docker-compose.local-new.yml b/docker-compose.local-new.yml index 0d6096ce6..6008aabb2 100644 --- a/docker-compose.local-new.yml +++ b/docker-compose.local-new.yml @@ -1,5 +1,3 @@ -version: '3.9' - services: rair-node: container_name: 'rair-node' diff --git a/docker-compose.local-ssl-with_certbot.yml b/docker-compose.local-ssl-with_certbot.yml index 0258df060..089089e4f 100644 --- a/docker-compose.local-ssl-with_certbot.yml +++ b/docker-compose.local-ssl-with_certbot.yml @@ -1,5 +1,3 @@ -version: '3.9' - services: certbot: image: certbot/certbot diff --git a/docker-compose.local-ssl-without_certbot.yml b/docker-compose.local-ssl-without_certbot.yml index c9cd0bf2f..a79bccf4c 100644 --- a/docker-compose.local-ssl-without_certbot.yml +++ b/docker-compose.local-ssl-without_certbot.yml @@ -1,5 +1,3 @@ -version: '3.9' - services: rair-node: container_name: 'rair-node' diff --git a/docker-compose.yml b/docker-compose.yml index c6c9f4c1d..67d82bddb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3.9' - services: rair-node: container_name: 'rair-node' diff --git a/rair-front/.env.sample b/rair-front/.env.sample index 938397666..b1bd83c05 100644 --- a/rair-front/.env.sample +++ b/rair-front/.env.sample @@ -18,13 +18,13 @@ VITE_UPLOAD_PROGRESS_HOST=http://localhost:5000 VITE_NODE_SOCKET_URI=:5000 -VITE_TESTNET=false +//VITE_TESTNET=false -VITE_HTML_META_TITLE=RAIR Collectible Marketplace +VITE_HTML_META_TITLE=RAIRprotocol | Open-source Deployment Layer VITE_HTML_META_FAVICON_URI=./favicons/loading-favicon.svg -VITE_HTML_META_IMAGE_URL=https://proofof.s3.filebase.com/rairmarket.webp -VITE_HTML_META_AUTHOR=RAIR Collectible Marketplace -VITE_HTML_META_DESCRIPTION=We help IP owners make their content collectible through private label marketplaces. Mint, stream, sell digital assets. +VITE_HTML_META_IMAGE_URL=https://github.com/rairprotocol/RAIRsite/blob/main/src/assets/images/1500x500.jpg +VITE_HTML_META_AUTHOR=RAIRprotocol | Open-source Deployment Layer +VITE_HTML_META_DESCRIPTION=RAIRTECH is pioneering the future of open-source Web3 deployment. With the creation of RAIRprotocol, enterprises can now access a truly open deployment layer, eliminating API risks and fulfilling the transparent promise of Web3. We support the RAIRprotocol ecosystem with a comprehensive suite of managed services, ensuring seamless and secure integration for your business. VITE_IPFS_GATEWAY=http://rair.myfilebase.com/ipfs/ VITE_DEFAULT_BLOCKCHAIN=0x2105 diff --git a/rair-front/Dockerfile b/rair-front/Dockerfile index 4423e3a1f..9e3df894e 100644 --- a/rair-front/Dockerfile +++ b/rair-front/Dockerfile @@ -1,4 +1,4 @@ -FROM node:lts as build +FROM node:lts AS build #install dependencies WORKDIR /usr/src/minting diff --git a/rair-front/Dockerfile.prod b/rair-front/Dockerfile.prod index 06bf63f38..78fff4eff 100644 --- a/rair-front/Dockerfile.prod +++ b/rair-front/Dockerfile.prod @@ -1,6 +1,6 @@ # build environment -FROM node:22.4.0 as build +FROM node:22.4.0 AS build WORKDIR /usr/src/minting diff --git a/rair-front/Dockerfile.prod-new b/rair-front/Dockerfile.prod-new index 4ff19c147..7ff80e6b8 100644 --- a/rair-front/Dockerfile.prod-new +++ b/rair-front/Dockerfile.prod-new @@ -1,6 +1,6 @@ # build environment -FROM node:21.2.0 as build +FROM node:21.2.0 AS build WORKDIR /usr/src/minting diff --git a/rair-front/env-templates/opencarbon.sample b/rair-front/env-templates/opencarbon.sample new file mode 100644 index 000000000..938397666 --- /dev/null +++ b/rair-front/env-templates/opencarbon.sample @@ -0,0 +1,31 @@ +VITE_NODE_ADDRESS=0x3fD4268B03cce553f180E77dfC14fde00271F9B7 +VITE_DIAMONDS_ENABLED=true +VITE_LOG_WEB3=false +VITE_HOME_PAGE=/ +VITE_DISABLE_CREATOR_VIEWS=false +VITE_3_TAB_MARKETPLACE_DISABLED=false +VITE_TEST_CONTRACTS=true +DANGEROUSLY_DISABLE_HOST_CHECK=true +VITE_GOOGLE_ANALYTICS=t +VITE_GA_NAME=t + +// Optional +// Please go to web3auth to get your free API key +// VITE_WEB3AUTH_CLIENT_ID= + +#upload_progress_host +VITE_UPLOAD_PROGRESS_HOST=http://localhost:5000 + +VITE_NODE_SOCKET_URI=:5000 + +VITE_TESTNET=false + +VITE_HTML_META_TITLE=RAIR Collectible Marketplace +VITE_HTML_META_FAVICON_URI=./favicons/loading-favicon.svg +VITE_HTML_META_IMAGE_URL=https://proofof.s3.filebase.com/rairmarket.webp +VITE_HTML_META_AUTHOR=RAIR Collectible Marketplace +VITE_HTML_META_DESCRIPTION=We help IP owners make their content collectible through private label marketplaces. Mint, stream, sell digital assets. +VITE_IPFS_GATEWAY=http://rair.myfilebase.com/ipfs/ + +VITE_DEFAULT_BLOCKCHAIN=0x2105 +VITE_WEB3AUTH_CLIENT_ID=BEfl04Slm6zUDrpxC-r5qgO6cjW2mlXc82z0rvTiNL-JdYTxYQHl7YzyNy4Ja4jq8fUDhysW1hwRDqLM6tYK3-4 diff --git a/rair-front/package.json b/rair-front/package.json index 54c282c7b..04b688685 100644 --- a/rair-front/package.json +++ b/rair-front/package.json @@ -5,7 +5,7 @@ "type": "module", "scripts": { "start": "vite", - "build": "tsc && vite build", + "build": "tsc --target ES2020 && vite build", "preview": "vite preview", "lint": "eslint src/**/*.{js,jsx,ts,tsx}", "lint:fix": "eslint --fix \"src/**/*.{js,jsx,ts,tsx}\"", @@ -13,94 +13,96 @@ "prepare": "cd ../ && husky install ./minting-marketplace/.husky" }, "dependencies": { - "@alchemy/aa-accounts": "^3.18.2", - "@alchemy/aa-alchemy": "^3.18.2", - "@alchemy/aa-core": "^3.18.2", - "@alchemy/aa-ethers": "^3.18.2", - "@alchemy/aa-signers": "^3.18.2", + "@alchemy/aa-accounts": "^3.19.0", + "@alchemy/aa-alchemy": "^3.19.0", + "@alchemy/aa-core": "^3.19.0", + "@alchemy/aa-ethers": "^3.19.0", + "@alchemy/aa-signers": "^3.19.0", "@analytics/google-analytics": "^1.0.7", - "@emotion/react": "^11.11.4", - "@emotion/styled": "^11.11.0", - "@fortawesome/fontawesome-svg-core": "^6.5.2", - "@fortawesome/free-brands-svg-icons": "^6.5.2", - "@fortawesome/free-solid-svg-icons": "^6.5.2", + "@emotion/is-prop-valid": "^1.3.0", + "@emotion/react": "^11.13.3", + "@emotion/styled": "^11.13.0", + "@fortawesome/fontawesome-svg-core": "^6.6.0", + "@fortawesome/free-brands-svg-icons": "^6.6.0", + "@fortawesome/free-solid-svg-icons": "^6.6.0", "@fortawesome/react-fontawesome": "^0.2.2", - "@getyoti/react-face-capture": "^2.0.0", + "@getyoti/react-face-capture": "^2.3.1", "@metamask/onboarding": "^1.0.1", "@metamask/providers": "^14.0.2", - "@mui/icons-material": "^5.14.18", - "@mui/material": "^5.14.18", + "@mui/icons-material": "^5.16.7", + "@mui/material": "^5.16.7", + "@reduxjs/toolkit": "^2.2.7", "@sentry/browser": "^7.85.0", "@sentry/react": "^7.85.0", - "@types/react-router": "^5.1.20", - "@types/react-slick": "^0.23.12", - "@types/slick-carousel": "^1.6.40", - "@types/styled-components": "^5.1.32", - "@types/uuid": "^9.0.7", - "@walletconnect/sign-client": "^2.10.6", - "@walletconnect/utils": "^2.11.0", - "@web3auth/base": "^8.6.2", - "@web3auth/modal": "^8.6.2", - "alchemy-sdk": "^3.2.0", - "analytics": "^0.8.9", - "axios": "^1.6.2", + "@walletconnect/sign-client": "^2.14.0", + "@walletconnect/utils": "^2.14.0", + "@web3auth/base": "^8.12.4", + "@web3auth/modal": "^8.12.4", + "alchemy-sdk": "^3.4.1", + "analytics": "^0.8.14", + "axios": "^1.7.5", "bootstrap": "^5.3.3", - "eslint-plugin-prettier": "^5.0.1", - "eslint-plugin-react": "^7.33.2", - "ethers": "^5.7.2", + "ethers": "^6.13.2", "global": "^4.4.0", - "husky": "^8.0.3", - "moment-timezone": "^0.5.43", - "prettier": "^3.1.1", - "react": "^18.2.0", + "moment-timezone": "^0.5.45", + "prettier": "^3.3.3", + "react": "^18.3.1", "react-accessible-accordion": "^5.0.0", - "react-dom": "^18.2.0", + "react-dom": "^18.3.1", "react-dropzone": "^14.2.3", "react-ga": "^3.3.1", - "react-helmet-async": "^2.0.3", - "react-hook-form": "^7.49.0", + "react-helmet-async": "^2.0.5", + "react-hook-form": "^7.52.2", "react-hot-toast": "^2.4.1", "react-modal": "^3.16.1", "react-moment": "^1.1.3", - "react-multi-carousel": "^2.8.4", - "react-player": "^2.13.0", - "react-redux": "^8.1.3", - "react-router-dom": "^6.22.3", - "react-share": "^5.0.3", + "react-multi-carousel": "^2.8.5", + "react-player": "^2.16.0", + "react-redux": "^9.1.2", + "react-router-dom": "^6.26.1", + "react-share": "^5.1.0", "react-slick": "^0.29.0", "react-tabs": "^6.0.2", "react-webcam": "^7.2.0", "reactjs-popup": "^2.0.6", - "redux": "^4.2.1", - "redux-saga": "^1.2.3", "slick-carousel": "^1.8.1", "socket.io-client": "^4.7.5", - "styled-components": "^5.3.3", + "styled-components": "^6.1.12", "sweetalert2": "^11.10.1", "sweetalert2-react-content": "^5.0.7", + "use-debounce": "^10.0.3", "use-state-if-mounted": "^1.0.7", - "uuid": "^9.0.1", - "video.js": "^8.10.0", + "uuid": "^10.0.0", + "video.js": "^8.17.3", "videojs-contrib-quality-levels": "^4.0.0", "videojs-hls-quality-selector": "^1.1.4", - "viem": "^2.8.11", - "vite-plugin-radar": "^0.9.2", + "viem": "^2.20.0", + "vite-plugin-radar": "^0.9.6", "vite-plugin-svgr": "^4.2.0", - "wicg-inert": "^3.1.2" + "wicg-inert": "^3.1.3" }, "devDependencies": { - "@types/react": "^18.2.43", - "@types/react-dom": "^18.2.15", + "@types/react": "^18.3.4", + "@types/react-dom": "^18.3.0", + "@types/react-modal": "^3.16.3", + "@types/react-router-dom": "^5.3.3", + "@types/react-slick": "^0.23.13", + "@types/slick-carousel": "^1.6.40", + "@types/styled-components": "^5.1.34", + "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "^6.14.0", "@typescript-eslint/parser": "^6.14.0", - "@vitejs/plugin-react": "^4.2.0", + "@vitejs/plugin-react": "^4.3.1", "eslint": "^8.55.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.4", - "eslint-plugin-simple-import-sort": "^10.0.0", - "typescript": "^5.4.2", - "vite": "^5.3.3", - "vite-plugin-node-polyfills": "^0.21.0" + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-react": "^7.35.0", + "eslint-plugin-react-hooks": "^4.6.2", + "eslint-plugin-react-refresh": "^0.4.9", + "eslint-plugin-simple-import-sort": "^12.1.1", + "husky": "^9.1.5", + "typescript": "^5.5.4", + "vite": "^5.4.2", + "vite-plugin-node-polyfills": "^0.22.0" } } diff --git a/rair-front/src/App.tsx b/rair-front/src/App.tsx index 88ea8568e..74aff8ccb 100644 --- a/rair-front/src/App.tsx +++ b/rair-front/src/App.tsx @@ -1,30 +1,13 @@ -//@ts-nocheck import { Fragment, useCallback, useEffect, useState } from 'react'; import { Toaster } from 'react-hot-toast'; -import { useDispatch, useSelector } from 'react-redux'; import { Route, Routes, useLocation, useNavigate } from 'react-router-dom'; -// React Redux types import { ErrorBoundary, withSentryReactRouterV6Routing } from '@sentry/react'; -import { RootState } from './ducks'; -// import * as ethers from 'ethers'; -// import * as colorTypes from './ducks/colors/types'; -// logos for About Page -import { - headerLogoBlack, - headerLogoWhite, - HotdropsFavicon, - RairFavicon -} from './images'; - -//import CSVParser from './components/metadata/csvParser'; import AboutPageNew from './components/AboutPage/AboutPageNew/AboutPageNew'; import ImportAndTransfer from './components/adminViews/ImportAndTransfer'; import ImportExternalContracts from './components/adminViews/ImportExternalContracts'; import LicenseExchange from './components/adminViews/LicenseExchange'; -import useServerSettings from './components/adminViews/useServerSettings'; import AlertMetamask from './components/AlertMetamask/index'; -import ConsumerMode from './components/consumerMode'; import DiamondMarketplace from './components/ConsumerMode/DiamondMarketplace'; import ContractDetails from './components/creatorStudio/ContractDetails'; import Contracts from './components/creatorStudio/Contracts'; @@ -44,12 +27,12 @@ import MockUpPage from './components/MockUpPage/MockUpPage'; import { NftDataCommonLink } from './components/MockUpPage/NftList/NftData/NftDataCommonLink'; import NftDataExternalLink from './components/MockUpPage/NftList/NftData/NftDataExternalLink'; import MenuNavigation from './components/Navigation/Menu'; -import MyItems from './components/nft/myItems'; import RairProduct from './components/nft/rairCollection'; import Token from './components/nft/Token'; import NotFound from './components/NotFound/NotFound'; import ResalePage from './components/ResalePage/ResalePage'; import MetaTags from './components/SeoTags/MetaTags'; +import ServerSettings from './components/ServerSettings'; import CoinAgenda2021SplashPage from './components/SplashPage/CoinAgenda2021/CoinAgenda2021'; import ComingSoonNut from './components/SplashPage/CommingSoon/ComingSoonNut'; import ComingSoon from './components/SplashPage/CommingSoon/CommingSoon'; @@ -72,17 +55,14 @@ import Wallstreet80sClubSplashPage from './components/SplashPage/wallstreet80scl import ThankYouPage from './components/ThankYouPage'; import UserProfilePage from './components/UserProfilePage/UserProfilePage'; import NotificationPage from './components/UserProfileSettings/NotificationPage/NotificationPage'; -// import setTitle from './utils/setTitle'; -import FileUpload from './components/video/videoUpload/videoUpload'; import VideoManager from './components/videoManager/VideoManager'; import YotiPage from './components/YotiPage/YotiPage'; -import { ColorStoreType } from './ducks/colors/colorStore.types'; -import { setChainId } from './ducks/contracts/actions'; -import { ContractsInitialType } from './ducks/contracts/contracts.types'; -import { getCurrentPageEnd } from './ducks/pages/actions'; -import { TUsersInitialState } from './ducks/users/users.types'; import useConnectUser from './hooks/useConnectUser'; +import useContracts from './hooks/useContracts'; +import { useAppDispatch, useAppSelector } from './hooks/useReduxHooks'; import useWeb3Tx from './hooks/useWeb3Tx'; +import { loadCategories, loadSettings } from './redux/settingsSlice'; +import { setConnectedChain } from './redux/web3Slice'; import { AppContainerFluid, MainBlockApp @@ -103,29 +83,22 @@ import './App.css'; const SentryRoutes = withSentryReactRouterV6Routing(Routes); function App() { - const dispatch = useDispatch(); - const { getServerSettings, settings, blockchainSettings } = - useServerSettings(); + const dispatch = useAppDispatch(); + const { blockchainSettings } = useAppSelector((store) => store.settings); const [renderBtnConnect, setRenderBtnConnect] = useState(false); const [showAlert, setShowAlert] = useState(true); const [isSplashPage, setIsSplashPage] = useState(false); const [isIframePage, setIsIframePage] = useState(false); const { - currentChain, - realChain, - diamondMarketplaceInstance, + connectedChain, + requestedChain, currentUserAddress, - minterInstance, programmaticProvider - } = useSelector( - (store) => store.contractStore - ); + } = useAppSelector((store) => store.web3); + const { diamondMarketplaceInstance } = useContracts(); const [isAboutPage, setIsAboutPage] = useState(false); - const { selectedChain, realNameChain, selectedChainId } = detectBlockchain( - currentChain, - realChain - ); - const seo = useSelector((store) => store.seoStore); + const { realNameChain } = detectBlockchain(connectedChain, requestedChain); + const seo = useAppSelector((store) => store.seo); const carousel_match = window.matchMedia('(min-width: 1025px)'); const [carousel, setCarousel] = useState(carousel_match.matches); const [tabIndex, setTabIndex] = useState(0); @@ -135,24 +108,29 @@ function App() { const [notificationCount, setNotificationCount] = useState(0); // Redux - const { primaryColor, textColor, backgroundImage, backgroundImageEffect } = - useSelector((store) => store.colorStore); - const { adminRights, loggedIn } = useSelector( - (store) => store.userStore - ); + const { + primaryColor, + textColor, + backgroundImage, + backgroundImageEffect, + isDarkMode + } = useAppSelector((store) => store.colors); + const { adminRights, isLoggedIn } = useAppSelector((store) => store.user); const { correctBlockchain } = useWeb3Tx(); - const { connectUserData, logoutUser } = useConnectUser(); + const { logoutUser } = useConnectUser(); const { pathname } = useLocation(); const showAlertHandler = useCallback(() => { setShowAlert( - (pathname !== '/' || isSplashPage) && + !!( + (pathname !== '/' || isSplashPage) && currentUserAddress && realNameChain && - !correctBlockchain(realChain) + !correctBlockchain(requestedChain) + ) ); }, [ pathname, @@ -160,14 +138,13 @@ function App() { currentUserAddress, realNameChain, correctBlockchain, - realChain + requestedChain ]); useEffect(() => showAlertHandler(), [showAlertHandler]); const goHome = () => { navigate('/'); - dispatch(getCurrentPageEnd()); sessionStorage.removeItem('CategoryItems'); sessionStorage.removeItem('BlockchainItems'); }; @@ -183,7 +160,7 @@ function App() { useEffect(() => { if (window.ethereum) { const foo = async (chainId) => { - dispatch(setChainId(chainId, blockchainSettings)); + dispatch(setConnectedChain(chainId)); }; window.ethereum.on('chainChanged', foo); window.ethereum.on('accountsChanged', logoutUser); @@ -195,13 +172,15 @@ function App() { }, [dispatch, logoutUser, blockchainSettings]); const getNotificationsCount = useCallback(async () => { - if (currentUserAddress) { + if (isLoggedIn && currentUserAddress) { const result = await rFetch(`/api/notifications?onlyUnread=true`); if (result.success && result.totalCount >= 0) { setNotificationCount(result.totalCount); } + } else { + setNotificationCount(0); } - }, [currentUserAddress]); + }, [isLoggedIn, currentUserAddress]); useEffect(() => { getNotificationsCount(); @@ -210,10 +189,10 @@ function App() { // gtag useEffect(() => { - gtag('event', 'page_view', { + gtag(/*'event', 'page_view', { page_title: window.location.pathname, page_location: window.location.href - }); + }*/); }, []); useEffect(() => { @@ -231,17 +210,18 @@ function App() { }, [carousel_match.matches]); useEffect(() => { - if (primaryColor === 'charcoal') { + if (isDarkMode) { (function () { let angle = 0; const p = document.querySelector('p'); - if (p) { + if (p?.textContent) { const text = p.textContent.split(''); - /* eslint-disable */ + // eslint-disable-next-line no-var var len = text.length; + // eslint-disable-next-line no-var var phaseJump = 360 / len; + // eslint-disable-next-line no-var var spans; - /* eslint-enable */ p.innerHTML = text .map(function (char) { return '' + char + ''; @@ -261,7 +241,7 @@ function App() { })(); })(); } - }, [primaryColor]); + }, [isDarkMode]); const hotDropsVar = import.meta.env.VITE_TESTNET; @@ -275,68 +255,20 @@ function App() { const creatorViewsDisabled = import.meta.env.VITE_DISABLE_CREATOR_VIEWS === 'true'; - const loadLogos = useCallback(async () => { - getServerSettings(); - }, [getServerSettings]); - useEffect(() => { - loadLogos(); + dispatch(loadSettings()); + dispatch(loadCategories()); }, []); - useEffect(() => { - if (settings.favicon) { - const changeFavicon = () => { - const link = - document.querySelector("link[rel*='icon']") || - document.createElement('link'); - link.type = 'image/x-icon'; - link.rel = 'icon'; - link.href = settings.favicon; // Set the href to your favicon - document.getElementsByTagName('head')[0].appendChild(link); - }; - - changeFavicon(); // Call the function to change the favicon when the component mounts - } else { - const changeFavicon = () => { - const link = - document.querySelector("link[rel*='icon']") || - document.createElement('link'); - link.type = 'image/x-icon'; - link.rel = 'icon'; - link.href = - import.meta.env.VITE_TESTNET === 'true' - ? HotdropsFavicon - : RairFavicon; // Set the href to your favicon - document.getElementsByTagName('head')[0].appendChild(link); - }; - - changeFavicon(); // Call the function to change the favicon when the component mounts - } - - // Optionally, you can remove the old favicon when the component unmounts - return () => { - const link = document.querySelector("link[rel*='icon']"); - if (link) { - link.parentNode.removeChild(link); - } - }; - }, [settings]); - return ( }> - {showAlert === true && ( - - )} + {showAlert === true && } @@ -358,9 +290,8 @@ function App() { renderBtnConnect={renderBtnConnect} creatorViewsDisabled={creatorViewsDisabled} showAlert={showAlert} - selectedChain={correctBlockchain(realChain)} isSplashPage={isSplashPage} - realChainId={realNameChain && realChain} + realChainId={realNameChain && requestedChain} setTabIndexItems={setTabIndexItems} isAboutPage={isAboutPage} setTokenNumber={setTokenNumber} @@ -368,14 +299,11 @@ function App() { ) : ( !isIframePage && ( +
@@ -424,11 +347,6 @@ function App() { required: false, default: undefined }, - exact: { - type: Boolean, - required: false, - default: true - } } */} @@ -440,109 +358,100 @@ function App() { {[ { path: '/simdogs-splash', - content: SimDogsSplashPage + content: }, { path: '/markkohler-splash', - content: MarkKohler, - props: { setIsSplashPage } + content: }, { path: '/genesis-splash', - content: RAIRGenesisSplashPage + content: }, { path: '/wallstreet80sclub', - content: Wallstreet80sClubSplashPage + content: ( + + ) }, { path: '/coinagenda2021', - content: CoinAgenda2021SplashPage + content: ( + + ) }, { path: '/immersiverse-splash', - content: ImmersiVerseSplashPage + content: }, { path: '/nftnyc-splash', - content: NFTNYCSplashPage + content: }, { path: '/video-tiles-test', - content: VideoTilesTest + content: }, { path: '/nftla-splash', - content: NFTLASplashPage + content: }, { path: '/ukraineglitch', - content: UkraineSplashPage + content: }, { path: '/vaporverse-splash', - content: VaporverseSplashPage + content: }, { path: '/greyman-splash', - content: GreymanSplashPage + content: }, { path: '/nutcrackers-splash', - content: Nutcrackers + content: }, { path: '/nipsey-splash', - content: SplashPage + content: }, { path: '/slidelock', - content: SlideLock + content: }, { path: '/yoti-page', - content: YotiPage + content: }, { path: '/about-page', - content: AboutPageNew, - props: { - headerLogoWhite: headerLogoWhite, - headerLogoBlack: headerLogoBlack, - setIsSplashPage: setIsSplashPage - } + content: }, { path: '/main-page', - content: MainPage, - props: { - setIsSplashPage: setIsSplashPage, - setIsAboutPage: setIsAboutPage - } + content: ( + + ) } ].map((item, index) => { // If the path is set as the Home Page, render it as the default path (/) const isHome = item.path === import.meta.env.VITE_HOME_PAGE; if (import.meta.env.VITE_HOME_PAGE !== '/' && !isHome) { - return ; + return ; } return ( - } + element={item.content} /> ); })} @@ -553,259 +462,246 @@ function App() { */ { path: '/', - content: WelcomeHeader, - requirement: import.meta.env.VITE_HOME_PAGE === '/', - props: { - setIsSplashPage, - tabIndex: tabIndex, - setTabIndex: setTabIndex - } + content: ( + + ), + requirement: import.meta.env.VITE_HOME_PAGE === '/' }, { path: '/demo/upload', - content: DemoMediaUpload, + content: , requirement: hotDropsVar === 'true' - ? loggedIn && adminRights - : loggedIn + ? isLoggedIn && adminRights + : isLoggedIn }, { path: '/user/videos', - content: VideoManager + content: }, // Server Settings view { path: '/admin/settings', - content: FileUpload, + content: , requirement: - loggedIn && !creatorViewsDisabled && adminRights + isLoggedIn && !creatorViewsDisabled && adminRights }, // License UI { path: '/license', - content: LicenseExchange, - requirement: loggedIn && !creatorViewsDisabled + content: , + requirement: isLoggedIn && !creatorViewsDisabled }, // Token transfers { path: '/admin/transferNFTs', - content: ImportAndTransfer, - constraint: loggedIn && !creatorViewsDisabled + content: , + constraint: isLoggedIn && !creatorViewsDisabled }, // Resale offers page { path: '/resale-offers', - content: ResalePage, + content: , requirement: - loggedIn && adminRights && !creatorViewsDisabled, - exact: true + isLoggedIn && adminRights && !creatorViewsDisabled }, // Creator UI - New Views based on Figma { path: '/creator/deploy', - content: Deploy, + content: , requirement: - loggedIn && adminRights && !creatorViewsDisabled + isLoggedIn && adminRights && !creatorViewsDisabled }, { path: '/creator/contracts', - content: Contracts, - requirement: loggedIn && !creatorViewsDisabled + content: , + requirement: isLoggedIn && !creatorViewsDisabled }, { path: '/creator/contract/:blockchain/:address/createCollection', - content: ContractDetails, - requirement: loggedIn && !creatorViewsDisabled + content: , + requirement: isLoggedIn && !creatorViewsDisabled }, { path: '/creator/contract/:blockchain/:address/listCollections', - content: ListCollections, - requirement: loggedIn && !creatorViewsDisabled + content: , + requirement: isLoggedIn && !creatorViewsDisabled }, { path: '/creator/contract/:blockchain/:address/collection/:collectionIndex/*', // NEW: Wildcard allows WorkflowSteps to have routes within - content: WorkflowSteps, - requirement: loggedIn && !creatorViewsDisabled, - exact: false + content: , + requirement: isLoggedIn && !creatorViewsDisabled }, // Old Creator UI (Using the Database) { path: '/on-sale', - content: MinterMarketplace, - requirement: loggedIn && !creatorViewsDisabled + content: , + requirement: isLoggedIn && !creatorViewsDisabled }, { path: '/rair/:contract/:product', - content: RairProduct, - requirement: loggedIn && !creatorViewsDisabled + content: , + requirement: isLoggedIn && !creatorViewsDisabled }, // Old Token Viewer (Using the database) { path: '/token/:blockchain/:contract/:identifier', - content: Token, - requirement: loggedIn && !creatorViewsDisabled - }, - - // Classic Minter Marketplace (Uses the blockchain) - { - path: '/minter', - content: ConsumerMode, - requirement: - loggedIn && - !creatorViewsDisabled && - minterInstance !== undefined + content: , + requirement: isLoggedIn && !creatorViewsDisabled }, // Diamond Marketplace (Uses the blockchain) { path: '/diamondMinter', - content: DiamondMarketplace, + content: , requirement: - loggedIn && + isLoggedIn && !creatorViewsDisabled && diamondMarketplaceInstance !== undefined }, { path: '/importExternalContracts', - content: ImportExternalContracts, - constraint: loggedIn && !creatorViewsDisabled + content: , + constraint: isLoggedIn && !creatorViewsDisabled }, { path: '/about-page', - content: AboutPageNew, - props: { - headerLogoWhite: headerLogoWhite, - headerLogoBlack: headerLogoBlack, - setIsSplashPage: setIsSplashPage - } + content: ( + + ) }, // Public Facing Routes { path: '/all', - content: MockUpPage, - props: { - tabIndex: tabIndex, - setTabIndex: setTabIndex - } - }, - { - path: '/profile/my-items', - content: MyItems, - requirement: loggedIn, - props: { - goHome, - setIsSplashPage, - setTabIndexItems, - tabIndexItems - } + content: ( + + ) }, { path: '/:userAddress', - content: UserProfilePage + content: }, { path: '/:contractId/:product/:offer/:token', - content: NftDataExternalLink + content: }, { path: '/coming-soon', - content: ComingSoon + content: }, { path: '/coming-soon-nutcrackers', - content: ComingSoonNut + content: }, { path: '/privacy', - content: PrivacyPolicy, - props: { - setIsSplashPage: setIsSplashPage - } + content: }, { path: '/terms-use', - content: TermsUse, - props: { - setIsSplashPage: setIsSplashPage - } + content: }, { path: '/:userAddress', - content: UserProfilePage + content: }, { path: '/thankyou', - content: ThankYouPage + content: }, { path: '/inquiries', - content: InquiriesPage + content: }, //3 Tab Marketplace? { path: '/tokens/:blockchain/:contract/:product/:tokenId', - content: NftDataCommonLink, - props: { - setTokenNumber, - tokenNumber - }, + content: ( + + ), requirement: import.meta.env.VITE_3_TAB_MARKETPLACE_DISABLED !== 'true' }, { path: '/collection/:blockchain/:contract/:product/:tokenId', - content: NftDataCommonLink, - props: { - setTokenNumber, - tokenNumber - }, + content: ( + + ), requirement: import.meta.env.VITE_3_TAB_MARKETPLACE_DISABLED !== 'true' }, { path: '/unlockables/:blockchain/:contract/:product/:tokenId', - content: NftDataCommonLink, - props: { - setTokenNumber, - tokenNumber - }, + content: ( + + ), requirement: import.meta.env.VITE_3_TAB_MARKETPLACE_DISABLED !== 'true' }, { path: '/notifications', - content: NotificationPage + content: }, // Video Player { path: '/watch/:contract/:videoId/:mainManifest', - content: IframePage, - props: { - setIsIframePage, - renderBtnConnect, - programmaticProvider - } + content: ( + + ) }, { path: '/test-iframe/:contract/:videoId/:mainManifest', - content: TestIframe, - props: { setIsIframePage } + content: }, { path: '*', - content: NotFound, - exact: false + content: }, { path: '/404', - content: NotFound, - exact: false + content: } ].map((item, index) => { // If the requirements for the route aren't met, it won't return anything @@ -815,9 +711,8 @@ function App() { return ( } + element={item.content} /> ); })} diff --git a/rair-front/src/axios.responseTypes.ts b/rair-front/src/axios.responseTypes.ts index 541026a39..0df9b863c 100644 --- a/rair-front/src/axios.responseTypes.ts +++ b/rair-front/src/axios.responseTypes.ts @@ -1,6 +1,8 @@ import { TOfferType } from './components/marketplace/marketplace.types'; import { MediaListResponseType } from './components/video/video.types'; -import { UserType } from './ducks/users/users.types'; +import { CatalogItem } from './redux/tokenSlice'; +import { CatalogVideoItem } from './types/commonTypes'; +import { User } from './types/databaseTypes'; export type BackendResponse = { success: boolean; @@ -9,15 +11,10 @@ export type BackendResponse = { export type TUserResponse = { success: boolean; - user: UserType | null; + user: User; message: string; }; -export type TNftItemResult = { - totalCount: number; - tokens: TTokenData[]; -}; - export type TAttributes = { trait_type: string; value: string; @@ -58,8 +55,8 @@ export type TTokenData = { export type TNftItemResponse = { success: boolean; - result: TNftItemResult; - tokens?: any; + totalCount: number; + tokens: TTokenData[]; }; export type TFavotiteTokenData = { @@ -88,32 +85,9 @@ export type TFileKeyType = { }; }; -export type TFileType = { - animatedThumbnail: string; - ageRestricted?: boolean; - author: string; - uploader: string; - category: string; - contract: string; - creationDate: string; - demo: boolean; - description: string; - duration: string; - encryptionType: string; - extension: string; - isUnlocked: boolean; - mainManifest: string; - offer: string[]; - product: string; - staticThumbnail: string; - title: string; - type: string; - _id: string; -}; - export type TNftFilesResponse = { success: boolean; - files: TFileType[]; + files: CatalogVideoItem[]; }; export type IOffersResponseType = { @@ -128,29 +102,11 @@ export type TMediaList = { }; export type TGetFullContracts = { - contracts: TContract[]; + contracts: CatalogItem[]; success: boolean; totalNumber: number; }; -export type TContract = { - blockchain: BlockchainType; - contractAddress: string; - creationDate: string; - diamond: boolean; - external: boolean; - lastSyncedBlock: string; - metadataURI: string; - offerPool?: TOfferPool; - products: TProducts; - singleMetadata: boolean; - title: string; - transactionHash?: string; - user: string; - userData: UserType | null; - _id: string; -}; - export type TProducts = { collectionIndexInContract: string; contract: string; @@ -218,7 +174,7 @@ export type TUploadSocket = { }; export type TNftDataExternalLinkResultType = { - contract: TContract; + contract: CatalogItem; tokens: TTokenData[]; totalCount: number; }; diff --git a/rair-front/src/components/AboutPage/AboutPageNew/AboutPageNew.tsx b/rair-front/src/components/AboutPage/AboutPageNew/AboutPageNew.tsx index 914ccfe74..fb8b03a59 100644 --- a/rair-front/src/components/AboutPage/AboutPageNew/AboutPageNew.tsx +++ b/rair-front/src/components/AboutPage/AboutPageNew/AboutPageNew.tsx @@ -1,17 +1,13 @@ -import React, { useEffect } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { FC, useEffect } from 'react'; import { useLocation } from 'react-router-dom'; -import Swal from 'sweetalert2'; +import { Hex } from 'viem'; -import { IAboutPageNew } from './aboutPage.types'; - -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; -import { setInfoSEO } from '../../../ducks/seo/actions'; -import { InitialState } from '../../../ducks/seo/reducers'; -import { TInfoSeo } from '../../../ducks/seo/seo.types'; import useConnectUser from '../../../hooks/useConnectUser'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; +import useSwal from '../../../hooks/useSwal'; import { metaMaskIcon, RairLogoBlue } from '../../../images'; +import { setSEOInfo } from '../../../redux/seoSlice'; +import { SplashPageProps } from '../../../types/commonTypes'; import PurchaseTokenButton from '../../common/PurchaseToken'; import { rairAdvisorsTeam, teamAboutRair } from '../../MainPage/AboutUsTeam'; import MetaTags from '../../SeoTags/MetaTags'; @@ -29,20 +25,18 @@ import StreamsAbout from './StreamsAbout/StreamsAbout'; import './AboutPageNew.css'; -const AboutPageNew: React.FC = ({ setIsSplashPage }) => { +const AboutPageNew: FC = ({ setIsSplashPage }) => { const { pathname } = useLocation(); - const dispatch = useDispatch(); - const seo = useSelector((store) => store.seoStore); - const { primaryColor } = useSelector( - (store) => store.colorStore - ); + const dispatch = useAppDispatch(); + const seo = useAppSelector((store) => store.seo); + const { primaryColor } = useAppSelector((store) => store.colors); + const rSwal = useSwal(); const connectUserData = useConnectUser(); useEffect(() => { - dispatch(setInfoSEO(InitialState)); - //eslint-disable-next-line - }, []); + dispatch(setSEOInfo()); + }, [dispatch]); const termsText = 'I understand this a test NFT designed to unlock RAIR streams'; @@ -59,9 +53,8 @@ const AboutPageNew: React.FC = ({ setIsSplashPage }) => { setIsSplashPage(true); }, [setIsSplashPage]); - const switchToNetwork = '0x38'; - const aboutPageAddress = - '0xb6163454da87e9f3fd63683c5d476f7d067f75a2'.toLowerCase(); + const switchToNetwork: Hex = '0x38'; + const aboutPageAddress: Hex = '0xb6163454da87e9f3fd63683c5d476f7d067f75a2'; const offerIndexInMarketplace = '1'; const purchaseButton = ( @@ -77,7 +70,7 @@ const AboutPageNew: React.FC = ({ setIsSplashPage }) => { presaleMessage: termsText, diamond: true, customSuccessAction: (nextToken) => - Swal.fire('Success', `You own token #${nextToken}!`, 'success') + rSwal.fire('Success', `You own token #${nextToken}!`, 'success') }} /> ); @@ -89,14 +82,13 @@ const AboutPageNew: React.FC = ({ setIsSplashPage }) => {
- + - + = ({ setIsSplashPage }) => { purchaseButton={purchaseButton} /> {/* */} - +
{ const [categories, setCategories] = useState(10); + const { iconColor } = useAppSelector((store) => store.colors); const handleChange = (event) => { setCategories(event.target.value); @@ -82,6 +84,7 @@ const CompareAbout = () => {
diff --git a/rair-front/src/components/AboutPage/AboutPageNew/ExclusiveNfts/MainSelectNft.jsx b/rair-front/src/components/AboutPage/AboutPageNew/ExclusiveNfts/MainSelectNft.jsx index c2d99631e..54e8a833b 100644 --- a/rair-front/src/components/AboutPage/AboutPageNew/ExclusiveNfts/MainSelectNft.jsx +++ b/rair-front/src/components/AboutPage/AboutPageNew/ExclusiveNfts/MainSelectNft.jsx @@ -1,6 +1,9 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; -export const MainSelectNft = styled.div` +export const MainSelectNft = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` background: url(${(props) => (props.NftImage ? props.NftImage : '')}) no-repeat; background-size: cover; diff --git a/rair-front/src/components/AboutPage/AboutPageNew/LeftTokenAbout/LeftTokenAbout.tsx b/rair-front/src/components/AboutPage/AboutPageNew/LeftTokenAbout/LeftTokenAbout.tsx index ec9be01bd..92f5ff412 100644 --- a/rair-front/src/components/AboutPage/AboutPageNew/LeftTokenAbout/LeftTokenAbout.tsx +++ b/rair-front/src/components/AboutPage/AboutPageNew/LeftTokenAbout/LeftTokenAbout.tsx @@ -1,9 +1,10 @@ -import React from 'react'; +import { FC } from 'react'; +import { useAppSelector } from '../../../../hooks/useReduxHooks'; import { discrodIconNoBorder } from '../../../../images'; -import { ILeftTokenAbout } from '../aboutPage.types'; -const LeftTokenAbout: React.FC = ({ primaryColor }) => { +const LeftTokenAbout: FC = () => { + const { isDarkMode } = useAppSelector((store) => store.colors); return (
@@ -14,24 +15,24 @@ const LeftTokenAbout: React.FC = ({ primaryColor }) => {
-

+

RAIRtech has developed a new way to control content on the blockchain called DDRM or distributed digital rights management.

  • -

    +

    Allows for encrypted streaming of videos, music, images and data

  • -

    +

    Only the owner of the NFT can stream the content this makes digital goods work like real goods

  • -

    +

    Feature complete platform: minting, streaming, royalties & metadata

    diff --git a/rair-front/src/components/AboutPage/AboutPageNew/MainBlock/MainBlock.tsx b/rair-front/src/components/AboutPage/AboutPageNew/MainBlock/MainBlock.tsx index 71d2ef5f0..2e73d1804 100644 --- a/rair-front/src/components/AboutPage/AboutPageNew/MainBlock/MainBlock.tsx +++ b/rair-front/src/components/AboutPage/AboutPageNew/MainBlock/MainBlock.tsx @@ -1,18 +1,17 @@ -import { useState /*useCallback, useEffect*/ } from 'react'; +import { useState } from 'react'; import Modal from 'react-modal'; -import { useSelector } from 'react-redux'; +import { Hex } from 'viem'; import { diamondFactoryAbi } from '../../../../contracts/index'; -import { RootState } from '../../../../ducks'; -import { ContractsInitialType } from '../../../../ducks/contracts/contracts.types'; import useConnectUser from '../../../../hooks/useConnectUser'; +import useContracts from '../../../../hooks/useContracts'; +import { useAppSelector } from '../../../../hooks/useReduxHooks'; import useSwal from '../../../../hooks/useSwal'; import useWeb3Tx from '../../../../hooks/useWeb3Tx'; -// import { rFetch } from "../../../../utils/rFetch"; -// import { erc721Abi } from "../../../../contracts"; +import { CustomModalStyle } from '../../../../types/commonTypes'; import { IMainBlock } from '../aboutPage.types'; -const customStyles = { +const customStyles: CustomModalStyle = { overlay: { zIndex: '1' }, @@ -38,26 +37,23 @@ Modal.setAppElement('#root'); const MainBlock: React.FC = ({ Metamask, - primaryColor, termsText, purchaseButton }) => { const [modalIsOpen, setIsOpen] = useState(false); const [active, setActive] = useState({ policy: false, use: false }); - const { diamondMarketplaceInstance, contractCreator, currentUserAddress } = - useSelector( - (store) => store.contractStore - ); + const { diamondMarketplaceInstance, contractCreator } = useContracts(); + const { currentUserAddress } = useAppSelector((store) => store.web3); const reactSwal = useSwal(); const { web3TxHandler, correctBlockchain, web3Switch } = useWeb3Tx(); const { connectUserData } = useConnectUser(); + const { isDarkMode } = useAppSelector((store) => store.colors); const targetBlockchain = '0x38'; - const aboutPageAddress = - '0xb6163454da87e9f3fd63683c5d476f7d067f75a2'.toLowerCase(); + const aboutPageAddress: Hex = '0xb6163454da87e9f3fd63683c5d476f7d067f75a2'; const offerIndexInMarketplace = 1; let subtitle; @@ -165,15 +161,12 @@ const MainBlock: React.FC = ({ return (
    -

    +

    Encrypted,
    Streaming NFTs

    -
    +
    Our platform makes it possible to attach digital goods
    {"to an NFT using encrypted streaming - making today's"} diff --git a/rair-front/src/components/AboutPage/AboutPageNew/RairOffer/RairOffer.tsx b/rair-front/src/components/AboutPage/AboutPageNew/RairOffer/RairOffer.tsx index 1fdb93bb9..0c2d0dd8e 100644 --- a/rair-front/src/components/AboutPage/AboutPageNew/RairOffer/RairOffer.tsx +++ b/rair-front/src/components/AboutPage/AboutPageNew/RairOffer/RairOffer.tsx @@ -1,8 +1,9 @@ -import React from 'react'; +import { FC } from 'react'; -import { IRairOffer } from '../aboutPage.types'; +import { useAppSelector } from '../../../../hooks/useReduxHooks'; -const RairOffer: React.FC = ({ primaryColor }) => { +const RairOffer: FC = () => { + const { isDarkMode } = useAppSelector((store) => store.colors); return (
    @@ -10,10 +11,7 @@ const RairOffer: React.FC = ({ primaryColor }) => {
    -
    +
    @@ -32,9 +30,7 @@ const RairOffer: React.FC = ({ primaryColor }) => {
    @@ -55,7 +51,7 @@ const RairOffer: React.FC = ({ primaryColor }) => {
    2 diff --git a/rair-front/src/components/AboutPage/AboutPageNew/RoadMapAbout/RoadMapAbout.tsx b/rair-front/src/components/AboutPage/AboutPageNew/RoadMapAbout/RoadMapAbout.tsx index e397de9e5..f9540c6af 100644 --- a/rair-front/src/components/AboutPage/AboutPageNew/RoadMapAbout/RoadMapAbout.tsx +++ b/rair-front/src/components/AboutPage/AboutPageNew/RoadMapAbout/RoadMapAbout.tsx @@ -1,8 +1,9 @@ -import React from 'react'; +import { FC } from 'react'; -import { IRoadMap } from '../aboutPage.types'; +import { useAppSelector } from '../../../../hooks/useReduxHooks'; -const RoadMap: React.FC = ({ primaryColor }) => { +const RoadMap: FC = () => { + const { isDarkMode } = useAppSelector((store) => store.colors); return (
    2022 Roadmap
    @@ -16,10 +17,7 @@ const RoadMap: React.FC = ({ primaryColor }) => {
    Q2
    Q3
    -
    +
    Curation Alpha
    @@ -39,10 +37,7 @@ const RoadMap: React.FC = ({ primaryColor }) => {
    Q3
    Q4
    -
    +
    Private Beta
    @@ -62,10 +57,7 @@ const RoadMap: React.FC = ({ primaryColor }) => {
    Q4
    Q5
    -
    +
    Public Release
    @@ -88,10 +80,7 @@ const RoadMap: React.FC = ({ primaryColor }) => {
    Q2
    Q3
    -
    +
    Curation Alpha
    @@ -111,10 +100,7 @@ const RoadMap: React.FC = ({ primaryColor }) => {
    Q4
    Q5
    -
    +
    Public Release
    @@ -126,10 +112,7 @@ const RoadMap: React.FC = ({ primaryColor }) => {
    -
    +
    @@ -144,10 +127,7 @@ const RoadMap: React.FC = ({ primaryColor }) => {
    Q3
    Q4
    -
    +
    Private Beta
    diff --git a/rair-front/src/components/AboutPage/AboutPageNew/StreamsAbout/StreamsAbout.tsx b/rair-front/src/components/AboutPage/AboutPageNew/StreamsAbout/StreamsAbout.tsx index 12eb26250..6684d1014 100644 --- a/rair-front/src/components/AboutPage/AboutPageNew/StreamsAbout/StreamsAbout.tsx +++ b/rair-front/src/components/AboutPage/AboutPageNew/StreamsAbout/StreamsAbout.tsx @@ -1,20 +1,17 @@ import React, { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import axios from 'axios'; -import { TFileType, TNftFilesResponse } from '../../../../axios.responseTypes'; -import { RootState } from '../../../../ducks'; -import { ColorStoreType } from '../../../../ducks/colors/colorStore.types'; +import { TNftFilesResponse } from '../../../../axios.responseTypes'; +import { useAppSelector } from '../../../../hooks/useReduxHooks'; +import { CatalogVideoItem } from '../../../../types/commonTypes'; import VideoPlayerView from '../../../MockUpPage/NftList/NftData/UnlockablesPage/VideoPlayerView'; import { IStreamsAbout } from '../aboutPage.types'; const StreamsAbout: React.FC = ({ purchaseButton }) => { const whatSplashPage = 'about-page'; - const [allVideos, setAllVideos] = useState([]); - const [selectVideo, setSelectVideo] = useState(); - const { primaryColor } = useSelector( - (store) => store.colorStore - ); + const [allVideos, setAllVideos] = useState([]); + const [selectVideo, setSelectVideo] = useState(); + const { primaryColor, isDarkMode } = useAppSelector((store) => store.colors); const getAllVideos = useCallback(async () => { const response = await axios.get( @@ -36,14 +33,8 @@ const StreamsAbout: React.FC = ({ purchaseButton }) => { Test our streams
    -
    -
    +
    +

    You’ll need Metamask and a watch token to play our encrypted streams. To stream the videos below you’ll need to mint diff --git a/rair-front/src/components/AboutPage/AboutPageNew/aboutPage.types.ts b/rair-front/src/components/AboutPage/AboutPageNew/aboutPage.types.ts index 996355ef1..c676ebd9d 100644 --- a/rair-front/src/components/AboutPage/AboutPageNew/aboutPage.types.ts +++ b/rair-front/src/components/AboutPage/AboutPageNew/aboutPage.types.ts @@ -1,14 +1,7 @@ import { ReactNode } from 'react'; -export interface IAboutPageNew { - headerLogoBlack?: string; - headerLogoWhite?: string; - setIsSplashPage: (arg: boolean) => void; -} - export interface IMainBlock { Metamask: string; - primaryColor: string; termsText: string; purchaseButton: ReactNode; RairLogo?: string; @@ -20,19 +13,6 @@ export interface IStreamsAbout { primaryColor?: string; } -export interface IRoadMap { - primaryColor: string; - RairLogo?: string; -} - -export interface ILeftTokenAbout { - primaryColor: string; -} - -export interface IRairOffer { - primaryColor: string; -} - export interface IMobileCarouselNfts { children: ReactNode; screen?: number; diff --git a/rair-front/src/components/AlertMetamask/alertMetamask.types.ts b/rair-front/src/components/AlertMetamask/alertMetamask.types.ts index 46476c41d..3909b46cb 100644 --- a/rair-front/src/components/AlertMetamask/alertMetamask.types.ts +++ b/rair-front/src/components/AlertMetamask/alertMetamask.types.ts @@ -1,6 +1,3 @@ export interface IAlertMetamask { - selectedChain: string; - selectedChainId: BlockchainType; - realNameChain: string; setShowAlert: (value: boolean) => void; } diff --git a/rair-front/src/components/AlertMetamask/index.tsx b/rair-front/src/components/AlertMetamask/index.tsx index f304e9d26..41d37601d 100644 --- a/rair-front/src/components/AlertMetamask/index.tsx +++ b/rair-front/src/components/AlertMetamask/index.tsx @@ -1,37 +1,45 @@ -import { FC } from 'react'; -import CloseIcon from '@mui/icons-material/Close'; +import { FC, useEffect } from 'react'; +import { faTimes } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { IAlertMetamask } from './alertMetamask.types'; import { Alert } from './styles'; +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; import useWeb3Tx from '../../hooks/useWeb3Tx'; -const AlertMetamask: FC = ({ - selectedChain, - realNameChain, - selectedChainId, - setShowAlert -}) => { - const { web3Switch } = useWeb3Tx(); +const AlertMetamask: FC = ({ setShowAlert }) => { + const { web3Switch, correctBlockchain } = useWeb3Tx(); + const { requestedChain, connectedChain } = useAppSelector( + (store) => store.web3 + ); + const { getBlockchainData } = useServerSettings(); + + useEffect(() => { + if (requestedChain) { + setShowAlert(!correctBlockchain(requestedChain)); + } + }, [correctBlockchain, requestedChain, setShowAlert]); return ( Your wallet is connected to the{' '} - {selectedChain}{' '} + + {getBlockchainData(connectedChain)?.name} + {' '} network. Please switch to{' '} web3Switch(selectedChainId)}> - {realNameChain} + onClick={() => web3Switch(requestedChain)}> + {getBlockchainData(requestedChain)?.name} {' '} network - setShowAlert(false)}> - - + ); }; diff --git a/rair-front/src/components/ConsumerMode/BatchMinting.tsx b/rair-front/src/components/ConsumerMode/BatchMinting.tsx index 8a200679a..2bc4b88f7 100644 --- a/rair-front/src/components/ConsumerMode/BatchMinting.tsx +++ b/rair-front/src/components/ConsumerMode/BatchMinting.tsx @@ -1,8 +1,7 @@ import React, { ChangeEvent, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import { faPlus, faTrash } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { BigNumber, utils } from 'ethers'; +import { formatEther } from 'ethers'; import { IBatchMinting, @@ -10,9 +9,8 @@ import { TBatchMintingItem } from './consumerMode.types'; -import { RootState } from '../../ducks'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; -import useServerSettings from '../adminViews/useServerSettings'; +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; const BatchRow: React.FC = ({ index, deleter, array }) => { const [address, setAddress] = useState(); @@ -71,9 +69,7 @@ const BatchMinting: React.FC = ({ }) => { const [rows, setRows] = useState([]); - const { currentChain } = useSelector( - (store) => store.contractStore - ); + const { connectedChain } = useAppSelector((store) => store.web3); const { getBlockchainData } = useServerSettings(); @@ -108,12 +104,10 @@ const BatchMinting: React.FC = ({

    = ({ const [batchArray, setBatchArray] = useState([]); const [rerender, setRerender] = useState(false); - const { primaryButtonColor, textColor, secondaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { primaryButtonColor, textColor, secondaryButtonColor } = + useAppSelector((store) => store.colors); const addRecipient = () => { if (batchArray.length >= +max) { @@ -118,10 +115,9 @@ const BatchTokenSelector: React.FC = ({ const TokenSelector: React.FC = ({ buyCall, max, min }) => { const [tokenId, setTokenId] = useState(min); - const { textColor, secondaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { textColor, secondaryButtonColor } = useAppSelector( + (store) => store.colors + ); return (
    @@ -161,10 +157,8 @@ const DiamondMarketplace = () => { useState(false); const [treasuryAddress, setTreasuryAddress] = useState(); - const { diamondMarketplaceInstance, contractCreator, currentChain } = - useSelector( - (store) => store.contractStore - ); + const { connectedChain } = useAppSelector((store) => store.web3); + const { diamondMarketplaceInstance, contractCreator } = useContracts(); const reactSwal = useSwal(); const { web3TxHandler } = useWeb3Tx(); @@ -178,7 +172,7 @@ const DiamondMarketplace = () => { textColor, secondaryButtonColor, primaryButtonColor - } = useSelector((store) => store.colorStore); + } = useAppSelector((store) => store.colors); const fetchDiamondData = useCallback(async () => { if (!diamondMarketplaceInstance) { @@ -217,7 +211,7 @@ const DiamondMarketplace = () => { const mintTokenCall = async ( offerIndex: string, nextToken: string, - price: BigNumber + price: bigint ) => { //setTransactionInProgress(true); reactSwal.fire({ @@ -258,7 +252,7 @@ const DiamondMarketplace = () => { offerIndex: string, tokens: number[], addresses: string[], - price: BigNumber + price: bigint ) => { if (!diamondMarketplaceInstance) { return; @@ -276,7 +270,7 @@ const DiamondMarketplace = () => { tokens, addresses, { - value: price.mul(tokens.length) + value: BigInt(price.toString()) * BigInt(tokens.length) } ]) ) { @@ -301,7 +295,7 @@ const DiamondMarketplace = () => { ? 'Loading data, please wait...' : `${offersArray.length} offers found.`}
    - {treasuryAddress === constants.AddressZero && ( + {treasuryAddress === ZeroAddress && ( - - {start && allowed && end && ( - - )} - {allowed} tokens left! - {allowed && Number(allowed) !== 0 && ( - <> - -
    - Mint a specific token! - setSpecificIndex(+e.target.value)} - /> -
    - -
    -
    - - )} -
    -
    -
    - ); -}; - -const ERC721Manager: React.FC = ({ - offerInfo, - index, - width = 6 -}) => { - const [balance, setBalance] = useState(); - const [productName, setProductName] = useState(); - const [contractName, setContractName] = useState(); - const [rangeInfo, setRangeInfo] = useState([]); - const [refetchingFlag, setRefetchingFlag] = useState(false); - - const { minterInstance, currentUserAddress } = useSelector< - RootState, - ContractsInitialType - >((state) => state.contractStore); - - const refreshData = useCallback(async () => { - if (!offerInfo.instance) { - return; - } - setRefetchingFlag(true); - const balances: TBalanceInfo[] = []; - const tokensOwned = ( - await offerInfo.instance.balanceOf(currentUserAddress) - ).toString(); - setProductName( - (await offerInfo.instance.getProduct(offerInfo.productIndex)).productName - ); - setContractName(await offerInfo.instance?.name()); - const ranges: TRangeInfo[] = []; - for await (const rangeIndex of [ - // eslint-disable-next-line - ...Array.apply(null, { - length: offerInfo.ranges - }).keys() - ]) { - const data = await minterInstance?.getOfferRangeInfo(index, rangeIndex); - ranges.push({ - name: data.name, - price: data.price.toString(), - start: data.tokenStart.toString(), - end: data.tokenEnd.toString(), - allowed: data.tokensAllowed.toString() - }); - } - setRangeInfo(ranges); - if (tokensOwned > 0) { - for await (const index of [ - // eslint-disable-next-line - ...Array.apply(null, { - length: tokensOwned - }).keys() - ]) { - const token = ( - await offerInfo.instance.tokenOfOwnerByIndex( - currentUserAddress, - index - ) - ).toString(); - if ( - (await offerInfo.instance.tokenToProduct(token)).toString() === - offerInfo.productIndex - ) { - balances.push({ - token, - internalIndex: ( - await offerInfo.instance.tokenToProductIndex(token) - ).toString() - }); - } - } - } - setBalance(balances); - setRefetchingFlag(false); - }, [ - currentUserAddress, - index, - minterInstance, - offerInfo.instance, - offerInfo.productIndex, - offerInfo.ranges - ]); - - useEffect(() => { - refreshData(); - }, [offerInfo, currentUserAddress, refreshData]); - - return ( -
    - -
    - #{index + 1} -
    -
    -
    {productName}
    - - @{contractName} - -
    - - - Contract Address: {offerInfo.contractAddress} - -
    - Product Index: {offerInfo.productIndex} -
    -
    - {rangeInfo.map((item, rangeIndex) => { - return ( - - ); - })} -
    - {balance && ( - <> - You own {balance.length} tokens from this collection -
    - {balance.map((item, index) => ( -
    - -
    {item.internalIndex}
    -
    - {offerInfo.contractAddress}:{item.token} -
    -
    - -
    - -
    -
    -
    - ))} - - )} -
    -
    -
    - ); -}; - -export default ERC721Manager; diff --git a/rair-front/src/components/ConsumerMode/consumerMode.types.ts b/rair-front/src/components/ConsumerMode/consumerMode.types.ts index 8d682f45f..66dfc7b39 100644 --- a/rair-front/src/components/ConsumerMode/consumerMode.types.ts +++ b/rair-front/src/components/ConsumerMode/consumerMode.types.ts @@ -1,4 +1,5 @@ -import { BigNumber, ethers } from 'ethers'; +import { ethers } from 'ethers'; +import { Hex } from 'viem'; export interface IBatchRow { index: number; @@ -59,13 +60,13 @@ export type TRangeInfo = { }; export type TOffersArrayItem = { - contractAddress: string; + contractAddress: Hex; endingToken: string; lockedTokens: string; mintableTokens: string; name: string; offerIndex: string; - price: BigNumber; + price: bigint; productIndex: string; rangeIndex: string; startingToken: string; diff --git a/rair-front/src/components/CreatorMode/CollectionManager.tsx b/rair-front/src/components/CreatorMode/CollectionManager.tsx deleted file mode 100644 index ff1c66411..000000000 --- a/rair-front/src/components/CreatorMode/CollectionManager.tsx +++ /dev/null @@ -1,599 +0,0 @@ -import React, { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; -import { - faArrowUp, - faLock, - faPlus, - faTrash -} from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { utils } from 'ethers'; - -import { - IExistingLock, - IProductManager, - IRangeManager, - IRangesType -} from './creatorMode.types'; - -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; -import useSwal from '../../hooks/useSwal'; -import useWeb3Tx from '../../hooks/useWeb3Tx'; - -const RangeManager: React.FC = ({ - disabled, - index, - array, - deleter, - sync, - hardLimit, - locker, - productIndex, - updater, - offerIndex -}) => { - const [endingRange, setEndingRange] = useState( - disabled - ? array[index].endingToken - : index === 0 - ? 0 - : Number(array[index - 1].endingToken) + 1 - ); - const [rangeName, setRangeName] = useState(array[index].name); - const [rangePrice, setRangePrice] = useState(array[index].price); - const syncOutside = useCallback(sync, [sync]); - const rangeInit = index === 0 ? 0 : Number(array[index - 1].endingToken) + 1; - const [locked, setLocked] = useState(0); - const { primaryButtonColor, textColor, secondaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); - - useEffect(() => { - const aux = array[index].endingToken !== endingRange; - array[index].endingToken = endingRange; - if (aux) { - syncOutside(); - } - }, [endingRange, array, index, syncOutside]); - - useEffect(() => { - const aux = array[index].name !== rangeName; - array[index].name = rangeName; - if (aux) { - syncOutside(); - } - }, [rangeName, array, index, syncOutside]); - - useEffect(() => { - const aux = array[index].price !== rangePrice; - array[index].price = rangePrice; - if (aux) { - syncOutside(); - } - }, [rangePrice, array, index, syncOutside]); - - const prevLastIndex = - index === 0 ? 0 : Number(array[index - 1].endingToken + 1); - - return ( - <> - - - {!disabled ? ( - - ) : ( - '' - )} - - #{index + 1} - - setRangeName(e.target.value)} - /> - - - - - - endingRange || - endingRange > hardLimit - ? { - backgroundColor: 'red', - color: 'white' - } - : {} - } - disabled={disabled} - className="form-control" - type="number" - min={index === 0 ? 0 : Number(array[index - 1].endingToken) + 1} - max={hardLimit} - value={endingRange} - onChange={(e) => setEndingRange(Number(e.target.value))} - /> - - - setRangePrice(e.target.value)} - /> - - - - - - setLocked(+e.target.value)} - /> - - - - - - - - - - - - - - {utils.formatEther(rangePrice === '' ? 0 : rangePrice).toString()}{' '} - {'ETH'} - - - - - - - ); -}; - -const ProductManager: React.FC = ({ - productIndex, - productInfo, - tokenInstance, - tokenAddress -}) => { - const { minterInstance } = useSelector( - (state) => state.contractStore - ); - const { textColor, secondaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); - - const [ranges, setRanges] = useState([]); - const [, /*locks*/ setLocks] = useState([]); - const [forceSync, setForceSync] = useState(false); - const [, /*offerIndex*/ setOfferIndex] = useState(''); - - const reactSwal = useSwal(); - const { web3TxHandler } = useWeb3Tx(); - - const deleter = (index) => { - const aux = [...ranges]; - aux.splice(index, 1); - setRanges(aux); - }; - - const locker = async ( - productIndex: number, - startingToken: number, - endingToken: number, - lockedTokens: number - ) => { - if (!tokenInstance) { - return; - } - reactSwal.fire({ - title: 'Locking tokens', - html: 'Please wait', - icon: 'info', - showConfirmButton: false - }); - if ( - await web3TxHandler(tokenInstance, 'createRangeLock', [ - productIndex, - startingToken, - endingToken, - lockedTokens - ]) - ) { - reactSwal.fire('Success', 'Tokens locked', 'success'); - } - }; - - const refresher = useCallback(async () => { - try { - // Marketplace Ranges - const offerInfo = await minterInstance?.contractToOfferRange( - tokenInstance?.address, - productIndex - ); - const offerIndex = offerInfo?.toString(); - if (offerIndex) { - setOfferIndex(offerIndex); - } - const offerData = await minterInstance?.getOfferInfo(offerIndex); - const existingRanges: IRangesType[] = []; - for await (const rangeIndex of [ - // eslint-disable-next-line - ...Array.apply(null, { - length: offerData.availableRanges.toString() - }).keys() - ]) { - const rangeInfo = await minterInstance?.getOfferRangeInfo( - offerIndex, - rangeIndex - ); - if (Number(rangeInfo.collectionIndex.toString()) === productIndex) { - existingRanges.push({ - offerIndex, - endingToken: Number(rangeInfo.tokenEnd.toString()), - name: rangeInfo.name, - price: rangeInfo.price.toString(), - disabled: true - }); - } - } - setRanges(existingRanges); - // - } catch (err) { - console.error(err); - } - - try { - // Lock Ranges - const existingLocks: IExistingLock[] = []; - for await (const lockIndex of productInfo.locks) { - const lockInfo = await tokenInstance?.getLockedRange(lockIndex); - if (Number(lockInfo.productIndex.toString()) === productIndex) { - existingLocks.push({ - startingToken: lockInfo.startingToken.toString(), - endingToken: lockInfo.endingToken.toString(), - countToUnlock: lockInfo.countToUnlock.toString(), - disabled: true - }); - } - } - setLocks(existingLocks); - } catch (err) { - const error = err as any; - console.error(error?.data?.message); - } - }, [minterInstance, productIndex, productInfo.locks, tokenInstance]); - - const notDisabled = (item) => { - return !item.disabled; - }; - - const updater = async ( - offerIndex: string | undefined, - rangeIndex: number, - startToken: number, - endToken: number, - price: string, - name: string - ) => { - if ( - !offerIndex || - !rangeIndex === undefined || - startToken === undefined || - !endToken || - !price || - !name - ) { - console.error('Update Rejected'); - return; - } - if (!minterInstance) { - return; - } - reactSwal.fire({ - title: 'Updating', - html: 'Please wait', - icon: 'info', - showConfirmButton: false - }); - if ( - await web3TxHandler(minterInstance, 'updateOfferRange', [ - offerIndex, - rangeIndex, - startToken, - endToken, - price, - name - ]) - ) { - reactSwal.fire('Success', 'Offer updated', 'success'); - } - }; - - useEffect(() => { - if (minterInstance) { - minterInstance.on( - 'AppendedRange(address,uint256,uint256,uint256,uint256,uint256,uint256,string)', - refresher - ); - } - return () => { - minterInstance?.off( - 'AppendedRange(address,uint256,uint256,uint256,uint256,uint256,uint256,string)', - refresher - ); - }; - }, [minterInstance, refresher]); - - useEffect(() => { - if (tokenInstance && minterInstance) { - refresher(); - } - }, [productInfo, tokenInstance, minterInstance, refresher]); - return ( -
    - - Product #{productIndex + 1}: {productInfo.name} - -
    -
    -
    Product Info
    - First token: {productInfo.startingToken} -
    - Last Token: {productInfo.endingToken} -
    - Mintable Tokens Left: {productInfo.mintableTokensLeft} -
    -
    -
    -
    - -
    On the Minter Marketplace
    - - - - - - - - - - - - - - {ranges.map((item, index, array) => { - return ( - { - setForceSync(!forceSync); - }} - hardLimit={ - +productInfo.endingToken - +productInfo.startingToken - } - locker={locker} - productIndex={productIndex} - /> - ); - })} - -
    - # NameStartsEndsPrice for eachLocked Tokens
    - -
    - {/*
    - -
    Resale Locks
    - - - - - - - - - - - {locks.map((item, index, array) => { - return {setForceSync(!forceSync)}} - hardLimit={productInfo.endingToken - productInfo.startingToken} - /> - })} - -
    - # - Starts - - Ends - - Locked Tokens -
    -
    */} -
    -
    - ); -}; - -export default ProductManager; diff --git a/rair-front/src/components/CreatorMode/ERC721Manager.tsx b/rair-front/src/components/CreatorMode/ERC721Manager.tsx deleted file mode 100644 index 1e4a83086..000000000 --- a/rair-front/src/components/CreatorMode/ERC721Manager.tsx +++ /dev/null @@ -1,193 +0,0 @@ -import React, { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; -import { MultiOwnerModularAccount } from '@alchemy/aa-accounts'; -import { AccountSigner } from '@alchemy/aa-ethers'; -import { faRedo } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import * as ethers from 'ethers'; - -import ProductManager from './CollectionManager'; -import { - IERC721Manager, - ITokenInfo, - ProductInfoType -} from './creatorMode.types'; - -import { abi } from '../../contracts/RAIR_ERC721.json'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; - -const ERC721Manager: React.FC = ({ tokenAddress }) => { - const [erc721Instance, setERC721Instance] = useState< - ethers.Contract | undefined - >(); - const [tokenInfo, setTokenInfo] = useState(); - - const [minterApproved, setMinterApproved] = useState(); - const [productName, setProductName] = useState(''); - const [productLength, setProductLength] = useState(0); - const [existingProductsData /*setExistingProductsData*/] = - useState(); - const [refetchingFlag, setRefetchingFlag] = useState(false); - - const { minterInstance, currentUserAddress, programmaticProvider } = - useSelector( - (state) => state.contractStore - ); - const { textColor, secondaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); - - const refreshData = useCallback(async () => { - if (!erc721Instance) { - return; - } - setRefetchingFlag(true); - setMinterApproved( - await erc721Instance?.hasRole( - await erc721Instance.MINTER(), - minterInstance?.address - ) - ); - const tokInfo: ITokenInfo = { - name: await erc721Instance?.name(), - symbol: await erc721Instance?.symbol(), - balance: (await erc721Instance.balanceOf(currentUserAddress)).toString(), - address: erc721Instance?.address - }; - setTokenInfo(tokInfo); - setRefetchingFlag(false); - }, [erc721Instance, currentUserAddress, minterInstance?.address]); - - useEffect(() => { - if (erc721Instance) { - refreshData(); - } - }, [erc721Instance, refreshData]); - - useEffect(() => { - let signer: - | AccountSigner - | ethers.Wallet - | ethers.providers.JsonRpcSigner - | undefined = programmaticProvider; - if (window.ethereum) { - const provider = new ethers.providers.Web3Provider(window.ethereum); - signer = provider.getSigner(0); - } - const erc721 = new ethers.Contract(tokenAddress, abi, signer); - setERC721Instance(erc721); - }, [programmaticProvider, tokenAddress]); - - return ( -
    - - - ERC721 {tokenInfo && tokenInfo.name} -
    -
    -
    - Contract Address: {tokenAddress} - -
    -
    - {tokenInfo && erc721Instance ? ( -
    -
    -
    ERC721 Info
    - Name: {tokenInfo.name} -
    - Symbol: {tokenInfo.symbol} -
    -
    - Current Balance: {tokenInfo.balance} -
    -
    -
    -
    Create a new product
    - Product Name:{' '} - setProductName(e.target.value)} - /> -
    - {"Product's length"}:{' '} - setProductLength(+e.target.value)} - /> -
    - -
    - {minterApproved === false ? ( -
    - To sell your unminted products -
    - -
    - (once) -
    - ) : ( -
    - )} -
    - {existingProductsData && ( - <> -
    Existing Products
    - - {existingProductsData.map((item, index) => { - return ( - - ); - })} - - )} -
    -
    - ) : ( - <>Fetching info... - )} -
    - ); -}; - -export default ERC721Manager; diff --git a/rair-front/src/components/CreatorMode/creatorMode.types.ts b/rair-front/src/components/CreatorMode/creatorMode.types.ts deleted file mode 100644 index 5283535b5..000000000 --- a/rair-front/src/components/CreatorMode/creatorMode.types.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { ethers } from 'ethers'; - -export interface IRangeManager { - disabled?: boolean; - index: number; - array: IRangesType[]; - deleter: (index: number) => void; - sync: () => void; - hardLimit: number; - locker: ( - productIndex: number, - startingToken: number, - endingToken: number, - lockedTokens: number - ) => void; - productIndex: number; - updater: ( - offerIndex: string | undefined, - rangeIndex: number, - startToken: number, - endToken: number, - price: string, - name: string - ) => void; - offerIndex: string | undefined; -} - -export type ProductInfoType = { - name: string; - startingToken: string; - endingToken: string; - mintableTokensLeft: string; - locks: number[]; -}; - -export interface IProductManager { - productIndex: number; - productInfo: ProductInfoType; - tokenInstance: ethers.Contract | undefined; - tokenAddress: string | undefined; -} - -export interface IRangesType { - offerIndex?: string; - endingToken: number; - name: string; - price: string; - disabled?: boolean; -} - -export interface IExistingLock { - startingToken: string; - endingToken: string; - countToUnlock: string; - disabled: boolean; -} - -export interface IERC721Manager { - tokenAddress: string; -} - -export interface IColdData { - startingToken: number; - endingToken: number; - mintableTokensLeft: number; - productName: string; - locks: number[]; -} - -export interface ITokenInfo { - name: string; - symbol: string; - balance: string; - address: string | undefined; -} - -export interface IERC777Manager { - instance?: ethers.Contract | undefined; - account?: any; - factoryAddress?: string; -} - -export interface IErc777Data { - balance: string; - name: string; - symbol: string; - decimals: number; -} - -export interface IFactoryManager { - instance?: ethers.Contract | undefined; - mainTokenInstance?: ethers.Contract | undefined; - account?: any; - setDeployedTokens: (tokens: string[]) => void; -} diff --git a/rair-front/src/components/CreatorMode/erc777.tsx b/rair-front/src/components/CreatorMode/erc777.tsx deleted file mode 100644 index 59f9579de..000000000 --- a/rair-front/src/components/CreatorMode/erc777.tsx +++ /dev/null @@ -1,158 +0,0 @@ -import React, { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; -import { faRedo } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import * as ethers from 'ethers'; -import { stringToHex } from 'viem'; - -import { IErc777Data, IERC777Manager } from './creatorMode.types'; - -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; -import useSwal from '../../hooks/useSwal'; -import useWeb3Tx from '../../hooks/useWeb3Tx'; - -const ERC777Manager: React.FC = () => { - const [erc777Data, setERC777Data] = useState(); - const [targetAddress, setTargetAddress] = useState(''); - const [targetValue, setTargetValue] = useState(0); - const [refetchingFlag, setRefetchingFlag] = useState(false); - - const { mainTokenInstance, currentUserAddress } = useSelector< - RootState, - ContractsInitialType - >((state) => state.contractStore); - const { textColor, secondaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); - - const reactSwal = useSwal(); - const { web3TxHandler } = useWeb3Tx(); - - const refreshData = useCallback(async () => { - setRefetchingFlag(true); - setERC777Data({ - balance: ( - await mainTokenInstance?.balanceOf(currentUserAddress) - ).toString(), - name: await mainTokenInstance?.name(), - symbol: await mainTokenInstance?.symbol(), - decimals: await mainTokenInstance?.decimals() - }); - setRefetchingFlag(false); - }, [mainTokenInstance, currentUserAddress]); - - useEffect(() => { - if (currentUserAddress) { - refreshData(); - } - }, [refreshData, currentUserAddress]); - - return ( -
    -
    ERC777
    - ({mainTokenInstance?.address}) - -
    - {erc777Data ? ( - <> -
    - {`Your balance on the '${erc777Data.name}' Token: `} - {ethers.utils.formatEther(erc777Data.balance)} {erc777Data.symbol}{' '} -
    -
    - Transfer Tokens -
    - Transfer to Address:{' '} - setTargetAddress(e.target.value)} - /> - Amount to Transfer:{' '} - setTargetValue(+e.target.value)} - /> -
    - {String(targetValue) !== '' && targetAddress && ( - - )} -
    - {window.ethereum && ( - - )} - - ) : ( - 'Fetching info...' - )} -
    - ); -}; - -export default ERC777Manager; diff --git a/rair-front/src/components/CreatorMode/factory.tsx b/rair-front/src/components/CreatorMode/factory.tsx deleted file mode 100644 index f731d0d62..000000000 --- a/rair-front/src/components/CreatorMode/factory.tsx +++ /dev/null @@ -1,180 +0,0 @@ -import React, { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; -import { faRedo } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { BigNumber, utils } from 'ethers'; -import { stringToHex } from 'viem'; - -import { IFactoryManager } from './creatorMode.types'; - -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; -import useSwal from '../../hooks/useSwal'; -import useWeb3Tx from '../../hooks/useWeb3Tx'; - -const FactoryManager: React.FC = ({ setDeployedTokens }) => { - const [erc721Name, setERC721Name] = useState(''); - const [clientTokens, setClientTokens] = useState(); - const [tokensOwned, setTokensOwned] = useState(); - const [tokensRequired, setTokensRequired] = useState(); - const [tokenSymbol, setTokenSymbol] = useState(); - const [tokenDecimals, setTokenDecimals] = useState(); - const [refetchingFlag, setRefetchingFlag] = useState(false); - - const { mainTokenInstance, factoryInstance, currentUserAddress } = - useSelector( - (state) => state.contractStore - ); - const { textColor, secondaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); - - const reactSwal = useSwal(); - const { web3TxHandler } = useWeb3Tx(); - - const refreshData = useCallback(async () => { - setRefetchingFlag(true); - const tokenCount = - await factoryInstance?.getContractCountOf(currentUserAddress); - const tokens: string[] = []; - for (let i = 0; i < tokenCount; i++) { - tokens.push( - await factoryInstance?.ownerToContracts(currentUserAddress, i) - ); - } - setClientTokens(await mainTokenInstance?.balanceOf(currentUserAddress)); - setTokensOwned(tokenCount); - setDeployedTokens(tokens); - setTokensRequired( - await factoryInstance?.deploymentCostForERC777(mainTokenInstance?.address) - ); - setRefetchingFlag(false); - setTokenSymbol(await mainTokenInstance?.symbol()); - setTokenDecimals(await mainTokenInstance?.decimals()); - }, [ - currentUserAddress, - factoryInstance, - mainTokenInstance, - setDeployedTokens - ]); - - useEffect(() => { - if (currentUserAddress) { - refreshData(); - } - }, [factoryInstance, refreshData, currentUserAddress]); - return ( -
    -
    Factory
    - ({factoryInstance?.address}) -
    - -
    - {tokensOwned && tokensRequired && tokenDecimals ? ( - <> - You currently own {tokensOwned._hex.length} ERC721 contracts -
    -
    Deploy a new contract
    - {"New contract's name:"} - setERC721Name(e.target.value)} - /> -
    - - {tokensRequired.eq(0) && ( - <> -
    - - - )} - {clientTokens?.lt(tokensRequired) && ( - <> - {' '} -
    - Insufficient {tokenSymbol} Tokens!{' '} - - )} - - ) : ( - 'Fetching info...' - )} -
    - ); -}; - -export default FactoryManager; diff --git a/rair-front/src/components/DemoMediaUpload/DemoMediaUpload.tsx b/rair-front/src/components/DemoMediaUpload/DemoMediaUpload.tsx index 4173e9443..9b2c55d63 100644 --- a/rair-front/src/components/DemoMediaUpload/DemoMediaUpload.tsx +++ b/rair-front/src/components/DemoMediaUpload/DemoMediaUpload.tsx @@ -1,16 +1,14 @@ import React, { useCallback, useEffect, useState } from 'react'; import Dropzone from 'react-dropzone'; -import { useSelector } from 'react-redux'; import WorkflowContext from '../../contexts/CreatorWorkflowContext'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; +import { useAppSelector } from '../../hooks/useReduxHooks'; import videoIcon from '../../images/videoIcon.svg'; +import { UploadMediaFile } from '../../types/commonTypes'; import { rFetch } from '../../utils/rFetch'; import LoadingComponent from '../common/LoadingComponent'; import { TooltipBox } from '../common/Tooltip/TooltipBox'; -import { IMediaUpload, TMediaType } from '../creatorStudio/creatorStudio.types'; +import { IMediaUpload } from '../creatorStudio/creatorStudio.types'; import MediaListBox from './MediaListBox/MediaListBox'; import UploadedListBox from './UploadedListBox/UploadedListBox'; @@ -18,12 +16,8 @@ import UploadedListBox from './UploadedListBox/UploadedListBox'; import './DemoMediaUpload.css'; const MediaUpload: React.FC = () => { - const { primaryColor, textColor } = useSelector( - (store) => store.colorStore - ); - const { currentUserAddress } = useSelector( - (store) => store.contractStore - ); + const { primaryColor, textColor } = useAppSelector((store) => store.colors); + const { currentUserAddress } = useAppSelector((store) => store.web3); const selectCommonInfo = { customClass: 'form-control rounded-rair', @@ -36,7 +30,7 @@ const MediaUpload: React.FC = () => { } }; - const [mediaList, setMediaList] = useState([]); + const [mediaList, setMediaList] = useState([]); const [mediaUploadedList, setMediaUploadedList] = useState([]); const [uploadSuccess, setUploadSuccess] = useState(null); const [newUserStatus, setNewUserStatus] = useState(false); @@ -92,7 +86,7 @@ const MediaUpload: React.FC = () => { }, [currentUserAddress]); const onMediaDrop = (media) => { - let aux: TMediaType[] = [...mediaList]; + let aux = [...mediaList]; aux = aux.concat( media.map((item: File) => { return { diff --git a/rair-front/src/components/DemoMediaUpload/LinearProgressWithLabel/LinearProgressWithLabel.tsx b/rair-front/src/components/DemoMediaUpload/LinearProgressWithLabel/LinearProgressWithLabel.tsx index b68231861..0e9bd74be 100644 --- a/rair-front/src/components/DemoMediaUpload/LinearProgressWithLabel/LinearProgressWithLabel.tsx +++ b/rair-front/src/components/DemoMediaUpload/LinearProgressWithLabel/LinearProgressWithLabel.tsx @@ -1,16 +1,12 @@ -import { useSelector } from 'react-redux'; import { Box, LinearProgress, LinearProgressProps } from '@mui/material'; import Typography from '@mui/material/Typography'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; const LinearProgressWithLabel = ( props: LinearProgressProps & { value: number } ) => { - const { primaryColor } = useSelector( - (store) => store.colorStore - ); + const { primaryColor } = useAppSelector((store) => store.colors); return ( diff --git a/rair-front/src/components/DemoMediaUpload/MediaItemChange/MediaItem.styled.tsx b/rair-front/src/components/DemoMediaUpload/MediaItemChange/MediaItem.styled.tsx index 2e5c8300f..a02788849 100644 --- a/rair-front/src/components/DemoMediaUpload/MediaItemChange/MediaItem.styled.tsx +++ b/rair-front/src/components/DemoMediaUpload/MediaItemChange/MediaItem.styled.tsx @@ -1,10 +1,13 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; interface IMediaItemContainerStyled { editTitleVideo: boolean; } -export const MediaItemContainer = styled.div` +export const MediaItemContainer = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` @media screen and (max-width: 1640px) and (min-width: 1480px) { & { padding-left: ${(props) => (!props.editTitleVideo ? '4rem' : 0)}; diff --git a/rair-front/src/components/DemoMediaUpload/MediaItemChange/MediaItemChange.tsx b/rair-front/src/components/DemoMediaUpload/MediaItemChange/MediaItemChange.tsx index 3c4ce23a1..c08298745 100644 --- a/rair-front/src/components/DemoMediaUpload/MediaItemChange/MediaItemChange.tsx +++ b/rair-front/src/components/DemoMediaUpload/MediaItemChange/MediaItemChange.tsx @@ -1,5 +1,4 @@ import React, { useCallback, useState } from 'react'; -import { useSelector } from 'react-redux'; import { faCheck, faPencilAlt, @@ -9,8 +8,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { MediaItemContainer } from './MediaItem.styled'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; import { rFetch } from '../../../utils/rFetch'; import { TooltipBox } from '../../common/Tooltip/TooltipBox'; import PopUpChangeVideo from '../PopUpChangeVideo/PopUpChangeVideo'; @@ -33,9 +31,7 @@ const MediaItemChange: React.FC = ({ setUploadSuccess, beforeUpload }) => { - const { primaryColor } = useSelector( - (store) => store.colorStore - ); + const { primaryColor } = useAppSelector((store) => store.colors); const [modalIsOpen, setModalIsOpen] = useState(false); const openModal = useCallback(() => { diff --git a/rair-front/src/components/DemoMediaUpload/MediaListBox/MediaListBox.tsx b/rair-front/src/components/DemoMediaUpload/MediaListBox/MediaListBox.tsx index d51afa706..1fa060973 100644 --- a/rair-front/src/components/DemoMediaUpload/MediaListBox/MediaListBox.tsx +++ b/rair-front/src/components/DemoMediaUpload/MediaListBox/MediaListBox.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useEffect, useState } from 'react'; -import { Provider, useDispatch, useSelector, useStore } from 'react-redux'; +import { Provider, useStore } from 'react-redux'; import { faCheck, faPen, @@ -9,16 +9,11 @@ import { } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; -import { - uploadVideoEnd, - uploadVideoStart -} from '../../../ducks/uploadDemo/action'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; +import useServerSettings from '../../../hooks/useServerSettings'; import useSwal from '../../../hooks/useSwal'; import { rFetch } from '../../../utils/rFetch'; import sockets from '../../../utils/sockets'; -import useServerSettings from '../../adminViews/useServerSettings'; import InputField from '../../common/InputField'; import InputSelect from '../../common/InputSelect'; import LinearProgressWithLabel from '../LinearProgressWithLabel/LinearProgressWithLabel'; @@ -56,10 +51,8 @@ const ContractDataModal = ({ const [contractOptions, setContractOptions] = useState([]); const reactSwal = useSwal(); - const { textColor, primaryButtonColor, secondaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { textColor, primaryButtonColor, secondaryButtonColor } = + useAppSelector((store) => store.colors); const getContractData = useCallback(async () => { const request = await rFetch('/api/contracts/full?itemsPerPage=5'); @@ -74,11 +67,11 @@ const ContractDataModal = ({ const contractMapping = {}; contracts.forEach((contract) => { if (!contractMapping[contract._id]) { - contract.productArray = [contract.products]; - delete contract.products; + contract.productArray = [contract.product]; + delete contract.product; contractMapping[contract._id] = contract; } else { - contractMapping[contract._id]?.productArray.push(contract.products); + contractMapping[contract._id]?.productArray.push(contract.product); } }); setContractData(contractMapping); @@ -248,10 +241,9 @@ const BasicDataModal = ({ const [newTitle, setNewTitle] = useState(title); const [newDescription, setNewDescription] = useState(description); const [newCategory, setNewCategory] = useState(category); - const { textColor, primaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { textColor, primaryButtonColor } = useAppSelector( + (store) => store.colors + ); const reactSwal = useSwal(); return ( <> @@ -330,22 +322,22 @@ const MediaListBox: React.FC = ({ textColor, primaryButtonColor, secondaryButtonColor - } = useSelector((store) => store.colorStore); + } = useAppSelector((store) => store.colors); const store = useStore(); const reactSwal = useSwal(); - const dispatch = useDispatch(); + const dispatch = useAppDispatch(); + const { categories } = useAppSelector((store) => store.settings); const getCategories = useCallback(async () => { - const { success, categories } = await rFetch('/api/files/categories'); - if (success) { + if (categories) { setCategoryOptions( categories.map((item) => { - return { label: item.name, value: item._id }; + return { label: item.name, value: item._id! }; }) ); - setCategory(categories?.at(0)?._id); + setCategory(categories[0]._id!); } - }, []); + }, [categories]); useEffect(() => { getCategories(); @@ -367,7 +359,6 @@ const MediaListBox: React.FC = ({ setUploading(false); setUploadSuccess(true); setTimeout(() => { - dispatch(uploadVideoEnd()); rerender?.(); deleter(index); }, 3000); @@ -386,7 +377,6 @@ const MediaListBox: React.FC = ({ if (contract === 'null' || product === 'null' || offer === 'null') { return; } - dispatch(uploadVideoStart()); setUploadSuccess(false); const formData = new FormData(); @@ -441,7 +431,6 @@ const MediaListBox: React.FC = ({ contract, product, offer, - dispatch, item.file, title, description, diff --git a/rair-front/src/components/DemoMediaUpload/PopUpChangeVideo/PopUpChangeVideo.tsx b/rair-front/src/components/DemoMediaUpload/PopUpChangeVideo/PopUpChangeVideo.tsx index 4bf29aa5d..28567595d 100644 --- a/rair-front/src/components/DemoMediaUpload/PopUpChangeVideo/PopUpChangeVideo.tsx +++ b/rair-front/src/components/DemoMediaUpload/PopUpChangeVideo/PopUpChangeVideo.tsx @@ -1,12 +1,11 @@ import React, { useCallback, useEffect, useState } from 'react'; import Modal from 'react-modal'; -import { useSelector } from 'react-redux'; -import Swal from 'sweetalert2'; import { PopUpVideoChangeBox } from './PopUpChangeVideoStyled'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; +import useSwal from '../../../hooks/useSwal'; +import { CustomModalStyle } from '../../../types/commonTypes'; import { rFetch } from '../../../utils/rFetch'; import { OptionsType } from '../../common/commonTypes/InputSelectTypes.types'; import InputField from '../../common/InputField'; @@ -23,23 +22,22 @@ const PopUpChangeVideo: React.FC = ({ mediaList, index }) => { - const { primaryColor, textColor, primaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { primaryColor, textColor, primaryButtonColor } = useAppSelector( + (store) => store.colors + ); + const { categories } = useAppSelector((store) => store.settings); + const rSwal = useSwal(); const [desc, setDesc] = useState(item.description); const [title, setTitle] = useState(item.title); - const [categories, setCategories] = useState( + const [categoryList, setCategoryList] = useState( undefined ); const [itemCategory, setItemCategory] = useState(item.category); const getCategory = useCallback(async () => { - const { success, categories } = await rFetch(`/api/files/categories`); - - if (success) { - setCategories( + if (categories) { + setCategoryList( categories.map((item) => { return { id: item._id, @@ -50,13 +48,13 @@ const PopUpChangeVideo: React.FC = ({ }) ); } - }, [setCategories]); + }, [categories]); const updateVideoData = async () => { - if (beforeUpload && categories) { + if (beforeUpload && categoryList) { const choiceCategory: any = - categories && - categories.find((item: any) => item.value === itemCategory); + categoryList && + categoryList.find((item: any) => item.value === itemCategory); const newMediaList = mediaList; newMediaList[index].description = desc; @@ -72,8 +70,8 @@ const PopUpChangeVideo: React.FC = ({ closeModal(); } else { const choiceCategory: any = - categories && - categories.find((item: any) => item.value === itemCategory); + categoryList && + categoryList.find((item: any) => item.value === itemCategory); setUploadSuccess(true); @@ -92,7 +90,7 @@ const PopUpChangeVideo: React.FC = ({ }); if (request.success) { - Swal.fire('Successfully!', 'Video has been updated.', 'success'); + rSwal.fire('Successfully!', 'Video has been updated.', 'success'); closeModal(); setUploadSuccess(null); } @@ -130,7 +128,7 @@ const PopUpChangeVideo: React.FC = ({ } }; - const customStyles = { + const customStyles: CustomModalStyle = { overlay: { zIndex: '1' }, @@ -165,9 +163,10 @@ const PopUpChangeVideo: React.FC = ({ setDesc(item.description); setTitle(item.title); - if (categories && categories.length > 0) { + if (categoryList && categoryList.length > 0) { const defaultCategory: any = - categories && categories.find((el: any) => el.id === item.category); + categoryList && + categoryList.find((el: any) => el.id === item.category); if (defaultCategory) { setItemCategory(defaultCategory.value); @@ -176,7 +175,7 @@ const PopUpChangeVideo: React.FC = ({ } } } - }, [item, modalIsOpen, categories]); + }, [item, modalIsOpen, categoryList]); return (
    @@ -207,7 +206,7 @@ const PopUpChangeVideo: React.FC = ({ label="Category" getter={itemCategory} setter={setItemCategory} - options={categories} + options={categoryList} placeholder="Select a Category" {...selectCommonInfoNFT} /> diff --git a/rair-front/src/components/DemoMediaUpload/PopUpChangeVideo/PopUpChangeVideoStyled.tsx b/rair-front/src/components/DemoMediaUpload/PopUpChangeVideo/PopUpChangeVideoStyled.tsx index f28ce6c85..36f2c0d4c 100644 --- a/rair-front/src/components/DemoMediaUpload/PopUpChangeVideo/PopUpChangeVideoStyled.tsx +++ b/rair-front/src/components/DemoMediaUpload/PopUpChangeVideo/PopUpChangeVideoStyled.tsx @@ -1,10 +1,13 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; interface IPopUpVideoChangeBox { - primaryColor: string; + primaryColor?: string; } -export const PopUpVideoChangeBox = styled.div` +export const PopUpVideoChangeBox = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` width: 100%; label { diff --git a/rair-front/src/components/DemoMediaUpload/PopUpChoiceNFT/PopUpChoiceNFT.tsx b/rair-front/src/components/DemoMediaUpload/PopUpChoiceNFT/PopUpChoiceNFT.tsx index d088684f6..b78516c68 100644 --- a/rair-front/src/components/DemoMediaUpload/PopUpChoiceNFT/PopUpChoiceNFT.tsx +++ b/rair-front/src/components/DemoMediaUpload/PopUpChoiceNFT/PopUpChoiceNFT.tsx @@ -1,14 +1,11 @@ -//@ts-nocheck import React, { useCallback, useEffect, useState } from 'react'; import Modal from 'react-modal'; -import { useSelector } from 'react-redux'; -import Swal from 'sweetalert2'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../../ducks/contracts/contracts.types'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; +import useServerSettings from '../../../hooks/useServerSettings'; +import useSwal from '../../../hooks/useSwal'; +import { CustomModalStyle } from '../../../types/commonTypes'; import { rFetch } from '../../../utils/rFetch'; -import useServerSettings from '../../adminViews/useServerSettings'; import { OptionsType } from '../../common/commonTypes/InputSelectTypes.types'; import InputSelect from '../../common/InputSelect'; import { TChoiceAllOptions } from '../../creatorStudio/creatorStudio.types'; @@ -35,16 +32,16 @@ const PopUpChoiceNFT: React.FC = ({ const [offer, setOffer] = useState('null'); const [isDemo, setIsDemo] = useState(false); const { primaryColor, textColor, primaryButtonColor, secondaryButtonColor } = - useSelector((store) => store.colorStore); - const { currentUserAddress } = useSelector( - (store) => store.contractStore - ); + useAppSelector((store) => store.colors); + const { currentUserAddress } = useAppSelector((store) => store.web3); + + const rSwal = useSwal(); const { getBlockchainData } = useServerSettings(); const [contractData, setContractData] = useState({}); const [contractOptions, setContractOptions] = useState([]); - const [productOptions, setProductOptions] = useState(); + const [productOptions, setProductOptions] = useState>([]); const [offersOptions, setOffersOptions] = useState(); const [choiceAllOptions, setChoiceAllOptions] = useState(null); @@ -65,7 +62,7 @@ const PopUpChoiceNFT: React.FC = ({ } }; - const customStyles = { + const customStyles: CustomModalStyle = { overlay: { zIndex: '1' }, @@ -108,12 +105,14 @@ const PopUpChoiceNFT: React.FC = ({ const handleChoiceOffer = useCallback(async () => { if (offer && contract !== 'None' && offersOptions) { - const filteredOffers = offersOptions.filter((el) => el.value === offer); + const filteredOffers = offersOptions.filter( + (el) => el.value && el.value === offer + ); if (Array.isArray(mediaList)) { const newArray = mediaList; newArray[index].contractAddress = contract; newArray[index].productIndex = product; - newArray[index].offer = filteredOffers; + newArray[index].offer = filteredOffers[0].value!; newArray[index].demo = isDemo; setMediaList(newArray); rerender?.(); @@ -157,21 +156,23 @@ const PopUpChoiceNFT: React.FC = ({ false ); - if (!request.success) { - setMediaUploadedList({}); + if (!request.success && setMediaUploadedList) { setUploadSuccess(null); setModalIsOpen(false); if ( request.message === 'Nothing to update' || request.message === `"offer[0]" must be a string` ) { - Swal.fire('Error', 'Nothing to update', 'error'); + rSwal.fire('Error', 'Nothing to update', 'error'); } else { - Swal.fire('Error', request.message, 'error'); + rSwal.fire('Error', request.message, 'error'); } } - setMediaUploadedList({}); + if (setMediaUploadedList) { + setMediaUploadedList({}); + } + setUploadSuccess(null); setModalIsOpen(false); } @@ -179,9 +180,9 @@ const PopUpChoiceNFT: React.FC = ({ const newArray = [...mediaList]; newArray[index] = { ...newArray[index], - contractAddress: undefined, - productIndex: undefined, - offer: undefined + contractAddress: 'null', + productIndex: 'null', + offer: 'null' }; setMediaList(newArray); setChoiceAllOptions(null); @@ -244,7 +245,7 @@ const PopUpChoiceNFT: React.FC = ({ }); const mapping = {}; - const options = []; + const options: any = []; if (contractsFiltered.length === 0) { contractsFiltered = contracts.filter( (el) => @@ -271,7 +272,7 @@ const PopUpChoiceNFT: React.FC = ({ mapping[item._id] = item; options.push({ label: `${item.title} (${ - getBlockchainData(item.blockchain).symbol + getBlockchainData(item?.blockchain)?.symbol } ${ item.external ? 'External' : item.diamond ? 'Diamond' : 'Classic' })`, @@ -289,7 +290,7 @@ const PopUpChoiceNFT: React.FC = ({ setContract(options[0].value); } } - }, [address, currentUserAddress]); + }, [address, currentUserAddress, getBlockchainData]); const getOffers = useCallback(async () => { const arrOfferOption = @@ -313,7 +314,7 @@ const PopUpChoiceNFT: React.FC = ({ if (address && collectionIndex && !Array.isArray(mediaList)) { if (fileData.demo) { - setOffer(-1); + setOffer('-1'); } else { setOffer(fileData.offer[0]); } @@ -419,7 +420,6 @@ const PopUpChoiceNFT: React.FC = ({ {contractData && ( <> { @@ -433,7 +433,6 @@ const PopUpChoiceNFT: React.FC = ({ {contract !== 'null' && contract !== 'None' && ( { @@ -448,7 +447,6 @@ const PopUpChoiceNFT: React.FC = ({ {product !== 'null' && product !== 'None' && ( <> { diff --git a/rair-front/src/components/DemoMediaUpload/UploadedListBox/AnalyticsPopUp/AnalyticsPopUp.tsx b/rair-front/src/components/DemoMediaUpload/UploadedListBox/AnalyticsPopUp/AnalyticsPopUp.tsx index 1068128ff..1e415beeb 100644 --- a/rair-front/src/components/DemoMediaUpload/UploadedListBox/AnalyticsPopUp/AnalyticsPopUp.tsx +++ b/rair-front/src/components/DemoMediaUpload/UploadedListBox/AnalyticsPopUp/AnalyticsPopUp.tsx @@ -1,10 +1,8 @@ -import React, { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; +import { FC, useCallback, useEffect, useState } from 'react'; import { faEye } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { RootState } from '../../../../ducks'; -import { ColorStoreType } from '../../../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../../../hooks/useReduxHooks'; import useSwal from '../../../../hooks/useSwal'; import { rFetch } from '../../../../utils/rFetch'; @@ -14,14 +12,13 @@ interface IAnalyticsPopUp { videoId: string; } -const AnalyticsPopUp: React.FC = ({ videoId }) => { +const AnalyticsPopUp: FC = ({ videoId }) => { const reactSwal = useSwal(); const [watchCounter, setWatchCounter] = useState(0); - const { textColor, primaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { textColor, primaryButtonColor } = useAppSelector( + (store) => store.colors + ); const getCounterVideo = useCallback(async () => { if (videoId) { diff --git a/rair-front/src/components/DemoMediaUpload/UploadedListBox/UploadedListBox.tsx b/rair-front/src/components/DemoMediaUpload/UploadedListBox/UploadedListBox.tsx index 7e8815652..060514b07 100644 --- a/rair-front/src/components/DemoMediaUpload/UploadedListBox/UploadedListBox.tsx +++ b/rair-front/src/components/DemoMediaUpload/UploadedListBox/UploadedListBox.tsx @@ -1,6 +1,5 @@ import React, { useCallback, useEffect, useState } from 'react'; import Modal from 'react-modal'; -import { useSelector } from 'react-redux'; import { faCheck, faLock, @@ -9,9 +8,9 @@ import { } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; import useSwal from '../../../hooks/useSwal'; +import { CustomModalStyle } from '../../../types/commonTypes'; import { copyEmbebed } from '../../../utils/copyEmbed'; import { rFetch } from '../../../utils/rFetch'; import { TooltipBox } from '../../common/Tooltip/TooltipBox'; @@ -32,10 +31,8 @@ const UploadedListBox: React.FC = ({ getMediaList, setUploadSuccess }) => { - const { primaryColor, textColor, primaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { primaryColor, textColor, primaryButtonColor, isDarkMode } = + useAppSelector((store) => store.colors); const rSwal = useSwal(); const [openVideoplayer, setOpenVideoplayer] = useState(false); @@ -44,7 +41,7 @@ const UploadedListBox: React.FC = ({ const [editTitleVideo, setEditTitleVideo] = useState(false); const [currentContract, setCurrentContract] = useState(null); - const customStyles = { + const customStyles: CustomModalStyle = { overlay: { zIndex: '1' }, @@ -213,20 +210,20 @@ const UploadedListBox: React.FC = ({ ) : openVideoplayer ? ( ) : ( - <> + fileData.staticThumbnail && ( setOpenVideoplayer(true)} className={'modal-content-play-image'} src={playImagesColored} alt="Button play video" /> - + ) )} - {openVideoplayer ? ( + {openVideoplayer || !fileData.staticThumbnail ? ( <> ) : ( Modal content video thumbnail @@ -236,7 +233,7 @@ const UploadedListBox: React.FC = ({
    + isDarkMode={isDarkMode}> void; + item: MediaFile; + setMediaList: (arg: UploadMediaFile[]) => void; index: number; - mediaList: TMediaType[]; + mediaList: UploadMediaFile[]; uploadSuccess: null | boolean; textFlag?: boolean; mediaId?: string; @@ -18,7 +19,7 @@ export interface IMediaItemChange { export interface IMediaListBox { index: number; - item: TMediaType; + item: UploadMediaFile; newUserStatus: boolean; selectCommonInfo: any; deleter: (index: number) => void; @@ -28,8 +29,8 @@ export interface IMediaListBox { export interface IUploadedListBox { fileData: any; index: number; - setMediaList: (arg: TMediaType[]) => void; - mediaList: TMediaType[]; + setMediaList: (arg: UploadMediaFile[]) => void; + mediaList: UploadMediaFile[]; uploadSuccess: boolean | null; getMediaList: () => void; setUploadSuccess: (arg: boolean | null) => void; @@ -39,8 +40,8 @@ export interface IUploadedListBox { } export interface IAnalyticsPopUp { index: number; - setMediaList: (arg: TMediaType[]) => void; - mediaList: TMediaType[]; + setMediaList: (arg: UploadMediaFile[]) => void; + mediaList: UploadMediaFile[]; setUploadSuccess: (arg: boolean | null) => void; titleOfContract?: any | undefined; selectCommonInfo?: any; @@ -57,7 +58,7 @@ export interface IPopUpChangeVideo { item: any; setUploadSuccess: (arg: boolean | null) => void; beforeUpload: boolean | undefined; - setMediaList: (arg: TMediaType[]) => void; - mediaList: TMediaType[]; + setMediaList: (arg: UploadMediaFile[]) => void; + mediaList: UploadMediaFile[]; index: number; } diff --git a/rair-front/src/components/Dropdown/Dropdown.tsx b/rair-front/src/components/Dropdown/Dropdown.tsx index e3d702156..91aa1d3dd 100644 --- a/rair-front/src/components/Dropdown/Dropdown.tsx +++ b/rair-front/src/components/Dropdown/Dropdown.tsx @@ -1,5 +1,3 @@ -import useServerSettings from '../adminViews/useServerSettings'; - import { TDropdownProps } from '.'; import './styles.css'; @@ -10,24 +8,17 @@ const Dropdown = ({ selectedOptions, isMobileDesign }: TDropdownProps) => { - const { getBlockchainData } = useServerSettings(); - return (
      - {options?.map((option, idx) => { + {options?.map((option, index) => { // logic for multiple select - const isChecked = !!selectedOptions?.find( - (selectedOption) => selectedOption?.optionId === option.optionId - ); + const isChecked = selectedOptions.includes(option.optionId); if (option?.display !== false) { return ( -
    • +
    • {option?.dropDownImg && (
      @@ -35,26 +26,20 @@ const Dropdown = ({ className={`dropdownn-chain-icons ${ isMobileDesign ? 'mobile-chain-icons' : '' }`} - src={`${ - option?.chainId && - getBlockchainData(option?.chainId as `0x${string}`) - ?.image - }`} + src={option.dropDownImg} alt="blockchain-img" - key={idx + Math.random() * 1_000_000} />
      )} {dropdownIMG} -
      - + + { + onDropdownChange(option.optionId); + }} checked={isChecked} />
      diff --git a/rair-front/src/components/Dropdown/index.ts b/rair-front/src/components/Dropdown/index.ts index d52d58c02..f92bbbb28 100644 --- a/rair-front/src/components/Dropdown/index.ts +++ b/rair-front/src/components/Dropdown/index.ts @@ -1,15 +1,18 @@ export type TOption = { - name?: string; + optionId: string; + display?: boolean; + dropDownImg?: string; + name: string; + chainId?: string; clicked?: boolean; - dropDownImg?: boolean; - optionId?: number; - display?: boolean; + categoryId?: string; }; + export type TDropdownProps = { options: Array; - onDropdownChange: (ev: React.SyntheticEvent) => void; + onDropdownChange: (value: string) => void; dropdownIMG?: React.ReactNode; - selectedOptions: Array; + selectedOptions: Array; isMobileDesign?: boolean; }; diff --git a/rair-front/src/components/Footer/Footer.tsx b/rair-front/src/components/Footer/Footer.tsx index f4240b593..d3d881a31 100644 --- a/rair-front/src/components/Footer/Footer.tsx +++ b/rair-front/src/components/Footer/Footer.tsx @@ -1,20 +1,12 @@ -import React, { useState } from 'react'; -import { useSelector } from 'react-redux'; +import { FC, useState } from 'react'; import { NavLink } from 'react-router-dom'; -import Swal from 'sweetalert2'; import { IFooter } from './footer.types'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { DiscordIcon, TelegramIcon, TwitterIcon } from '../../images'; -import { SocialBox } from '../../styled-components/SocialLinkIcons/SocialLinkIcons'; -import useServerSettings from '../adminViews/useServerSettings'; +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useSwal from '../../hooks/useSwal'; import { - CommunityBlock, - CommunityBoxFooter, - FooterEmailBlock, FooterImage, FooterMain, FooterTextRairTech, @@ -23,22 +15,24 @@ import { NavFooterBox } from './FooterItems/FooterItems'; -const Footer: React.FC = () => { +const Footer: FC = () => { const [emailChimp, setEmailChimp] = useState(''); - const { footerLinks, legal } = useServerSettings(); + const { footerLinks, legal } = useAppSelector((store) => store.settings); const hotdropsVar = import.meta.env.VITE_TESTNET; - const { headerLogo, primaryColor, textColor, secondaryColor } = - useSelector((store) => store.colorStore); + const rSwal = useSwal(); + + const { headerLogo, primaryColor, textColor, secondaryColor, isDarkMode } = + useAppSelector((store) => store.colors); const onChangeEmail = (e) => { setEmailChimp(e.target.value); }; const onSubmit = () => { - Swal.fire( + rSwal.fire( 'Success', `Thank you for sign up! Check to your email ${emailChimp}`, 'success' @@ -51,10 +45,10 @@ const Footer: React.FC = () => { return ( + secondaryColor={secondaryColor}> diff --git a/rair-front/src/components/Footer/FooterItems/FooterItems.tsx b/rair-front/src/components/Footer/FooterItems/FooterItems.tsx index eb0305402..24b19660d 100644 --- a/rair-front/src/components/Footer/FooterItems/FooterItems.tsx +++ b/rair-front/src/components/Footer/FooterItems/FooterItems.tsx @@ -1,26 +1,28 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; type TFooterMainStyled = { - primaryColor: string; + primaryColor?: string; + isDarkMode?: boolean; messageAlert?: string; hotdrops?: string; textColor?: any; secondaryColor?: string; }; -export const FooterMain = styled.footer` - background: ${(props) => - props.primaryColor === '#dedede' - ? '#fff' - : `color-mix(in srgb, ${props.secondaryColor}, #888888)`}; +export const FooterMain = styled.footer.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` + background: ${({ isDarkMode, secondaryColor }) => + !isDarkMode ? '#fff' : `color-mix(in srgb, ${secondaryColor}, #888888)`}; padding: 40px 120px 25px 120px; color: ${(props) => props.textColor}; border-top: 1px solid - ${(props) => (props.primaryColor === 'rhyno' ? '#E5E5E5' : '#595959')}; + ${({ isDarkMode }) => (!isDarkMode ? '#E5E5E5' : '#595959')}; a { - color: ${(props) => props.textColor}; + color: ${({ textColor }) => textColor}; } @media screen and (max-width: 1024px) { @@ -32,7 +34,9 @@ export const FooterMain = styled.footer` } `; -export const FooterWrapper = styled.div` +export const FooterWrapper = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` display: flex; justify-content: space-between; align-items: flex-start; @@ -89,7 +93,9 @@ export const FooterImage = styled.div` export const FooterBoxJoin = styled.div``; -export const CommunityBlock = styled.div` +export const CommunityBlock = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` .community-text { color: ${(props) => props.primaryColor === '#dedede' ? '#7A797A' : '#fff'}; @@ -139,7 +145,9 @@ export const NavFooter = styled.nav` } `; -export const NavFooterBox = styled.ul` +export const NavFooterBox = styled.ul.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` list-type: none; padding-left: 5rem; @@ -195,8 +203,7 @@ export const NavFooterBox = styled.ul` } &.footer-nav-item-hotdrop h3 { - color: ${(props) => - props.primaryColor === '#dedede' ? '#7A797A' : '#fff'}; + color: ${(isDarkMode) => (!isDarkMode ? '#7A797A' : '#fff')}; text-transform: uppercase; margin-bottom: 20px; } @@ -205,14 +212,12 @@ export const NavFooterBox = styled.ul` font-size: 16px; line-height: 20px; margin-bottom: 14px; - color: ${(props) => - props.primaryColor === '#dedede' ? '#725BDB' : '#AA9DE9'}; + color: ${(isDarkMode) => (!isDarkMode ? '#725BDB' : '#AA9DE9')}; } li { font-size: 14px; - color: ${(props) => - props.primaryColor === '#dedede' ? '#7A797A' : '#fff'}; + color: ${(isDarkMode) => (!isDarkMode ? '#7A797A' : '#fff')}; justify-content: center; display: flex; } @@ -230,7 +235,9 @@ export const NavFooterBox = styled.ul` export const ListFooter = styled.ul``; -export const FooterTextRairTech = styled.div` +export const FooterTextRairTech = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` padding-top: 25px; ul { @@ -260,7 +267,9 @@ export const FooterTextRairTech = styled.div` } `; -export const FooterEmailBlock = styled.div` +export const FooterEmailBlock = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` h4 { font-size: 16px; line-height: 20px; diff --git a/rair-front/src/components/FrontPage/WelcomeHeader.tsx b/rair-front/src/components/FrontPage/WelcomeHeader.tsx index 429a30e3d..dc2e14c69 100644 --- a/rair-front/src/components/FrontPage/WelcomeHeader.tsx +++ b/rair-front/src/components/FrontPage/WelcomeHeader.tsx @@ -1,10 +1,7 @@ import { useEffect } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import { RootState } from '../../ducks'; -import { setInfoSEO } from '../../ducks/seo/actions'; -import { InitialState } from '../../ducks/seo/reducers'; -import { TInfoSeo } from '../../ducks/seo/seo.types'; +import { useAppDispatch, useAppSelector } from '../../hooks/useReduxHooks'; +import { setSEOInfo } from '../../redux/seoSlice'; import MockUpPage from '../MockUpPage/MockUpPage'; import MetaTags from '../SeoTags/MetaTags'; @@ -14,13 +11,12 @@ const WelcomeHeader = ({ setTabIndex, setIsSplashPage }) => { - const dispatch = useDispatch(); - const seo = useSelector((store) => store.seoStore); + const dispatch = useAppDispatch(); + const seo = useAppSelector((store) => store.seo); useEffect(() => { - dispatch(setInfoSEO(InitialState)); - //eslint-disable-next-line - }, []); + dispatch(setSEOInfo()); + }, [dispatch]); useEffect(() => { setIsSplashPage(false); }, [setIsSplashPage]); diff --git a/rair-front/src/components/GlobalModal/FilterModal/FilterModal.tsx b/rair-front/src/components/GlobalModal/FilterModal/FilterModal.tsx index 305c49ead..d8e1f3dd2 100644 --- a/rair-front/src/components/GlobalModal/FilterModal/FilterModal.tsx +++ b/rair-front/src/components/GlobalModal/FilterModal/FilterModal.tsx @@ -1,4 +1,3 @@ -//@ts-nocheck import { FC, useCallback, @@ -7,7 +6,7 @@ import { useRef, useState } from 'react'; -import { useSelector } from 'react-redux'; +import { Hex } from 'viem'; import { MobileCloseBtn, @@ -21,18 +20,17 @@ import { import { HomePageModalFilter } from './HomePAgeModal'; import { MobileHeaderBlock } from './MobileHeaderBlock'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; -// import { IFilterModal } from '.'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; +import useServerSettings from '../../../hooks/useServerSettings'; import { GlobalModalContext, TGlobalModalContext } from '../../../providers/ModalProvider'; import { GLOBAL_MODAL_ACTIONS } from '../../../providers/ModalProvider/actions'; -import { rFetch } from '../../../utils/rFetch'; +import { loadFrontPageCatalog } from '../../../redux/tokenSlice'; +import { loadVideoList } from '../../../redux/videoSlice'; import CustomAccordion from '../../Accordion/Accordion'; import AccordionItem from '../../Accordion/AccordionItem/AccordionItem'; -import useServerSettings from '../../adminViews/useServerSettings'; import { TOption } from '../../Dropdown'; import Dropdown from '../../Dropdown/Dropdown'; import { closeModal, openModal } from '../helpers/OnOpenModal'; @@ -40,57 +38,41 @@ import { closeModal, openModal } from '../helpers/OnOpenModal'; import './styles.css'; export type THomePageFilterModalProps = { isMobileDesign?: boolean; - className?: stirng; + className?: string; }; + const HomePageFilterModal: FC = ({ isMobileDesign, className }) => { - const { blockchainSettings } = useServerSettings(); - const blockchains = blockchainSettings.map((chain, index) => { - return { - name: chain.name, - chainId: chain.hash, - clicked: false, - dropDownImg: true, - optionId: index + 1 - }; - }); + const { blockchainSettings, categories } = useAppSelector( + (store) => store.settings + ); + const { textColor, primaryButtonColor, isDarkMode, primaryColor } = + useAppSelector((store) => store.colors); + const { getBlockchainData } = useServerSettings(); + + const [selectedBlockchains, setSelectedBlockchains] = useState>( + [] + ); + const [blockchainOptions, setBlockchainOptions] = useState>( + [] + ); + const [categoryOptions, setCategoryOptions] = useState>([]); + const [selectedCategories, setSelectedCategories] = useState>( + [] + ); - const [blockchainsArray, setBlockchainsArray] = useState(undefined); + const dispatch = useAppDispatch(); - const [categories, setCategories] = useState([]); const { globalModalState, globalModaldispatch } = useContext(GlobalModalContext); const [isBlockchainOpen, setIsBlockchainOpen] = useState(false); const isBlockchainStayExpand = useRef(false); - const [selectedBlockchainItems, setSelectedBlockchainItems] = useState< - Array - >([]); const [isCategoryOpen, setIsCategoryOpen] = useState(false); const isCategoryStayExpand = useRef(false); - const [selectedCategoriesItems, setSelectedCategories] = useState< - Array - >([]); - const { textColor, primaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); - - const { - primaryColor, - setBlockchain, - setCategory, - isBlockchainExpand, - isCategoryExpand, - selectedBchItems, - selectedCatItems, - isOpen, - clearFilter, - setFilterText, - setIsShow - } = globalModalState; + const { isBlockchainExpand, isCategoryExpand, isOpen } = globalModalState; const setIsBChOpen = () => { if (isBlockchainExpand) { @@ -128,125 +110,64 @@ const HomePageFilterModal: FC = ({ payload: { isCategoryExpand: isCategoryStayExpand.current } }); }; + useEffect(() => { - if (selectedBchItems) { - setSelectedBlockchainItems(selectedBchItems); - const selectedFiltersItemsText = selectedBchItems.map( - (selectedBchItem) => selectedBchItem.name + if (blockchainSettings) { + const filteredblockchainSettings: Array = blockchainSettings.map( + (chain) => { + const chainData = getBlockchainData(chain.hash); + return { + optionId: chain.hash, + display: chain.display, + dropDownImg: chainData?.image, + name: chain.name + }; + } ); - setFilterText(selectedFiltersItemsText); - setIsShow(true); + setBlockchainOptions(filteredblockchainSettings); } - }, [selectedBchItems, setFilterText, setIsShow]); + }, [blockchainSettings, getBlockchainData]); useEffect(() => { - if (blockchainSettings) { - const filteredblockchainSettings = blockchainSettings.map((item) => { + if (categories) { + const options = categories.map((category) => { return { - ...item, - display: item.sync + name: category.name, + optionId: category._id! }; }); - setBlockchainsArray(filteredblockchainSettings); + setCategoryOptions(options); } - }, [blockchainSettings]); + }, [categories]); - useEffect(() => { - if (selectedCatItems) { - setSelectedCategories(selectedCatItems); - /*const selectedFiltersItemsText = selectedCatItems.map( - (selectedCatItem) => selectedCatItem.name - );*/ - // setFilterText(selectedFiltersItemsText); - setIsShow(true); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [selectedCatItems]); - - const onOptionChange = (ev: React.SyntheticEvent) => { - const target = ev.target as HTMLInputElement; - const selectedItemDataTitle = target.getAttribute('data-title'); - const selectedOptionId = Number(target?.value); - if (selectedItemDataTitle === 'blockchain') { - const selectedOption = blockchains?.find( - (option) => option?.optionId === selectedOptionId - ); - if ( - selectedBchItems?.filter( - (selectedBchItem) => selectedBchItem?.optionId === selectedOptionId - ).length - ) { - const selectedBchItems = selectedBlockchainItems?.filter( - (selectedItem) => selectedItem?.optionId !== selectedOptionId - ); - globalModaldispatch({ - type: GLOBAL_MODAL_ACTIONS.UPDATE_MODAL, - payload: { selectedBchItems } - }); - return setSelectedBlockchainItems(selectedBchItems); + const checkBlockchain = useCallback( + (value: string) => { + const aux = [...selectedBlockchains]; + const index = aux.findIndex((chain) => chain === value); + if (index === -1) { + aux.push(value as Hex); } else { - if (selectedBchItems) { - setSelectedBlockchainItems([...selectedBchItems, selectedOption]); - globalModaldispatch({ - type: GLOBAL_MODAL_ACTIONS.UPDATE_MODAL, - payload: { - selectedBchItems: [...selectedBchItems, selectedOption] - } - }); - return; - } - setSelectedBlockchainItems((prevBchArray) => { - return [...prevBchArray, selectedOption]; - }); - globalModaldispatch({ - type: GLOBAL_MODAL_ACTIONS.UPDATE_MODAL, - payload: { - selectedBchItems: [...selectedBlockchainItems, selectedOption] - } - }); + aux.splice(index, 1); } - } - if (selectedItemDataTitle === 'category') { - const selectedOption = categories?.find( - (option) => option?.optionId === selectedOptionId - ); - if ( - selectedCatItems?.filter( - (selectedCatItem) => selectedCatItem?.optionId === selectedOptionId - ).length - ) { - const selectedCatItems = selectedCategoriesItems?.filter( - (selectedItem) => selectedItem?.optionId !== selectedOptionId - ); - globalModaldispatch({ - type: GLOBAL_MODAL_ACTIONS.UPDATE_MODAL, - payload: { selectedCatItems } - }); - return setSelectedCategories(selectedCatItems); + setSelectedBlockchains(aux); + }, + [selectedBlockchains] + ); + + const checkCategory = useCallback( + (value: string) => { + const aux = [...selectedCategories]; + const index = aux.findIndex((category) => category === value); + if (index === -1) { + aux.push(value as Hex); } else { - // let catArray; - if (selectedCatItems) { - setSelectedCategories([...selectedCatItems, selectedOption]); - globalModaldispatch({ - type: GLOBAL_MODAL_ACTIONS.UPDATE_MODAL, - payload: { - selectedCatItems: [...selectedCatItems, selectedOption] - } - }); - return; - } - setSelectedCategories((prevArray) => { - return [...prevArray, selectedOption]; - }); - globalModaldispatch({ - type: GLOBAL_MODAL_ACTIONS.UPDATE_MODAL, - payload: { - selectedCatItems: [...selectedCategoriesItems, selectedOption] - } - }); + aux.splice(index, 1); } - } - }; + setSelectedCategories(aux); + }, + [selectedCategories] + ); + const onScrollChange = useCallback(() => { if (isMobileDesign && isOpen) { document.body.style.overflow = 'hidden'; @@ -254,6 +175,7 @@ const HomePageFilterModal: FC = ({ document.body.style.overflow = 'unset'; } }, [isMobileDesign, isOpen]); + const onCloseBtn = useCallback(() => { if (isMobileDesign) { globalModaldispatch({ @@ -264,168 +186,51 @@ const HomePageFilterModal: FC = ({ document.body.style.overflow = 'unset'; } }, [globalModaldispatch, onScrollChange, isMobileDesign]); - const onFilterApply = useCallback( - ( - selectedBch: [TOption | undefined], - selectedCategories: [TOption | undefined] | undefined = undefined - ) => { - if (selectedBch) { - sessionStorage.setItem('BlockchainItems', JSON.stringify(selectedBch)); - let allSelectedChains = ''; - selectedBch.forEach((selectedBchItem, idx) => { - if (selectedBch.length > 1 && selectedBchItem?.chainId) { - if (selectedBch.length - 1 === idx) { - allSelectedChains = allSelectedChains.concat( - selectedBchItem?.chainId - ); - return; - } - allSelectedChains = allSelectedChains.concat( - selectedBchItem?.chainId, - ',' - ); - return; - } - if (selectedBchItem?.chainId) { - allSelectedChains = allSelectedChains.concat( - selectedBchItem?.chainId - ); - return; - } - }); - setBlockchain(allSelectedChains); + + const applyFilters = useCallback( + (selectedBlockchains: Array, selectedCategories: Array) => { + if (selectedBlockchains) { + sessionStorage.setItem( + 'BlockchainItems', + JSON.stringify(selectedBlockchains) + ); } if (selectedCategories) { sessionStorage.setItem( 'CategoryItems', JSON.stringify(selectedCategories) ); - let allSelectedCategories = ''; - selectedCategories.forEach((selectedCategItem, idx) => { - if (selectedCategories.length > 1 && selectedCategItem?.categoryId) { - if (selectedCategories.length - 1 === idx) { - allSelectedCategories = allSelectedCategories.concat( - selectedCategItem?.categoryId - ); - return; - } - allSelectedCategories = allSelectedCategories.concat( - selectedCategItem?.categoryId, - ',' - ); - return; - } - if (selectedCategItem?.categoryId) { - allSelectedCategories = allSelectedCategories.concat( - selectedCategItem?.categoryId - ); - return; - } - }); - - const catArray = allSelectedCategories - .split(',') - .map((el) => { - return `&category[]=${el}`; - }) - .join(''); - if (catArray === '&category[]=') { - setCategory(undefined); - } else { - setCategory(catArray); - } } + dispatch( + loadFrontPageCatalog({ + categories: selectedCategories, + blockchains: selectedBlockchains + }) + ); + dispatch( + loadVideoList({ + blockchain: selectedBlockchains, + category: selectedCategories + }) + ); onCloseBtn(); closeModal(); - // setCategories(selectedCategories[0]); }, - [onCloseBtn, setBlockchain, setCategory] + [dispatch, onCloseBtn] ); - const returnOption = useCallback(() => { - if (sessionStorage.getItem('CategoryItems')) { - const arr = JSON.parse(sessionStorage.getItem('CategoryItems')); - - if (arr.length > 0) { - globalModaldispatch({ - type: GLOBAL_MODAL_ACTIONS.UPDATE_MODAL, - payload: { - selectedCatItems: arr - } - }); - let allSelectedCategories = ''; - arr.forEach((selectedCategItem, idx) => { - if (arr.length > 1 && selectedCategItem?.categoryId) { - if (arr.length - 1 === idx) { - allSelectedCategories = allSelectedCategories.concat( - selectedCategItem?.categoryId - ); - return; - } - allSelectedCategories = allSelectedCategories.concat( - selectedCategItem?.categoryId, - ',' - ); - return; - } - if (selectedCategItem?.categoryId) { - allSelectedCategories = allSelectedCategories.concat( - selectedCategItem?.categoryId - ); - return; - } - }); - - const catArray = allSelectedCategories - .split(',') - .map((el) => { - return `&category[]=${el}`; - }) - .join(''); - if (catArray === '&category[]=') { - setCategory(undefined); - } else { - setCategory(catArray); - } - setSelectedCategories(arr); - } + const loadStoredFilters = useCallback(() => { + const storedCategories = sessionStorage.getItem('CategoryItems'); + const storedBlockchains = sessionStorage.getItem('BlockchainItems'); + if (storedCategories) { + const parsedCategories = JSON.parse(storedCategories); + setSelectedCategories(parsedCategories); } - if (sessionStorage.getItem('BlockchainItems')) { - const arr = JSON.parse(sessionStorage.getItem('BlockchainItems')); - if (arr.length > 0) { - globalModaldispatch({ - type: GLOBAL_MODAL_ACTIONS.UPDATE_MODAL, - payload: { - selectedBchItems: arr - } - }); - setSelectedBlockchainItems(arr); - let allSelectedChains = ''; - arr.forEach((selectedBchItem, idx) => { - if (arr.length > 1 && selectedBchItem?.chainId) { - if (arr.length - 1 === idx) { - allSelectedChains = allSelectedChains.concat( - selectedBchItem?.chainId - ); - return; - } - allSelectedChains = allSelectedChains.concat( - selectedBchItem?.chainId, - ',' - ); - return; - } - if (selectedBchItem?.chainId) { - allSelectedChains = allSelectedChains.concat( - selectedBchItem?.chainId - ); - return; - } - }); - setBlockchain(allSelectedChains); - } + if (storedBlockchains) { + const parsedBlockchains = JSON.parse(storedBlockchains); + setSelectedBlockchains(parsedBlockchains); } - }, [globalModaldispatch, setBlockchain, setCategory]); + }, []); useEffect(() => { if (isOpen && isMobileDesign) { @@ -439,58 +244,38 @@ const HomePageFilterModal: FC = ({ useEffect(() => { globalModaldispatch({ type: GLOBAL_MODAL_ACTIONS.UPDATE_MODAL, - payload: { onFilterApply } + payload: { applyFilters } }); - }, [globalModaldispatch, onFilterApply]); + }, [globalModaldispatch, applyFilters]); + const AccordionItemBtn = (isItemOpen) => isItemOpen ? ( ) : ( ); - const handleCleanFilter = () => { - clearFilter(); + + const clearAllFilters = useCallback(() => { + setSelectedBlockchains([]); setSelectedCategories([]); sessionStorage.removeItem('CategoryItems'); sessionStorage.removeItem('BlockchainItems'); - globalModaldispatch({ - type: GLOBAL_MODAL_ACTIONS.UPDATE_MODAL, - payload: { - selectedBchItems: [], - selectedCatItems: [] - } - }); - }; - - const getCategories = useCallback(async () => { - const res = await rFetch(`/api/files/categories`); - - if (res.success) { - const categ = res.categories.map((el, index) => { - return { - name: el.name, - clicked: false, - optionId: index + 7, - categoryId: el._id - }; - }); - setCategories(categ); - } - }, [setCategories]); + dispatch(loadFrontPageCatalog({})); + dispatch(loadVideoList({})); + }, [dispatch]); useEffect(() => { - returnOption(); - }, [returnOption]); + loadStoredFilters(); + }, [loadStoredFilters]); - useEffect(() => { - getCategories(); - }, [getCategories]); return ( = ({ itemImg={ }> {categories && ( = ({ isStayExpand={isBlockchainExpand} itemImg={ }> - {blockchainsArray && ( + {blockchainOptions && ( )}
      Clear all
      diff --git a/rair-front/src/components/GlobalModal/FilterModal/FilterModalIcons.tsx b/rair-front/src/components/GlobalModal/FilterModal/FilterModalIcons.tsx index fc69241bd..e71d94b66 100644 --- a/rair-front/src/components/GlobalModal/FilterModal/FilterModalIcons.tsx +++ b/rair-front/src/components/GlobalModal/FilterModal/FilterModalIcons.tsx @@ -1,173 +1,204 @@ -//@ts-nocheck +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; -export const BlockchainIcon = ({ className }) => ( - - - - -); -export const CategoryIcon = ({ className }) => ( - - - -); -export const ChevronDownIcon = ({ className }) => ( - - - -); -export const ChevronUPIcon = ({ className }) => ( - - - -); -export const CategoryItemIcon = ({ className }) => ( - - - - - - -); -export const MobileCloseBtn = ({ className }) => ( - - - -); +import { useAppSelector } from '../../../hooks/useReduxHooks'; +interface customColor { + isDarkMode: boolean; + primaryColor?: string; +} +export const BlockchainIcon = ({ className }) => { + const { primaryColor } = useAppSelector((store) => store.colors); + return ( + + + + + ); +}; +export const CategoryIcon = ({ className }) => { + const { primaryColor } = useAppSelector((store) => store.colors); + + return ( + + + + ); +}; +export const ChevronDownIcon = ({ className }) => { + const { primaryColor } = useAppSelector((store) => store.colors); + return ( + + + + ); +}; +export const ChevronUPIcon = ({ className }) => { + const { primaryColor } = useAppSelector((store) => store.colors); + return ( + + + + ); +}; +export const CategoryItemIcon = ({ className }) => { + const { primaryColor } = useAppSelector((store) => store.colors); + return ( + + + + + + + ); +}; + +export const MobileCloseBtn = ({ className }) => { + return ( + + + + ); +}; -export const StyledBlockchainIcon = styled(BlockchainIcon)` - stroke: ${(props) => - props.primaryColor.includes('rhyno') +export const StyledBlockchainIcon = styled(BlockchainIcon).withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` + stroke: ${({ isDarkMode, primaryColor }) => + !isDarkMode ? 'var(--rhyno-40)' - : `color-mix(in srgb, ${props.primaryColor} 20%, #aaaaaa)`}; + : `color-mix(in srgb, ${primaryColor} 20%, #aaaaaa)`}; `; -export const StyledCategoryIcon = styled(CategoryIcon)` - stroke: ${(props) => - props.primaryColor.includes('rhyno') +export const StyledCategoryIcon = styled(CategoryIcon).withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` + stroke: ${({ isDarkMode, primaryColor }) => + !isDarkMode ? 'var(--rhyno-40)' - : `color-mix(in srgb, ${props.primaryColor} 20%, #aaaaaa)`}; + : `color-mix(in srgb, ${primaryColor} 20%, #aaaaaa)`}; `; -export const StyledChevronDownIcon = styled(ChevronDownIcon)` +export const StyledChevronDownIcon = styled(ChevronDownIcon).withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` path { - stroke: ${(props) => - props.primaryColor.includes('rhyno') + stroke: ${({ isDarkMode, primaryColor }) => + !isDarkMode ? 'var(--rhyno-40)' - : `color-mix(in srgb, ${props.primaryColor} 20%, #aaaaaa)`}; + : `color-mix(in srgb, ${primaryColor} 20%, #aaaaaa)`}; } `; -export const StyledChevronUPIcon = styled(ChevronUPIcon)` +export const StyledChevronUPIcon = styled(ChevronUPIcon).withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` path { - stroke: ${(props) => - props.primaryColor.includes('rhyno') + stroke: ${({ isDarkMode, primaryColor }) => + !isDarkMode ? 'var(--rhyno-40)' - : `color-mix(in srgb, ${props.primaryColor} 20%, #aaaaaa)`}; + : `color-mix(in srgb, ${primaryColor} 20%, #aaaaaa)`}; } `; -export const StyledCategoryItemIcon = styled(CategoryItemIcon)` +export const StyledCategoryItemIcon = styled(CategoryItemIcon).withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` path { - stroke: ${(props) => - props.primaryColor.includes('rhyno') + stroke: ${({ isDarkMode, primaryColor }) => + !isDarkMode ? 'var(--rhyno-40)' - : `color-mix(in srgb, ${props.primaryColor} 20%, #aaaaaa)`}; + : `color-mix(in srgb, ${primaryColor} 20%, #aaaaaa)`}; } `; -export const StyledClearButton = styled.button` +export const StyledClearButton = styled.button.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` background-color: var( - --${(props) => (props.primaryColor.includes('charcoal') ? 'charcoal-80' : 'rhyno')} + --${({ isDarkMode }) => (!isDarkMode ? 'charcoal-80' : 'rhyno')} ); - color: ${(props) => - props.primaryColor.includes('charcoal') ? 'white' : '#585858'}; + color: ${({ isDarkMode }) => (!isDarkMode ? 'white' : '#585858')}; `; -// export const SelectFiltersPopUp = styled.div` -// background-color: var(--${(props) => props.primaryColor}); -// z-index: 100; -// `; diff --git a/rair-front/src/components/GlobalModal/FilterModal/HomePAgeModal.tsx b/rair-front/src/components/GlobalModal/FilterModal/HomePAgeModal.tsx index 4e2d66f31..e54565388 100644 --- a/rair-front/src/components/GlobalModal/FilterModal/HomePAgeModal.tsx +++ b/rair-front/src/components/GlobalModal/FilterModal/HomePAgeModal.tsx @@ -1,4 +1,4 @@ -//@ts-nocheck +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; type THomePageModalFilter = { @@ -36,7 +36,9 @@ type THomePageModalFilter = { //`color-mix(in srgb, ${props.primaryColor}, #888888)` -export const HomePageModalFilter = styled.div` +export const HomePageModalFilter = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` @media screen and (min-width: 1100px) { &.filter-modal-wrapper.unlockables-tab { width: 384px; diff --git a/rair-front/src/components/GroupLogos/MainLogo.tsx b/rair-front/src/components/GroupLogos/MainLogo.tsx index 6914b4fcd..40f34f465 100644 --- a/rair-front/src/components/GroupLogos/MainLogo.tsx +++ b/rair-front/src/components/GroupLogos/MainLogo.tsx @@ -1,34 +1,31 @@ -import React from 'react'; -import { useSelector } from 'react-redux'; +import { FC } from 'react'; import { IMainLogo } from './mainLogo.types'; import { MainLogoContaier } from './MainLogoItems'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import useServerSettings from '../adminViews/useServerSettings'; +import { useAppSelector } from '../../hooks/useReduxHooks'; +import { dataStatuses } from '../../redux/commonTypes'; import LoadingComponent from './../common/LoadingComponent'; -const MainLogo: React.FC = ({ goHome }) => { - const { headerLogo } = useSelector( - (store) => store.colorStore - ); - const { isLoading } = useServerSettings(); +const MainLogo: FC = ({ goHome }) => { + const { headerLogo } = useAppSelector((store) => store.colors); + const { dataStatus } = useAppSelector((store) => store.settings); const hotdropsVar = import.meta.env.VITE_TESTNET; + + if (dataStatus !== dataStatuses.Complete) { + return ; + } + return ( <> - {!isLoading ? ( - goHome()} - alt="Rair Tech" - src={headerLogo} - /> - ) : ( - - )} + goHome()} + alt="Rair Tech" + src={headerLogo} + /> ); diff --git a/rair-front/src/components/GroupLogos/mainLogo.types.ts b/rair-front/src/components/GroupLogos/mainLogo.types.ts index 804c2b4df..6d4bd5d41 100644 --- a/rair-front/src/components/GroupLogos/mainLogo.types.ts +++ b/rair-front/src/components/GroupLogos/mainLogo.types.ts @@ -1,7 +1,3 @@ export interface IMainLogo { goHome: () => void; - headerLogoWhite?: string; - headerLogoBlack?: string; - headerLogo: string; - primaryColor?: string; } diff --git a/rair-front/src/components/Header/AdminPanel/AdminPanel.tsx b/rair-front/src/components/Header/AdminPanel/AdminPanel.tsx index 3931b9c6a..9fd50498a 100644 --- a/rair-front/src/components/Header/AdminPanel/AdminPanel.tsx +++ b/rair-front/src/components/Header/AdminPanel/AdminPanel.tsx @@ -1,4 +1,3 @@ -import { useSelector } from 'react-redux'; import { NavLink } from 'react-router-dom'; import Popup from 'reactjs-popup'; import { @@ -11,25 +10,18 @@ import { } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../../ducks/contracts/contracts.types'; -import { TUsersInitialState } from '../../../ducks/users/users.types'; +import useContracts from '../../../hooks/useContracts'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; import { TooltipBox } from '../../common/Tooltip/TooltipBox'; const AdminPanel = ({ creatorViewsDisabled, adminPanel, setAdminPanel }) => { - const { diamondMarketplaceInstance } = useSelector< - RootState, - ContractsInitialType - >((store) => store.contractStore); - const { adminRights, superAdmin, loggedIn } = useSelector< - RootState, - TUsersInitialState - >((store) => store.userStore); - const { primaryColor, textColor, iconColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { diamondMarketplaceInstance } = useContracts(); + const { adminRights, superAdmin, isLoggedIn } = useAppSelector( + (store) => store.user + ); + const { primaryColor, textColor, iconColor } = useAppSelector( + (store) => store.colors + ); return ( <> @@ -73,7 +65,7 @@ const AdminPanel = ({ creatorViewsDisabled, adminPanel, setAdminPanel }) => { ), route: '/admin/settings', - disabled: !loggedIn + disabled: !isLoggedIn }, { name: ( @@ -101,7 +93,7 @@ const AdminPanel = ({ creatorViewsDisabled, adminPanel, setAdminPanel }) => { ), route: '/license', - disabled: !loggedIn + disabled: !isLoggedIn }, { name: ( @@ -130,7 +122,7 @@ const AdminPanel = ({ creatorViewsDisabled, adminPanel, setAdminPanel }) => { ), route: '/admin/transferNFTs', - disabled: !loggedIn + disabled: !isLoggedIn }, { name: ( @@ -157,7 +149,7 @@ const AdminPanel = ({ creatorViewsDisabled, adminPanel, setAdminPanel }) => { ), route: '/user/videos', - disabled: !loggedIn + disabled: !isLoggedIn }, { name: ( @@ -211,7 +203,7 @@ const AdminPanel = ({ creatorViewsDisabled, adminPanel, setAdminPanel }) => { ), route: '/on-sale', - disabled: !loggedIn + disabled: !isLoggedIn } ].map((item, index) => { if (!item.disabled) { diff --git a/rair-front/src/components/Header/HeaderItems/HeaderItems.tsx b/rair-front/src/components/Header/HeaderItems/HeaderItems.tsx index 397db700b..1fb402a27 100644 --- a/rair-front/src/components/Header/HeaderItems/HeaderItems.tsx +++ b/rair-front/src/components/Header/HeaderItems/HeaderItems.tsx @@ -1,31 +1,27 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; interface IHeaderContainerStyled { - primaryColor: string; + isDarkMode: boolean; showAlert?: boolean; - selectedChain?: string | null; isSplashPage?: boolean; hotdrops?: string; realChainId?: string | undefined; secondaryColor?: string; } -export const HeaderContainer = styled.div` - background: ${(props) => - props.primaryColor === '#dedede' - ? '#fff' - : `color-mix(in srgb, ${props.secondaryColor}, #888888)`}; +export const HeaderContainer = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` + background: ${({ isDarkMode, secondaryColor }) => + !isDarkMode ? '#fff' : `color-mix(in srgb, ${secondaryColor}, #888888)`}; margin-top: ${(props) => - props.realChainId && - props.showAlert && - !props.selectedChain && - !props.isSplashPage - ? '50px' - : ''}; + props.realChainId && props.showAlert && !props.isSplashPage ? '50px' : ''}; `; -export const SocialHeaderBox = styled.div` - border: 1px solid - ${(props) => (props.primaryColor === 'rhyno' ? '#9867D9' : '#fff')}; - background: ${(props) => (props.primaryColor === 'rhyno' ? '#b2b2b2' : '')}; +export const SocialHeaderBox = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` + border: 1px solid ${({ isDarkMode }) => (!isDarkMode ? '#9867D9' : '#fff')}; + background: ${({ isDarkMode }) => (!isDarkMode ? '#b2b2b2' : '')}; `; diff --git a/rair-front/src/components/Header/HeaderItems/TalkToSalesComponent/TalkSalesButton.tsx b/rair-front/src/components/Header/HeaderItems/TalkToSalesComponent/TalkSalesButton.tsx index 80fb35431..c0a310366 100644 --- a/rair-front/src/components/Header/HeaderItems/TalkToSalesComponent/TalkSalesButton.tsx +++ b/rair-front/src/components/Header/HeaderItems/TalkToSalesComponent/TalkSalesButton.tsx @@ -1,3 +1,4 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; interface ITalkSalesButton { @@ -7,7 +8,9 @@ interface ITalkSalesButton { isAboutPage?: boolean; } -export const TalkSalesButton = styled.button` +export const TalkSalesButton = styled.button.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` position: absolute; top: ${(props) => props.currentUserAddress diff --git a/rair-front/src/components/Header/HeaderItems/TalkToSalesComponent/TalkSalesComponent.tsx b/rair-front/src/components/Header/HeaderItems/TalkToSalesComponent/TalkSalesComponent.tsx index 403b27613..53e9350e8 100644 --- a/rair-front/src/components/Header/HeaderItems/TalkToSalesComponent/TalkSalesComponent.tsx +++ b/rair-front/src/components/Header/HeaderItems/TalkToSalesComponent/TalkSalesComponent.tsx @@ -1,12 +1,9 @@ import React from 'react'; -import { Provider, useSelector, useStore } from 'react-redux'; +import { Provider, useStore } from 'react-redux'; import { TalkSalesButton } from './TalkSalesButton'; -import { RootState } from '../../../../ducks'; -import { ColorStoreType } from '../../../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../../../ducks/contracts/contracts.types'; -import { TUsersInitialState } from '../../../../ducks/users/users.types'; +import { useAppSelector } from '../../../../hooks/useReduxHooks'; import useSwal from '../../../../hooks/useSwal'; import InquiriesPage from '../../../InquiriesPage/InquiriesPage'; @@ -21,17 +18,11 @@ const TalkSalesComponent: React.FC = ({ text, isAboutPage }) => { - const { primaryColor } = useSelector( - (store) => store.colorStore - ); + const { primaryColor } = useAppSelector((store) => store.colors); - const { adminRights } = useSelector( - (store) => store.userStore - ); + const { adminRights } = useAppSelector((store) => store.user); - const { currentUserAddress } = useSelector( - (store) => store.contractStore - ); + const { currentUserAddress } = useAppSelector((store) => store.web3); const reactSwal = useSwal(); @@ -39,23 +30,14 @@ const TalkSalesComponent: React.FC = ({ const openInquiriesPage = () => { reactSwal.fire({ - title: ( -

      - {currentUserAddress ? 'Contact Us' : 'Support'} -

      - ), + title:

      {currentUserAddress ? 'Contact Us' : 'Support'}

      , html: ( ), showConfirmButton: false, - width: '85vw', - customClass: { - popup: `bg-${ - primaryColor === '#dedede' ? 'rhyno' : 'charcoal' - } rounded-rair` - } + width: '85vw' }); }; diff --git a/rair-front/src/components/Header/MainHeader.tsx b/rair-front/src/components/Header/MainHeader.tsx index 5fa8d105b..c11d3cb37 100644 --- a/rair-front/src/components/Header/MainHeader.tsx +++ b/rair-front/src/components/Header/MainHeader.tsx @@ -1,6 +1,4 @@ -//tools -import React, { memo, useCallback, useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { FC, Fragment, memo, useCallback, useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { faSearch, @@ -13,15 +11,11 @@ import axios from 'axios'; import { IMainHeader, TAxiosCollectionData } from './header.types'; import { SvgUserIcon } from '../../components/UserProfileSettings/SettingsIcons/SettingsIcons'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; -import { getDataAllClear, getDataAllStart } from '../../ducks/search/actions'; -import { TUsersInitialState } from '../../ducks/users/users.types'; import useComponentVisible from '../../hooks/useComponentVisible'; import useConnectUser from '../../hooks/useConnectUser'; -//images -import { headerLogoBlack, headerLogoWhite } from '../../images'; +import { useAppDispatch, useAppSelector } from '../../hooks/useReduxHooks'; +import { dataStatuses } from '../../redux/commonTypes'; +import { clearResults, startSearch } from '../../redux/searchbarSlice'; import { rFetch } from '../../utils/rFetch'; import InputField from '../common/InputField'; import { TooltipBox } from '../common/Tooltip/TooltipBox'; @@ -29,12 +23,6 @@ import MainLogo from '../GroupLogos/MainLogo'; import ImageCustomForSearch from '../MockUpPage/utils/image/ImageCustomForSearch'; import PopUpNotification from '../UserProfileSettings/PopUpNotification/PopUpNotification'; -import { - TSearchDataProduct, - TSearchDataTokens, - TSearchDataUser, - TSearchInitialState -} from './../../ducks/search/search.types'; //imports components import UserProfileSettings from './../UserProfileSettings/UserProfileSettings'; import AdminPanel from './AdminPanel/AdminPanel'; @@ -46,10 +34,9 @@ import TalkSalesComponent from './HeaderItems/TalkToSalesComponent/TalkSalesComp //styles import './Header.css'; -const MainHeader: React.FC = ({ +const MainHeader: FC = ({ goHome, creatorViewsDisabled, - selectedChain, showAlert, isSplashPage, setTabIndexItems, @@ -57,31 +44,26 @@ const MainHeader: React.FC = ({ setTokenNumber, realChainId }) => { - const dispatch = useDispatch(); + const dispatch = useAppDispatch(); const navigate = useNavigate(); const { ref, isComponentVisible, setIsComponentVisible } = useComponentVisible(true); const { primaryColor, - headerLogo, primaryButtonColor, textColor, secondaryColor, - iconColor - } = useSelector((store) => store.colorStore); + iconColor, + isDarkMode + } = useAppSelector((store) => store.colors); const { connectUserData } = useConnectUser(); - const { dataAll, message } = useSelector( - (store) => store.allInformationFromSearch + const { searchResults } = useAppSelector((store) => store.searchbar); + const { adminRights, superAdmin, isLoggedIn, loginStatus } = useAppSelector( + (store) => store.user ); - const { adminRights, superAdmin, loggedIn, loginProcess } = useSelector< - RootState, - TUsersInitialState - >((store) => store.userStore); - const { currentUserAddress } = useSelector( - (store) => store.contractStore - ); + const { currentUserAddress } = useAppSelector((store) => store.web3); const hotdropsVar = import.meta.env.VITE_TESTNET; const [realDataNotification, setRealDataNotification] = useState([]); @@ -92,7 +74,7 @@ const MainHeader: React.FC = ({ const goToExactlyContract = useCallback( async (addressId: string, collectionIndexInContract: string) => { - if (dataAll) { + if (searchResults) { const response = await axios.get( `/api/contracts/${addressId}` ); @@ -105,15 +87,15 @@ const MainHeader: React.FC = ({ `/collection/${exactlyContractData.blockchain}/${exactlyContractData.contractAddress}/${exactlyContractData.indexInContract}/0` ); setTextSearch(''); - dispatch(getDataAllClear()); + dispatch(clearResults()); } }, - [dataAll, dispatch, navigate] + [searchResults, dispatch, navigate] ); const goToExactlyToken = useCallback( async (addressId: string, token: string) => { - if (dataAll) { + if (searchResults) { const response = await axios.get( `/api/contracts/${addressId}` ); @@ -127,10 +109,10 @@ const MainHeader: React.FC = ({ `/tokens/${exactlyTokenData.blockchain}/${exactlyTokenData.contractAddress}/0/${token}` ); setTextSearch(''); - dispatch(getDataAllClear()); + dispatch(clearResults()); } }, - [dataAll, dispatch, navigate] + [searchResults, dispatch, navigate] ); const goToExactlyUser = (userAddress) => { @@ -140,7 +122,7 @@ const MainHeader: React.FC = ({ const getNotifications = useCallback( async (pageNum?: number) => { - if (currentUserAddress) { + if (currentUserAddress && isLoggedIn) { const result = await rFetch( `/api/notifications${pageNum ? `?pageNum=${Number(pageNum)}` : ''}` ); @@ -155,22 +137,25 @@ const MainHeader: React.FC = ({ return dateB - dateA; }); - // console.info(result.notifications, 'result.notifications'); setRealDataNotification(sortedNotifications); } + } else { + setRealDataNotification([]); } }, - [currentUserAddress] + [currentUserAddress, isLoggedIn] ); const getNotificationsCount = useCallback(async () => { - if (currentUserAddress) { + if (currentUserAddress && isLoggedIn) { const result = await rFetch(`/api/notifications?onlyUnread=true`); if (result.success && result.totalCount >= 0) { setNotificationCount(result.totalCount); } + } else { + setNotificationCount(0); } - }, [currentUserAddress]); + }, [currentUserAddress, isLoggedIn]); useEffect(() => { getNotificationsCount(); @@ -178,7 +163,7 @@ const MainHeader: React.FC = ({ useEffect(() => { getNotifications(0); - }, [currentUserAddress]); + }, [getNotifications]); const Highlight = (props) => { const { filter, str } = props; @@ -196,10 +181,10 @@ const MainHeader: React.FC = ({ if (index < array.length - 1) { const c = matchValue.shift(); return ( - + {s} {c} - + ); } return s; @@ -208,17 +193,13 @@ const MainHeader: React.FC = ({ return str; }; - const handleChangeText = (e: React.ChangeEvent) => { - setTextSearch(e.target.value); - }; - const handleClearText = () => { setTextSearch(''); }; useEffect(() => { if (textSearch.length > 0) { - dispatch(getDataAllStart(textSearch)); + dispatch(startSearch({ searchTerm: textSearch })); } }, [dispatch, textSearch]); @@ -226,21 +207,14 @@ const MainHeader: React.FC = ({
      - +
      = ({ }} type="text" placeholder="Search..." - setter={handleChangeText} + setter={setTextSearch} getter={textSearch} onClick={() => setIsComponentVisible(true)} /> @@ -274,118 +248,108 @@ const MainHeader: React.FC = ({
      {textSearch && ( <> - {dataAll && dataAll?.products.length > 0 ? ( + {searchResults && + searchResults?.products?.length && + searchResults?.products?.length > 0 ? (
      Products
      - {dataAll?.products.map( - (item: TSearchDataProduct, index: number) => ( -
      - {item.name} -

      { - setTokenNumber(undefined); - goToExactlyContract( - item.contract, - item.collectionIndexInContract - ); - }}> - -

      -
      - ) - )} + {searchResults?.products.map((item, index) => ( +
      + {item.name} +

      { + setTokenNumber(undefined); + goToExactlyContract( + item.contract, + item.collectionIndexInContract + ); + }}> + +

      +
      + ))}
      ) : ( <> )} - {dataAll && dataAll?.tokens.length > 0 ? ( + {searchResults && + searchResults?.tokens?.length && + searchResults?.tokens?.length > 0 ? (
      Tokens
      - {dataAll?.tokens.map( - (item: TSearchDataTokens, index: number) => ( -
      - -

      { - setTokenNumber(undefined); - goToExactlyToken( - item.contract, - item.uniqueIndexInContract - ); - }}> + {searchResults?.tokens?.map((item, index) => ( +

      + +

      { + setTokenNumber(undefined); + goToExactlyToken( + item.contract, + item.uniqueIndexInContract + ); + }}> + +

      +
      +

      -
      -

      - -

      -
      - ) - )} +
      + ))}
      ) : ( <> )} - {dataAll && dataAll?.users.length > 0 ? ( + {searchResults && + searchResults?.users?.length && + searchResults?.users?.length > 0 ? (
      Users
      - {dataAll?.users.map( - (item: TSearchDataUser, index: number) => ( -
      - goToExactlyUser(item.publicAddress) - }> - {item.avatar ? ( - user-photo - ) : ( -
      - -
      - )} -

      - -

      -
      - ) - )} + {searchResults?.users?.map((item, index) => ( +
      goToExactlyUser(item.publicAddress)}> + {item.avatar ? ( + user-photo + ) : ( +
      + +
      + )} +

      + +

      +
      + ))}
      ) : ( <> )} )} - {textSearch !== '' && message === 'Nothing can found' ? ( - No items found - ) : ( - <> - )}
      @@ -411,7 +375,7 @@ const MainHeader: React.FC = ({
    - {!loggedIn && ( + {!isLoggedIn && (
    {isAboutPage ? null : ( )}
    @@ -448,16 +414,12 @@ const MainHeader: React.FC = ({ )}
    {currentUserAddress && ( void; - startedLogin: boolean; renderBtnConnect: boolean; - connectUserData: () => void; creatorViewsDisabled: boolean; - selectedChain: string | null; showAlert: boolean; isSplashPage: boolean; setTabIndexItems: (arg: number) => void; diff --git a/rair-front/src/components/InquiriesPage/InquiriesItems.tsx b/rair-front/src/components/InquiriesPage/InquiriesItems.tsx index ff9e8cdeb..5793f9632 100644 --- a/rair-front/src/components/InquiriesPage/InquiriesItems.tsx +++ b/rair-front/src/components/InquiriesPage/InquiriesItems.tsx @@ -1,11 +1,14 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; interface IInquireItems { - primaryColor: string; + primaryColor?: string; background?: any; } -export const InquireWrapper = styled.div` +export const InquireWrapper = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` padding: 0 0 20px 0; .inquiries-title { @@ -22,7 +25,9 @@ export const InquireWrapper = styled.div` } `; -export const InquireContainer = styled.div` +export const InquireContainer = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` max-width: 700px; margin: 0 auto; background: ${(props) => @@ -72,7 +77,9 @@ export const InquireContainer = styled.div` } `; -export const InquireField = styled.div` +export const InquireField = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` display: flex; justify-content: space-between; align-items: center; @@ -186,7 +193,9 @@ export const InquireInput = styled.input` } `; -export const InquireSelect = styled.select` +export const InquireSelect = styled.select.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` width: 462px; height: 44px; border: 1px solid #4e4d4d; @@ -216,7 +225,9 @@ export const InquireSelect = styled.select` } `; -export const InquireLabel = styled.label` +export const InquireLabel = styled.label.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` display: flex; align-items: center; @@ -238,7 +249,9 @@ export const InquireLabel = styled.label` } `; -export const InquireButton = styled.button` +export const InquireButton = styled.button.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` width: 162px; height: 44px; color: #fff; diff --git a/rair-front/src/components/InquiriesPage/InquiriesPage.tsx b/rair-front/src/components/InquiriesPage/InquiriesPage.tsx index f16dd4b10..700a4a02e 100644 --- a/rair-front/src/components/InquiriesPage/InquiriesPage.tsx +++ b/rair-front/src/components/InquiriesPage/InquiriesPage.tsx @@ -1,7 +1,3 @@ -//@ts-nocheck -import React from 'react'; -import { useSelector } from 'react-redux'; - import { InquireButton, InquireContainer, @@ -12,23 +8,21 @@ import { InquireWrapper } from './InquiriesItems'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../hooks/useReduxHooks'; const InquiriesPage = () => { - const { primaryColor, primaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { primaryColor, primaryButtonColor } = useAppSelector( + (store) => store.colors + ); - const { currentUserAddress } = useSelector((store) => store.contractStore); + const { currentUserAddress } = useAppSelector((store) => store.web3); - const { userRd } = useSelector( - (store) => store.userStore - ); + const { email, isLoggedIn, nickName } = useAppSelector((store) => store.user); const onReset = () => { - const formEl = document.getElementById('form'); + const formEl: HTMLFormElement | null = document.getElementById( + 'form' + ) as HTMLFormElement; formEl?.reset(); }; @@ -44,9 +38,9 @@ const InquiriesPage = () => { encType="multipart/form-data" id="form"> <> - {currentUserAddress && userRd ? ( + {currentUserAddress && isLoggedIn ? ( <> - {userRd && !userRd.email && ( + {email && ( <> @@ -93,7 +87,7 @@ const InquiriesPage = () => { style={{ display: 'none' }} - value={userRd.nickName ? userRd.nickName : ''} + value={nickName ? nickName : ''} name="Name_First" placeholder="Type in your First name" /> @@ -101,18 +95,14 @@ const InquiriesPage = () => { style={{ display: 'none' }} - value={userRd.email ? userRd.email : ''} + value={email ? email : ''} name="Email" placeholder="Type in your First name" /> + className={`${email ? 'block-user-inquire-message' : ''}`}> Message {' '} @@ -124,9 +114,7 @@ const InquiriesPage = () => { />
    diff --git a/rair-front/src/components/MainPage/MainPage.tsx b/rair-front/src/components/MainPage/MainPage.tsx index 9c32bda68..5752e43fe 100644 --- a/rair-front/src/components/MainPage/MainPage.tsx +++ b/rair-front/src/components/MainPage/MainPage.tsx @@ -1,13 +1,11 @@ import { useEffect, useRef, useState } from 'react'; -import { useSelector } from 'react-redux'; -import Swal from 'sweetalert2'; +import { Hex } from 'viem'; import { rairAdvisorsTeam, teamMainPage } from './AboutUsTeam'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; import useConnectUser from '../../hooks/useConnectUser'; +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useSwal from '../../hooks/useSwal'; /* image imports */ import { metaMaskIcon } from '../../images/index'; import { @@ -52,7 +50,7 @@ import './MainPage_ConflictingGlobalStyles.css'; import styles from './MainPage.module.css'; /* GLOBAL VALUES */ -const blockchain: BlockchainType = '0x1'; +const blockchain: Hex = '0x1'; const contract = '0x571acc173f57c095f1f63b28f823f0f33128a6c4'; const product = '0'; const offerIndexInMarketplace = ['0', '221']; @@ -60,9 +58,7 @@ const iframeLink = 'https://iframetester.com/?url=https://staging.rair.market/watch/0x48e89cb354a30d4ce0dafac77205792040ef485f/FaR4Z7kLDOZ87Rx1UU6CaLce_bip0X7vnrPjBu2t3APd9s/stream.m3u8'; const MainPage: React.FC = ({ setIsSplashPage, setIsAboutPage }) => { - const { primaryColor } = useSelector( - (store) => store.colorStore - ); + const { primaryColor } = useAppSelector((store) => store.colors); const { connectUserData } = useConnectUser(); @@ -82,9 +78,7 @@ const MainPage: React.FC = ({ setIsSplashPage, setIsAboutPage }) => { const executeScroll = (ref) => ref.current.scrollIntoView(); - const { currentUserAddress } = useSelector( - (store) => store.contractStore - ); + const { currentUserAddress } = useAppSelector((store) => store.web3); /*VIDEO PLAYER VIEW*/ const [productsFromOffer, selectVideo, setSelectVideo] = @@ -99,6 +93,8 @@ const MainPage: React.FC = ({ setIsSplashPage, setIsAboutPage }) => { setOpenVideoPlayer(true); }; + const rSwal = useSwal(); + /*TURN OFF SEARCH BAR */ useEffect(() => { setIsSplashPage?.(true); @@ -188,7 +184,7 @@ const MainPage: React.FC = ({ setIsSplashPage, setIsAboutPage }) => { presaleMessage: '', diamond: true, customSuccessAction: (nextToken) => - Swal.fire('Success', `You own token #${nextToken}!`, 'success') + rSwal.fire('Success', `You own token #${nextToken}!`, 'success') }} />
    @@ -417,7 +413,6 @@ const MainPage: React.FC = ({ setIsSplashPage, setIsAboutPage }) => { openVideoplayer={openVideoplayer} setOpenVideoPlayer={setOpenVideoPlayer} handlePlayerClick={handlePlayerClick} - primaryColor={primaryColor} />
    diff --git a/rair-front/src/components/MainPage/hooks/getProductsHookGeneral.ts b/rair-front/src/components/MainPage/hooks/getProductsHookGeneral.ts index 61ea7171d..0112f0145 100644 --- a/rair-front/src/components/MainPage/hooks/getProductsHookGeneral.ts +++ b/rair-front/src/components/MainPage/hooks/getProductsHookGeneral.ts @@ -1,15 +1,18 @@ import { useCallback, useEffect, useState } from 'react'; import axios from 'axios'; -import { TFileType, TNftFilesResponse } from '../../../axios.responseTypes'; +import { TNftFilesResponse } from '../../../axios.responseTypes'; +import { CatalogVideoItem } from '../../../types/commonTypes'; import { TUseGetProductsReturn } from '../../SplashPage/splashPage.types'; import { TUseGetProductsGeneralArguments } from '../types/mainpage.types'; export const useGetProductsGeneral = ( input: TUseGetProductsGeneralArguments ): TUseGetProductsReturn => { - const [productsFromOffer, setProductsFromOffer] = useState([]); - const [selectVideo, setSelectVideo] = useState(); + const [productsFromOffer, setProductsFromOffer] = useState< + CatalogVideoItem[] + >([]); + const [selectVideo, setSelectVideo] = useState(); const getProductsFromOffer = useCallback(async () => { if (input.currentUserAddress) { diff --git a/rair-front/src/components/MainPage/types/mainpage.types.ts b/rair-front/src/components/MainPage/types/mainpage.types.ts index 347ff52ce..f4bd89021 100644 --- a/rair-front/src/components/MainPage/types/mainpage.types.ts +++ b/rair-front/src/components/MainPage/types/mainpage.types.ts @@ -1,5 +1,7 @@ +import { Hex } from 'viem'; + export type TUseGetProductsGeneralArguments = { - blockchain: BlockchainType; + blockchain: Hex; contract: string; product: string; currentUserAddress: string | undefined; @@ -7,7 +9,5 @@ export type TUseGetProductsGeneralArguments = { export interface IMainPage { setIsSplashPage: (arg: boolean) => void; - connectUserData: () => void; - seoInformation: Object; setIsAboutPage: (arg: boolean) => void; } diff --git a/rair-front/src/components/MockUpPage/FilteringBlock/FilteringBlock.tsx b/rair-front/src/components/MockUpPage/FilteringBlock/FilteringBlock.tsx index e1cd94506..51c2abe24 100644 --- a/rair-front/src/components/MockUpPage/FilteringBlock/FilteringBlock.tsx +++ b/rair-front/src/components/MockUpPage/FilteringBlock/FilteringBlock.tsx @@ -1,10 +1,7 @@ -//@ts-nocheck import { useContext, useEffect, useRef, useState } from 'react'; -import { useSelector } from 'react-redux'; import CloseIcon from '@mui/icons-material/Close'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; import useWindowDimensions from '../../../hooks/useWindowDimensions'; import { GlobalModalContext, @@ -45,16 +42,14 @@ const FilteringBlock = ({ }: any) => { const [filterPopUp, setFilterPopUp] = useState(false); const [, /*filterItem*/ setFilterItem] = useState('Filters'); - const filterRef = useRef(); + const filterRef = useRef(null); const [filterCloseText, setFilterClose] = useState(false); const [sortPopUp, setSortPopUp] = useState(false); - const sortRef = useRef(); + const sortRef = useRef(null); - const { primaryColor, secondaryColor, textColor, iconColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { primaryColor, secondaryColor, textColor, iconColor, isDarkMode } = + useAppSelector((store) => store.colors); const [isOpenCategories, setIsOpenCategories] = useState(false); const [isOpenBlockchain, setIsOpenBlockchain] = useState(false); @@ -90,13 +85,13 @@ const FilteringBlock = ({ }; const handleClickOutSideFilter = (e) => { - if (hotdropsVar !== 'true' && !filterRef.current.contains(e.target)) { + if (hotdropsVar !== 'true' && !filterRef?.current?.contains(e.target)) { setFilterPopUp(false); } }; const handleClickOutSideSort = (e) => { - if (!sortRef.current.contains(e.target)) { + if (!sortRef.current?.contains(e.target)) { setSortPopUp(false); } }; @@ -149,6 +144,7 @@ const FilteringBlock = ({ import.meta.env.VITE_TESTNET === 'true' ? 'hotdrops-hover' : '' }`} primaryColor={primaryColor} + isDarkMode={isDarkMode} textColor={textColor} secondaryColor={secondaryColor} sortPopUp={sortPopUp}> @@ -199,7 +195,7 @@ const FilteringBlock = ({ {
    diff --git a/rair-front/src/components/MockUpPage/FilteringBlock/FilteringBlockItems/FilteringBlockItems.tsx b/rair-front/src/components/MockUpPage/FilteringBlock/FilteringBlockItems/FilteringBlockItems.tsx index 24b8402a6..14cb8fb8f 100644 --- a/rair-front/src/components/MockUpPage/FilteringBlock/FilteringBlockItems/FilteringBlockItems.tsx +++ b/rair-front/src/components/MockUpPage/FilteringBlock/FilteringBlockItems/FilteringBlockItems.tsx @@ -1,3 +1,4 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; import { ArrowDown, ArrowUp, FilterIconNew, SimpleFilterArrow } from './incons'; @@ -13,15 +14,17 @@ import { TStyledShevronIconStyled } from '../filteringBlock.types'; -export const SelectFiltersItem = styled.div` - background-color: ${(props: TSelectFiltersItemStyled) => +export const SelectFiltersItem = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` + background-color: ${(props) => props.primaryColor === '#dedede' ? 'var(--rhyno-40)' : `color-mix(in srgb, ${props.primaryColor}, #888888)`}; - color: ${(props: TSelectFiltersItemStyled) => + color: ${(props) => props.filterPopUp ? '#fff' : `var(--${props.textColor})`}; border: solid 1px - ${(props: TSelectFiltersItemStyled) => + ${(props) => props.secondaryColor === '#dedede' ? 'var(--rhyno-40)' : `color-mix(in srgb, ${props.secondaryColor}, #888888)`}; @@ -31,56 +34,65 @@ export const SelectFiltersItem = styled.div` } `; -export const FiltersTitleIcon = styled.i` - color: ${(props: TFiltersTitleIconStyled) => - props.filterPopUp ? '#fff' : '#E882D5'}; +export const FiltersTitleIcon = styled.i.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` + color: ${(props) => (props.filterPopUp ? '#fff' : '#E882D5')}; `; -export const SelectFiltersPopUp = styled.div` +export const SelectFiltersPopUp = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` background-color: - ${(props: TSelectFiltersPopUpStyled) => + ${(props) => props.primaryColor === '#dedede' ? 'var(--rhyno)' : props.primaryColor} ); z-index: 100; `; -export const SelectSortItem = styled.div` - background-color: ${(props: TSelectSortItemStyled) => - props.primaryColor === '#dedede' +export const SelectSortItem = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` + background-color: ${({ isDarkMode, primaryColor }) => + !isDarkMode ? 'var(--rhyno-40)' - : `color-mix(in srgb, ${props.primaryColor}, #888888)`}; - color: ${(props: TSelectSortItemStyled) => props.textColor}; + : `color-mix(in srgb, ${primaryColor}, #888888)`}; + color: ${(props) => props.textColor}; border: solid 1px - ${(props: TSelectSortItemStyled) => + ${(props) => props.secondaryColor === '#dedede' ? 'var(--rhyno-40)' : `color-mix(in srgb, ${props.secondaryColor}, #888888)`}; `; -export const SortArrowUpIcon = styled.i` - color: ${(props: TSortArrowUpIconStyled) => - props.sortItem === 'up' ? '#E882D5' : '#A7A6A6'}; +export const SortArrowUpIcon = styled.i.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` + color: ${(props) => (props.sortItem === 'up' ? '#E882D5' : '#A7A6A6')}; `; -export const SortArrowDownIcon = styled.i` - color: ${(props: TSortArrowUpIconStyled) => - props.sortItem === 'down' ? '#E882D5' : '#A7A6A6'}; +export const SortArrowDownIcon = styled.i.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` + color: ${(props) => (props.sortItem === 'down' ? '#E882D5' : '#A7A6A6')}; `; -export const SelectSortPopUp = styled.div` - background-color: ${(props: TSelectSortPopUpStyled) => - props.primaryColor === '#dedede' +export const SelectSortPopUp = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` + background-color: ${({ isDarkMode, primaryColor }) => + isDarkMode ? 'var(--rhyno)' - : `color-mix(in srgb, ${props.primaryColor}, #2d2d2d)`}; - color: ${(props: TSelectSortPopUpStyled) => props.textColor}; + : `color-mix(in srgb, ${primaryColor}, #2d2d2d)`}; + color: ${({ textColor }) => textColor}; &:after { content: ''; width: 20px; height: 20px; - background-color: ${(props) => - props.primaryColor === '#dedede' + background-color: ${({ primaryColor, isDarkMode }) => + isDarkMode ? 'var(--rhyno)' - : `color-mix(in srgb, ${props.primaryColor}, #2d2d2d)`}; + : `color-mix(in srgb, ${primaryColor}, #2d2d2d)`}; position: absolute; transform: rotate(45deg); bottom: 63px; @@ -89,16 +101,18 @@ export const SelectSortPopUp = styled.div` } `; -export const ModalContentPicture = styled.div` +export const ModalContentPicture = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` background-image: url(${(props) => props.picture || props.defaultImg}); - background-color: var( - --${(props: TModalContentPictureStyled) => props.primaryColor}-transparent - ); + background-color: var(--${(props) => props.primaryColor}-transparent); `; -export const StyledFilterIcon = styled(FilterIconNew)` +export const StyledFilterIcon = styled(FilterIconNew).withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` path { - stroke: ${(props: TFiltersTitleIconStyled) => + stroke: ${(props) => import.meta.env.VITE_TESTNET === 'true' ? `${ props.customSecondaryButtonColor === '#1486c5' @@ -116,9 +130,11 @@ export const StyledFilterIcon = styled(FilterIconNew)` margin-right: 8px; `; -export const StyledArrowUpIcon = styled(ArrowUp)` +export const StyledArrowUpIcon = styled(ArrowUp).withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` path { - stroke: ${(props: TSortArrowUpIconStyled) => + stroke: ${(props) => import.meta.env.VITE_TESTNET === 'true' ? `${ props.customSecondaryButtonColor === '#1486c5' @@ -134,9 +150,11 @@ export const StyledArrowUpIcon = styled(ArrowUp)` : '#A7A6A6'}; } `; -export const StyledArrowDownIcon = styled(ArrowDown)` +export const StyledArrowDownIcon = styled(ArrowDown).withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` path { - stroke: ${(props: TSortArrowUpIconStyled) => + stroke: ${(props) => import.meta.env.VITE_TESTNET === 'true' ? `${ props.customSecondaryButtonColor === '#1486c5' @@ -152,9 +170,10 @@ export const StyledArrowDownIcon = styled(ArrowDown)` } `; -export const StyledShevronIcon = styled(SimpleFilterArrow)` - transform: ${(props: TStyledShevronIconStyled) => - props.rotate ? 'rotate(-180deg)' : ''}; +export const StyledShevronIcon = styled(SimpleFilterArrow).withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` + transform: ${(props) => (props.rotate ? 'rotate(-180deg)' : '')}; path { stroke: ${(props) => @@ -172,9 +191,11 @@ export const StyledShevronIcon = styled(SimpleFilterArrow)` } `; -export const StyledPopupArrowUpIcon = styled(ArrowUp)` +export const StyledPopupArrowUpIcon = styled(ArrowUp).withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` path { - stroke: ${(props: TSortArrowUpIconStyled) => + stroke: ${(props) => import.meta.env.VITE_TESTNET === 'true' ? `${ props.customSecondaryButtonColor === '#1486c5' @@ -188,9 +209,11 @@ export const StyledPopupArrowUpIcon = styled(ArrowUp)` }`}; } `; -export const StyledPopupArrowDownIcon = styled(ArrowDown)` +export const StyledPopupArrowDownIcon = styled(ArrowDown).withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` path { - stroke: ${(props: TSortArrowUpIconStyled) => + stroke: ${(props) => import.meta.env.VITE_TESTNET === 'true' ? `${ props.customSecondaryButtonColor === '#1486c5' diff --git a/rair-front/src/components/MockUpPage/FilteringBlock/filteringBlock.types.ts b/rair-front/src/components/MockUpPage/FilteringBlock/filteringBlock.types.ts index 53a4c3e3b..aa96fe822 100644 --- a/rair-front/src/components/MockUpPage/FilteringBlock/filteringBlock.types.ts +++ b/rair-front/src/components/MockUpPage/FilteringBlock/filteringBlock.types.ts @@ -1,3 +1,5 @@ +import { Hex } from 'viem'; + import { TDiamondTokensType } from '../../nft/nft.types'; export interface IFilteringBlock { @@ -6,22 +8,20 @@ export interface IFilteringBlock { sortItem: TSortChoice | undefined; setSortItem: (item: TSortChoice) => void; isFilterShow: boolean; - setBlockchain?: (blockchain: BlockchainType | undefined) => void; - setCategory?: (category: TOnClickCategories | null) => void; + setBlockchain?: (blockchain: Hex | undefined) => void; + setCategory?: (category: string | null) => void; setIsShow?: (value: boolean) => void; setIsShowCategories?: (value: boolean) => void; setFilterText?: (name: TBlockchainNames) => void; - setFilterCategoriesText?: (name: TOnClickCategories) => void; - categoryClick?: TOnClickCategories | null; - setCategoryClick?: (value: TOnClickCategories | null) => void; + setFilterCategoriesText?: (name: string) => void; + categoryClick?: string | null; + setCategoryClick?: (value: string | null) => void; blockchainClick?: TBlockchainNames | null; setBlockchainClick?: (value: TBlockchainNames | null) => void; } export type TSortChoice = 'down' | 'up'; -export type TOnClickCategories = 'Science' | 'Music' | 'Conference' | 'Art'; - export type TFilterItemCategories = 'Price' | 'Metadata'; export interface IArrowUp { @@ -29,7 +29,7 @@ export interface IArrowUp { } export type TSelectFiltersItemStyled = { - primaryColor: string; + primaryColor?: string; filterPopUp: boolean; textColor?: string; secondaryColor?: string; @@ -38,31 +38,33 @@ export type TSelectFiltersItemStyled = { export type TFiltersTitleIconStyled = { filterPopUp: boolean; className?: string; - primaryColor: string; + primaryColor?: string; textColor?: string; customSecondaryButtonColor?: string; }; export type TSelectFiltersPopUpStyled = { - primaryColor: string; + primaryColor?: string; }; export type TSelectSortItemStyled = { - primaryColor: string; + primaryColor?: string; textColor?: string; sortPopUp: boolean; - secondaryColor: string; + secondaryColor?: string; + isDarkMode?: boolean; }; export type TSortArrowUpIconStyled = { sortItem?: TSortChoice; - primaryColor: string; + primaryColor?: string; textColor?: string; customSecondaryButtonColor?: any; }; export type TSelectSortPopUpStyled = { - primaryColor: string; + isDarkMode?: boolean; + primaryColor?: string; textColor?: string; }; @@ -74,24 +76,24 @@ export type TModalContentPictureStyled = { export type TStyledShevronIconStyled = { rotate?: string; - primaryColor: string; + primaryColor?: string; textColor?: string; customSecondaryButtonColor?: string; }; export type TModalCategoriesItem = { - name: TOnClickCategories; + name: string; clicked: boolean; }; export interface IModalCategories { - setFilterCategoriesText?: (name: TOnClickCategories) => void; + setFilterCategoriesText?: (name: string) => void; setIsOpenCategories: (value: boolean) => void; isOpenCategories: boolean; - setCategory?: (category: TOnClickCategories | null) => void; + setCategory?: (category: string | null) => void; setIsShowCategories?: (value: boolean) => void; - click?: TOnClickCategories | null; - setClick?: (clickItem: TOnClickCategories | null) => void; + click?: string | null; + setClick?: (clickItem: string | null) => void; } export type TBlockchainNames = @@ -105,12 +107,12 @@ export type TBlockchainNames = export type TBlockchainCategory = { name: TBlockchainNames; - chainId: BlockchainType; + chainId: Hex; clicked: boolean; }; export interface IModalBlockchain { - setBlockchain?: (blockchain: BlockchainType | undefined) => void; + setBlockchain?: (blockchain: Hex | undefined) => void; isOpenBlockchain: boolean; setIsOpenBlockchain: (value: boolean) => void; setIsShow?: (value: boolean) => void; @@ -138,7 +140,6 @@ export interface IModalItem { setIsCreatedTab: (value: boolean) => void; selectedData: TDiamondTokensType | undefined; defaultImg: string; - primaryColor: string; isCreatedTab: boolean; } diff --git a/rair-front/src/components/MockUpPage/FilteringBlock/portal/ModalBlockchain/ModalBlockchain.tsx b/rair-front/src/components/MockUpPage/FilteringBlock/portal/ModalBlockchain/ModalBlockchain.tsx index 2b2dbf4e9..2f27ce3ea 100644 --- a/rair-front/src/components/MockUpPage/FilteringBlock/portal/ModalBlockchain/ModalBlockchain.tsx +++ b/rair-front/src/components/MockUpPage/FilteringBlock/portal/ModalBlockchain/ModalBlockchain.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import { faTimes } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import useServerSettings from '../../../../adminViews/useServerSettings'; +import { useAppSelector } from '../../../../../hooks/useReduxHooks'; import { IModalBlockchain, TBlockchainNames } from '../../filteringBlock.types'; import Modal from '../../modal'; @@ -15,7 +15,7 @@ const ModalBlockchain: React.FC = ({ click, setClick }) => { - const { blockchainSettings } = useServerSettings(); + const { blockchainSettings } = useAppSelector((store) => store.settings); const [arrBlockchains /*setArrBlockchains*/] = useState( blockchainSettings.map((chain) => { return { diff --git a/rair-front/src/components/MockUpPage/FilteringBlock/portal/ModalCategories/ModalCategories.tsx b/rair-front/src/components/MockUpPage/FilteringBlock/portal/ModalCategories/ModalCategories.tsx index 0532a2801..0e035a6fe 100644 --- a/rair-front/src/components/MockUpPage/FilteringBlock/portal/ModalCategories/ModalCategories.tsx +++ b/rair-front/src/components/MockUpPage/FilteringBlock/portal/ModalCategories/ModalCategories.tsx @@ -2,33 +2,13 @@ import React, { useCallback, useEffect, useState } from 'react'; import { faTimes } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { rFetch } from '../../../../../utils/rFetch'; +import { useAppSelector } from '../../../../../hooks/useReduxHooks'; import { IModalCategories, - TModalCategoriesItem, - TOnClickCategories + TModalCategoriesItem } from '../../filteringBlock.types'; import Modal from '../../modal'; -const categories: TModalCategoriesItem[] = [ - { - name: 'Music', - clicked: false - }, - { - name: 'Art', - clicked: false - }, - { - name: 'Conference', - clicked: false - }, - { - name: 'Science', - clicked: false - } -]; - const ModalCategories: React.FC = ({ setFilterCategoriesText, setIsOpenCategories, @@ -38,11 +18,14 @@ const ModalCategories: React.FC = ({ setIsShowCategories, click }) => { - const [arrCategories, setArrCategories] = - useState(categories); + const [arrCategories, setArrCategories] = useState( + [] + ); const [, /*clearAll*/ setClearAll] = useState(false); - const onChangeClicked = (name: TOnClickCategories) => { + const { categories } = useAppSelector((store) => store.settings); + + const onChangeClicked = (name: string) => { setClick?.(name); setClearAll(false); setIsShowCategories?.(true); @@ -72,15 +55,14 @@ const ModalCategories: React.FC = ({ }; const getCategories = useCallback(async () => { - const data = await rFetch('/api/categories'); - if (data.success) { + if (categories) { setArrCategories( - data.result.map((item) => { + categories.map((item) => { return { name: item.name, clicked: false }; }) ); } - }, []); + }, [categories]); useEffect(() => { getCategories(); diff --git a/rair-front/src/components/MockUpPage/FilteringBlock/portal/ModalItem/ModalItem.tsx b/rair-front/src/components/MockUpPage/FilteringBlock/portal/ModalItem/ModalItem.tsx index 0b1ed6a5e..ab1e596cd 100644 --- a/rair-front/src/components/MockUpPage/FilteringBlock/portal/ModalItem/ModalItem.tsx +++ b/rair-front/src/components/MockUpPage/FilteringBlock/portal/ModalItem/ModalItem.tsx @@ -1,17 +1,16 @@ import { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import { faTimes } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { utils } from 'ethers'; +import { formatEther } from 'ethers'; +import { Hex } from 'viem'; import { erc721Abi } from '../../../../../contracts'; -import { RootState } from '../../../../../ducks'; -import { ColorStoreType } from '../../../../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../../../../ducks/contracts/contracts.types'; +import useContracts from '../../../../../hooks/useContracts'; +import { useAppSelector } from '../../../../../hooks/useReduxHooks'; +import useServerSettings from '../../../../../hooks/useServerSettings'; import useSwal from '../../../../../hooks/useSwal'; import useWeb3Tx from '../../../../../hooks/useWeb3Tx'; import { validateInteger } from '../../../../../utils/metamaskUtils'; -import useServerSettings from '../../../../adminViews/useServerSettings'; import InputField from '../../../../common/InputField'; import { SvgKeyForModalItem } from '../../../NftList/SvgKeyForModalItem'; import { IModalItem } from '../../filteringBlock.types'; @@ -25,7 +24,6 @@ const ModalItem: React.FC = ({ setIsCreatedTab, selectedData, defaultImg, - primaryColor, isCreatedTab }) => { const { web3TxHandler, correctBlockchain, web3Switch } = useWeb3Tx(); @@ -33,28 +31,23 @@ const ModalItem: React.FC = ({ const [price, setPrice] = useState(0); const [isApproved, setIsApproved] = useState(undefined); - const { - currentChain, - currentUserAddress, - contractCreator, - diamondMarketplaceInstance - } = useSelector( - (store) => store.contractStore + const { diamondMarketplaceInstance, contractCreator } = useContracts(); + const { connectedChain, currentUserAddress } = useAppSelector( + (store) => store.web3 + ); + const { textColor, primaryButtonColor, primaryColor } = useAppSelector( + (store) => store.colors ); - const { textColor, primaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); const instance = contractCreator?.(selectedData?.contractAddress, erc721Abi); const [onMyChain, setOnMyChain] = useState( - correctBlockchain(selectedData?.blockchain as BlockchainType) + correctBlockchain(selectedData?.blockchain as Hex) ); const reactSwal = useSwal(); useEffect(() => { - setOnMyChain(currentChain === selectedData?.blockchain); - }, [currentChain, selectedData]); + setOnMyChain(connectedChain === selectedData?.blockchain); + }, [connectedChain, selectedData]); const onCloseModal = useCallback(() => { setIsCreatedTab(false); @@ -62,10 +55,6 @@ const ModalItem: React.FC = ({ setPrice(0); }, [setIsOpenBlockchain, setIsCreatedTab]); - useEffect(() => { - setOnMyChain(currentChain === selectedData?.blockchain); - }, [currentChain, selectedData?.blockchain]); - const createResaleOffer = async () => { if (onMyChain && isApproved) { if (!validateInteger(price) || !diamondMarketplaceInstance) { @@ -104,7 +93,7 @@ const ModalItem: React.FC = ({ }); if ( await web3TxHandler(instance, 'approve', [ - diamondMarketplaceInstance?.address, + await diamondMarketplaceInstance?.getAddress(), selectedData?.uniqueIndexInContract ]) ) { @@ -123,10 +112,10 @@ const ModalItem: React.FC = ({ const approved = (await web3TxHandler(instance, 'getApproved', [ selectedData?.uniqueIndexInContract - ])) === diamondMarketplaceInstance.address || + ])) === (await diamondMarketplaceInstance.getAddress()) || (await web3TxHandler(instance, 'isApprovedForAll', [ currentUserAddress, - diamondMarketplaceInstance.address + await diamondMarketplaceInstance.getAddress() ])); setIsApproved(approved); } @@ -164,7 +153,7 @@ const ModalItem: React.FC = ({ backgroundImage: `url(${ selectedData?.metadata?.image || defaultImg })`, - backgroundColor: `var(--${primaryColor}-transparent)` + backgroundColor: primaryColor }}>
    @@ -187,7 +176,7 @@ const ModalItem: React.FC = ({
    {validateInteger(price) && ( <> - {utils.formatEther(price)}{' '} + {formatEther(price)}{' '} {selectedData?.blockchain && getBlockchainData(selectedData.blockchain)?.symbol} @@ -208,7 +197,7 @@ const ModalItem: React.FC = ({ {isCreatedTab ? ( Price for this NFT on the marketplace :{' '} - {utils.formatEther(Number(selectedData?.offer?.price))}{' '} + {formatEther(Number(selectedData?.offer?.price))}{' '} {selectedData?.blockchain && getBlockchainData(selectedData.blockchain)?.symbol} @@ -227,7 +216,7 @@ const ModalItem: React.FC = ({ createResaleOffer(); } } else { - web3Switch(selectedData?.blockchain as BlockchainType); + web3Switch(selectedData?.blockchain as Hex); } }}> {onMyChain diff --git a/rair-front/src/components/MockUpPage/ImageLazy/ImageLazyItem/ImageLazy.styled.tsx b/rair-front/src/components/MockUpPage/ImageLazy/ImageLazyItem/ImageLazy.styled.tsx index 98f4be0d4..eaa0600c0 100644 --- a/rair-front/src/components/MockUpPage/ImageLazy/ImageLazyItem/ImageLazy.styled.tsx +++ b/rair-front/src/components/MockUpPage/ImageLazy/ImageLazyItem/ImageLazy.styled.tsx @@ -1,9 +1,12 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; import { defaultHotDrops, RairBackground } from '../../../../images'; import { ILazyImageItem } from '../types/imageLazy.types'; -export const Image = styled.img` +export const Image = styled.img.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` &.col-12.h-100.w-100 { display: block; height: ${(props) => props.height && props.height}; diff --git a/rair-front/src/components/MockUpPage/MainBanner/MainBanner.tsx b/rair-front/src/components/MockUpPage/MainBanner/MainBanner.tsx index 5fd251350..55c578320 100644 --- a/rair-front/src/components/MockUpPage/MainBanner/MainBanner.tsx +++ b/rair-front/src/components/MockUpPage/MainBanner/MainBanner.tsx @@ -1,8 +1,8 @@ import { useCallback } from 'react'; import { useNavigate } from 'react-router'; +import useServerSettings from '../../../hooks/useServerSettings'; import { defaultAvatar, hotDropsDefaultBanner } from '../../../images'; -import useServerSettings from '../../adminViews/useServerSettings'; import { ImageLazy } from '../ImageLazy/ImageLazy'; import { changeIPFSLink } from '../NftList/utils/changeIPFSLink'; @@ -43,17 +43,15 @@ const MainBanner = ({ mainBannerInfo }) => {
    {mainBannerInfo && mainBannerInfo.user && (
    - {mainBannerInfo && - mainBannerInfo.user && - mainBannerInfo.user.avatar ? ( + {mainBannerInfo.user.avatar ? ( avatar ) : ( avatar )}
    - {mainBannerInfo && mainBannerInfo.user + {typeof mainBannerInfo.user === 'object' ? mainBannerInfo.user.nickName - : '123'} + : mainBannerInfo.user}
    )} diff --git a/rair-front/src/components/MockUpPage/MockUpPage.tsx b/rair-front/src/components/MockUpPage/MockUpPage.tsx index 61c3ef41d..3984803d5 100644 --- a/rair-front/src/components/MockUpPage/MockUpPage.tsx +++ b/rair-front/src/components/MockUpPage/MockUpPage.tsx @@ -1,12 +1,8 @@ import React, { useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; import SearchPanel from './SearchPanel'; // import RairFavicon from './assets/rair_favicon.ico'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { setShowSidebarTrue } from '../../ducks/metadata/actions'; import { rFetch } from '../../utils/rFetch'; import MainBanner from './MainBanner/MainBanner'; @@ -14,10 +10,6 @@ import { IMockUpPage } from './SelectBox/selectBox.types'; const MockUpPage: React.FC = ({ tabIndex, setTabIndex }) => { const [mainBannerInfo, setMainBannerInfo] = useState(undefined); - const dispatch = useDispatch(); - const { primaryColor, textColor } = useSelector( - (store) => store.colorStore - ); const getCollectionBanner = async () => { const response = await rFetch(`/api/settings/featured`); @@ -26,10 +18,6 @@ const MockUpPage: React.FC = ({ tabIndex, setTabIndex }) => { } }; - useEffect(() => { - dispatch(setShowSidebarTrue()); - }, [dispatch]); - useEffect(() => { getCollectionBanner(); }, []); @@ -41,12 +29,7 @@ const MockUpPage: React.FC = ({ tabIndex, setTabIndex }) => { return (
    - +
    ); }; diff --git a/rair-front/src/components/MockUpPage/NftList/Breadcrumbs/Breadcrumbs.tsx b/rair-front/src/components/MockUpPage/NftList/Breadcrumbs/Breadcrumbs.tsx index b6df41bd7..351cce21b 100644 --- a/rair-front/src/components/MockUpPage/NftList/Breadcrumbs/Breadcrumbs.tsx +++ b/rair-front/src/components/MockUpPage/NftList/Breadcrumbs/Breadcrumbs.tsx @@ -1,5 +1,4 @@ -import React, { memo, MouseEvent, ReactElement } from 'react'; -import { useSelector } from 'react-redux'; +import { FC, memo, MouseEvent, ReactElement } from 'react'; import { NavLink } from 'react-router-dom'; import { useLocation, useNavigate, useParams } from 'react-router-dom'; import NavigateNextIcon from '@mui/icons-material/NavigateNext'; @@ -8,15 +7,14 @@ import Link from '@mui/material/Link'; import Stack from '@mui/material/Stack'; import Typography from '@mui/material/Typography'; -import { RootState } from '../../../../ducks'; -import { ColorStoreType } from '../../../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../../../hooks/useReduxHooks'; import SingleTokenHome from '../../assets/singleTokenHome.svg?react'; import { TParamsBreadcrumbsComponent } from '../../mockupPage.types'; import { IBreadcrumbsComponent } from '../nftList.types'; import './Breadcrumbs.css'; -const BreadcrumbsComponent: React.FC = ({ +const BreadcrumbsComponent: FC = ({ embeddedParams }) => { const params = useParams(); @@ -24,8 +22,8 @@ const BreadcrumbsComponent: React.FC = ({ ? embeddedParams : params; const navigate = useNavigate(); - const { primaryColor, textColor, iconColor } = useSelector( - (store) => store.colorStore + const { primaryColor, textColor, iconColor } = useAppSelector( + (store) => store.colors ); function handleClick(event: MouseEvent) { @@ -67,11 +65,9 @@ const BreadcrumbsComponent: React.FC = ({ = ({ = ({ favoritesReducer, initialFavoritesState ); - const { currentUserAddress } = useSelector( - (store) => store.contractStore - ); + const { currentUserAddress } = useAppSelector((store) => store.web3); const addFavorite = async (tokenBody: string | undefined) => { const token = { diff --git a/rair-front/src/components/MockUpPage/NftList/NftData/AuthenticityBlock/AuthenticityBlock.tsx b/rair-front/src/components/MockUpPage/NftList/NftData/AuthenticityBlock/AuthenticityBlock.tsx index 1f14687ab..a97148d54 100644 --- a/rair-front/src/components/MockUpPage/NftList/NftData/AuthenticityBlock/AuthenticityBlock.tsx +++ b/rair-front/src/components/MockUpPage/NftList/NftData/AuthenticityBlock/AuthenticityBlock.tsx @@ -1,7 +1,6 @@ import React, { useState } from 'react'; import { useCallback } from 'react'; import { useEffect } from 'react'; -import { useSelector } from 'react-redux'; import { faArrowRight, faExternalLinkAlt @@ -10,8 +9,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { TableAuthenticity } from './AuthenticityBlockItems'; -import { RootState } from '../../../../../ducks'; -import { ColorStoreType } from '../../../../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../../../../hooks/useReduxHooks'; import { defaultHotDrops } from '../../../../../images'; import { IAuthenticityBlock } from '../../nftList.types'; @@ -24,8 +22,8 @@ const AuthenticityBlock: React.FC = ({ collectionToken, selectedData }) => { - const { primaryColor, textColor } = useSelector( - (store) => store.colorStore + const { primaryColor, textColor, isDarkMode } = useAppSelector( + (store) => store.colors ); const hotdropsVar = import.meta.env.VITE_TESTNET; @@ -73,6 +71,7 @@ const AuthenticityBlock: React.FC = ({ {title &&
    Authenticity
    }
    Action
    {tokenData && ( diff --git a/rair-front/src/components/MockUpPage/NftList/NftData/AuthenticityBlock/AuthenticityBlockItems.tsx b/rair-front/src/components/MockUpPage/NftList/NftData/AuthenticityBlock/AuthenticityBlockItems.tsx index f748d1692..aba3296e4 100644 --- a/rair-front/src/components/MockUpPage/NftList/NftData/AuthenticityBlock/AuthenticityBlockItems.tsx +++ b/rair-front/src/components/MockUpPage/NftList/NftData/AuthenticityBlock/AuthenticityBlockItems.tsx @@ -1,12 +1,15 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; import { TAuthenticityStyled } from '../../nftList.types'; -export const TableAuthenticity = styled.div` - background: ${(props) => - props.primaryColor === '#dedede' +export const TableAuthenticity = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` + background: ${({ isDarkMode, primaryColor }) => + !isDarkMode ? 'rgb(189, 189, 189)' - : `color-mix(in srgb, ${props.primaryColor}, #888888)`}; + : `color-mix(in srgb, ${primaryColor}, #888888)`}; border-radius: 16px; padding-top: 10px; margin-top: 24px; @@ -15,18 +18,18 @@ export const TableAuthenticity = styled.div` font-weight: 700; .authenticity-box:nth-child(2):hover { - background: ${(props) => - props.primaryColor === '#dedede' + background: ${({ isDarkMode, primaryColor }) => + !isDarkMode ? '#b1b1b1' - : `color-mix(in srgb, ${props.primaryColor} 20%, #888888)`}; + : `color-mix(in srgb, ${primaryColor} 20%, #888888)`}; cursor: pointer; } .authenticity-box:nth-child(3):hover { - background: ${(props) => - props.primaryColor === '#dedede' + background: ${({ isDarkMode, primaryColor }) => + !isDarkMode ? '#b1b1b1' - : `color-mix(in srgb, ${props.primaryColor} 30%, #888888)`}; + : `color-mix(in srgb, ${primaryColor} 30%, #888888)`}; border-end-end-radius: 16px; border-end-start-radius: 16px; cursor: pointer; diff --git a/rair-front/src/components/MockUpPage/NftList/NftData/BuySellButton.tsx b/rair-front/src/components/MockUpPage/NftList/NftData/BuySellButton.tsx index 5baa20fb6..348a09409 100644 --- a/rair-front/src/components/MockUpPage/NftList/NftData/BuySellButton.tsx +++ b/rair-front/src/components/MockUpPage/NftList/NftData/BuySellButton.tsx @@ -1,8 +1,4 @@ -import { useSelector } from 'react-redux'; - -import { RootState } from '../../../../ducks'; -import { ColorStoreType } from '../../../../ducks/colors/colorStore.types'; -// import MetamaskFox from '../../assets/MetamaskFox.svg?react'; +import { useAppSelector } from '../../../../hooks/useReduxHooks'; import { IBuySellButton } from '../../mockupPage.types'; export const BuySellButton: React.FC = ({ @@ -10,10 +6,9 @@ export const BuySellButton: React.FC = ({ handleClick, disabled }) => { - const { textColor, primaryButtonColor, primaryColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { textColor, primaryButtonColor, primaryColor } = useAppSelector( + (store) => store.colors + ); return (
    {remainingCopies > 0 ? ( <> - { - token.sponsored ?
    -
    :
    - { - return { - label: (index + 1).toString(), - value: (index + 1).toString() - }; - } - )} - getter={tokensToMint} - setter={setTokensToMint} - /> -
    - } + {token.sponsored ? ( +
    + ) : ( +
    + { + return { + label: (index + 1).toString(), + value: (index + 1).toString() + }; + } + )} + getter={tokensToMint} + setter={setTokensToMint} + /> +
    + )} ) : ( -
    No tokens available.
    +
    + No tokens available. +
    )} {mintToken && (
    @@ -122,17 +125,19 @@ const EasyMintRow = ({ diamond={token.diamond} setPurchaseStatus={setPurchaseStatus} customSuccessAction={(purchasedTokens) => { - Swal.fire( - 'Success', - `Token${tokensToMint !== '1' ? 's' : ''} purchased!`, - 'success' - ).then((result) => { - if (result.isConfirmed || result.isDismissed) { - navigate( - `/tokens/${blockchain}/${params.contract}/${params.product}/${purchasedTokens}` - ); - } - }); + rSwal + .fire( + 'Success', + `Token${tokensToMint !== '1' ? 's' : ''} purchased!`, + 'success' + ) + .then((result) => { + if (result.isConfirmed || result.isDismissed) { + navigate( + `/tokens/${blockchain}/${params.contract}/${params.product}/${purchasedTokens}` + ); + } + }); }} /> )} @@ -142,7 +147,7 @@ const EasyMintRow = ({ ); }; -const CollectionInfo: React.FC = ({ +const CollectionInfo: FC = ({ blockchain, offerData, openTitle, @@ -151,9 +156,7 @@ const CollectionInfo: React.FC = ({ setPurchaseStatus, closeModal }) => { - const primaryColor = useSelector( - (store) => store.colorStore.primaryColor - ); + const { primaryColor, isDarkMode } = useAppSelector((store) => store.colors); const params = useParams(); const [tokenData, setTokenData] = useState(null); const { width } = useWindowDimensions(); @@ -173,13 +176,13 @@ const CollectionInfo: React.FC = ({ ); if (data && data.success) { - const count = data.result.totalCount; + const count = data.totalCount; const response = await axios.get( `/api/nft/network/${params.blockchain}/${params.contract}/${params.product}?fromToken=0&toToken=${count}` ); if (response.data.success) { - setTokenData(response.data.result.tokens); + setTokenData(response.data.tokens); } } }; @@ -208,7 +211,7 @@ const CollectionInfo: React.FC = ({
    )} {closeModal && (
    = ({ position: 'fixed' }}> ` +export const CollectionInfoBody = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` width: 100%; .block-item-collection:nth-child(odd) { - background: ${(props) => - props.primaryColor === 'rhyno' ? 'rgb(248, 248, 248)' : '#2D2B2C'}; + background: ${({ isDarkMode }) => + !isDarkMode ? 'rgb(248, 248, 248)' : '#2D2B2C'}; } @media screen and (max-width: 1024px) { diff --git a/rair-front/src/components/MockUpPage/NftList/NftData/CustomShareButton.tsx b/rair-front/src/components/MockUpPage/NftList/NftData/CustomShareButton.tsx index aae02f0f1..9bb13de08 100644 --- a/rair-front/src/components/MockUpPage/NftList/NftData/CustomShareButton.tsx +++ b/rair-front/src/components/MockUpPage/NftList/NftData/CustomShareButton.tsx @@ -1,15 +1,16 @@ -import React from 'react'; +import { FC } from 'react'; +import { useAppSelector } from '../../../../hooks/useReduxHooks'; import useWindowDimensions from '../../../../hooks/useWindowDimensions'; import { ICusmonShareButton } from '../../mockupPage.types'; -const CustomShareButton: React.FC = ({ +const CustomShareButton: FC = ({ title, handleClick, - primaryColor, moreUnlockablesClassName }) => { const { width } = useWindowDimensions(); + const { isDarkMode } = useAppSelector((store) => store.colors); return ( - - )} -
    - Traits ({newAttr.length}) -
    -
    - {newAttr && - newAttr.map((item, index) => { - return ( - - ); - })} -
    -
    - setTitleSearchAttributes(e.target.value)} - style={{ - border: '1px solid #666666', - width: '100%', - borderRadius: '12px', - padding: '5px 10px', - background: 'none', - outline: 'none', - color: 'white' - }} - placeholder="Search..." + someUsersData={someUsersData} + userName={offerAllData?.owner} + setPlaying={setPlaying} + playing={playing} + diamond={token.offer.diamond} + resalePrice={token?.resaleData?.price} + resaleFlag={!!token?.resaleData} /> -
    - - {primaryColor && ( -
    - - -
    - )} - + someUsersData={someUsersData} + userName={offerAllData?.owner} + tokenDataLength={Object.keys(currentCollection).length} + setPlaying={setPlaying} + playing={playing} + diamond={item.offer.diamond} + resalePrice={item?.resaleData?.price} + resaleFlag={!!item?.resaleData} + /> + ); + } else { + return null; + } + }) + : Array.from(new Array(10)).map((item, index) => { + return ( + + ); + })} +
    + {metadataFilter && ( +
    + + {isMobileDesign && ( + + Filters + + + )} +
    + Traits ({newAttr.length}) +
    +
    + {newAttr && + newAttr.map((item, index) => { + return ( + + ); + })}
    - )} -
    - {isLoading && ( -
    - + +
    + -
    - )} - {tokenDataFiltered.length - ? null - : totalCount && - showTokensRef.current <= totalCount && ( -
    - )} - <> - {Object.keys(tokenData).length <= 5 && ( - <> + {primaryColor && (
    - - - )} - + marginTop: '10px' + }}> + + +
    + )} + +
    + )} +
    + {isLoading && ( +
    +
    - ) : ( -
    - {!!embeddedParams || ( + )} +
    + <> + {Object.keys(currentCollection).length <= 5 && ( + <>
    goBack()} - className="arrow-back"> - -
    - )} -

    {"Don't have product"}

    -
    - )} - + marginTop: '30px' + }}>
    + + + )} + +
    ); }; diff --git a/rair-front/src/components/MockUpPage/NftList/NftData/NftDataCommonLink.tsx b/rair-front/src/components/MockUpPage/NftList/NftData/NftDataCommonLink.tsx index 7d8bacf44..e1cbdd3b4 100644 --- a/rair-front/src/components/MockUpPage/NftList/NftData/NftDataCommonLink.tsx +++ b/rair-front/src/components/MockUpPage/NftList/NftData/NftDataCommonLink.tsx @@ -1,9 +1,8 @@ import React, { memo, useCallback, useEffect, useRef, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; import { useLocation, useNavigate, useParams } from 'react-router-dom'; import axios, { AxiosError } from 'axios'; -import { BigNumber, constants, utils } from 'ethers'; -import { formatEther } from 'ethers/lib/utils'; +import { isAddress, ZeroAddress } from 'ethers'; +import { Hex } from 'viem'; import { NftCollectionPage } from './NftCollectionPage'; import NftDataPageMain from './NftDataPageMain'; @@ -11,25 +10,24 @@ import NftUnlockablesPage from './NftUnlockablesPage'; import { IOffersResponseType, - TFileType, - TMetadataType, TNftFilesResponse, - TNftItemResponse, TProducts, TTokenData, TUserResponse } from '../../../../axios.responseTypes'; -import { RootState } from '../../../../ducks'; -import { ColorStoreType } from '../../../../ducks/colors/colorStore.types'; -import { setRealChain } from '../../../../ducks/contracts/actions'; -import { ContractsInitialType } from '../../../../ducks/contracts/contracts.types'; import { - setTokenData, - setTokenDataStart, - setTokenDataTotalCount -} from '../../../../ducks/nftData/action'; -import { UserType } from '../../../../ducks/users/users.types'; -import { rFetch } from '../../../../utils/rFetch'; + useAppDispatch, + useAppSelector +} from '../../../../hooks/useReduxHooks'; +import { dataStatuses } from '../../../../redux/commonTypes'; +import { loadCollection } from '../../../../redux/tokenSlice'; +import { setRequestedChain } from '../../../../redux/web3Slice'; +import { CatalogVideoItem } from '../../../../types/commonTypes'; +import { + MediaFile, + TokenMetadata, + User +} from '../../../../types/databaseTypes'; import { TOfferType } from '../../../marketplace/marketplace.types'; import { INftDataCommonLinkComponent, @@ -43,8 +41,7 @@ const NftDataCommonLinkComponent: React.FC = ({ }) => { const [collectionName, setCollectionName] = useState(); const [tokenDataFiltered, setTokenDataFiltered] = useState([]); - const [totalCount, setTotalCount] = useState(); - const [selectedData, setSelectedData] = useState(); + const [selectedData, setSelectedData] = useState(); const [selectedOfferIndex, setSelectedOfferIndex] = useState(); const [selectedToken, setSelectedToken] = useState(); const [offerPrice, setOfferPrice] = useState([]); @@ -52,26 +49,22 @@ const NftDataCommonLinkComponent: React.FC = ({ const [offerDataInfo, setOfferDataInfo] = useState(); const [ownerInfo, setOwnerInfo] = useState(); const [productsFromOffer, setProductsFromOffer] = useState< - TFileType[] | undefined + CatalogVideoItem[] | undefined >(undefined); const [showToken, setShowToken] = useState(15); const [isLoading, setIsLoading] = useState(false); - const [someUsersData, setSomeUsersData] = useState(); + const [someUsersData, setSomeUsersData] = useState(); const [dataForUser, setDataForUser] = useState(); - const [tokenBought, setTokenBought] = useState(false); const showTokensRef = useRef(20); - const dispatch = useDispatch(); - const { currentUserAddress } = useSelector( - (store) => store.contractStore - ); - const { primaryColor, textColor } = useSelector( - (store) => store.colorStore - ); - const tokenData = useSelector< - RootState, - { [index: string]: TTokenData } | null | undefined - >((state) => state.nftDataStore.tokenData); + const dispatch = useAppDispatch(); + const { currentUserAddress } = useAppSelector((store) => store.web3); + const { + currentCollection, + currentCollectionMetadata, + currentCollectionStatus, + currentCollectionMetadataStatus + } = useAppSelector((state) => state.tokens); const navigate = useNavigate(); const params = useParams(); @@ -87,60 +80,63 @@ const NftDataCommonLinkComponent: React.FC = ({ const getAllProduct = useCallback( async (fromToken: string, toToken: string, attributes: any) => { - - setIsLoading(true); - let responseAllProduct; - if(!window.location.href.includes('/tokens')) { - responseAllProduct = await axios.get( - `/api/nft/network/${blockchain}/${contract}/${product}?fromToken=${fromToken}&toToken=${toToken}${ - attributes ? `&metadataFilters=${JSON.stringify(attributes)}` : '' - }` - ); - } else { - responseAllProduct = await axios.get( - `/api/nft/network/${blockchain}/${contract}/${product}?fromToken=${tokenId}&toToken=${tokenId}${ - attributes ? `&metadataFilters=${JSON.stringify(attributes)}` : '' - }` - ); - } - const resaleData = await rFetch( - `/api/resales/open?contract=${contract}&blockchain=${blockchain}` - ); - const resaleMapping = {}; - if (resaleData.success) { - resaleData.data.forEach((resale) => { - resale.price = formatEther(resale.price); - resaleMapping[resale.tokenIndex] = resale; - }); + if ( + !product || + currentCollectionStatus === dataStatuses.Loading || + currentCollectionMetadataStatus === dataStatuses.Loading + ) { + return; } - const tokenMapping = {}; - if (responseAllProduct.data.success && responseAllProduct.data.result) { - responseAllProduct.data.result.tokens.forEach((item) => { - if (resaleMapping[item.uniqueIndexInContract]) { - item.resaleData = resaleMapping[item.uniqueIndexInContract]; - } - tokenMapping[item.token] = item; - }); + const tokensFlag = window.location.href.includes('/tokens') && tokenId; + + if ( + tokensFlag && + contract === currentCollectionMetadata?.contract?.contractAddress && + currentCollection[tokenId] + ) { + return; } - dispatch(setTokenData(tokenMapping)); dispatch( - setTokenDataTotalCount(responseAllProduct.data.result.totalCount) + loadCollection({ + blockchain: blockchain as Hex, + contract: contract as Hex, + product, + fromToken: tokensFlag ? tokenId : fromToken, + toToken: tokensFlag ? tokenId : toToken, + attributes + }) ); - setTotalCount(responseAllProduct.data.result.totalCount); - setIsLoading(false); - if (tokenId && tokenMapping[tokenId]) { - setSelectedData(tokenMapping[tokenId]?.metadata); - setIsLoading(false); - } - - setSelectedToken(tokenId); + setIsLoading(false); }, - [product, contract, tokenId, blockchain, dispatch] + [ + product, + tokenId, + currentCollection, + dispatch, + blockchain, + contract, + currentCollectionStatus, + currentCollectionMetadata, + currentCollectionMetadataStatus + ] ); + useEffect(() => { + if (!tokenId || !currentCollectionMetadata.product) { + return; + } + const realNumber = ( + BigInt(tokenId) + + BigInt(currentCollectionMetadata.product?.firstTokenIndex) + ).toString(); + if (realNumber && currentCollection[realNumber]?.metadata) { + setSelectedData(currentCollection[realNumber]?.metadata); + } + }, [tokenId, currentCollection, currentCollectionMetadata]); + const getProductsFromOffer = useCallback(async () => { setIsLoading(true); const response = await axios.get( @@ -149,8 +145,8 @@ const NftDataCommonLinkComponent: React.FC = ({ setIsLoading(false); const loadedFiles: string[] = []; setProductsFromOffer( - response.data.files.filter((item: TFileType) => { - if (!loadedFiles.includes(item._id)) { + response.data.files.filter((item: MediaFile) => { + if (item._id && !loadedFiles.includes(item._id)) { loadedFiles.push(item._id); return true; } @@ -161,18 +157,19 @@ const NftDataCommonLinkComponent: React.FC = ({ }, [blockchain, contract, product, currentUserAddress]); const initialTokenData = useCallback(() => { - if (tokenData && tokenId) { - if (tokenData[tokenId]?.offer?.diamond) { + if (currentCollection && selectedToken) { + if (currentCollection[selectedToken]?.offer?.diamond) { setSelectedOfferIndex( - tokenData && tokenData[tokenId]?.offer?.diamondRangeIndex + currentCollection && + currentCollection[selectedToken]?.offer?.diamondRangeIndex ); - } else { + } else if (currentCollection) { setSelectedOfferIndex( - tokenData && tokenData[tokenId]?.offer?.offerIndex + currentCollection[selectedToken]?.offer?.offerIndex ); } } - }, [tokenData, tokenId]); + }, [currentCollection, selectedToken]); const getParticularOffer = useCallback(async () => { try { @@ -214,8 +211,8 @@ const NftDataCommonLinkComponent: React.FC = ({ // find user if ( neededUserAddress && - utils.isAddress(neededUserAddress) && - neededUserAddress !== constants.AddressZero + isAddress(neededUserAddress) && + neededUserAddress !== ZeroAddress ) { const result = await axios .get(`/api/users/${neededUserAddress}`) @@ -224,66 +221,68 @@ const NftDataCommonLinkComponent: React.FC = ({ } }, [neededUserAddress]); - const handleTokenBoughtButton = useCallback(() => { - setTokenBought((prev) => !prev); - }, [setTokenBought]); - useEffect(() => { getInfoFromUser(); }, [getInfoFromUser]); - const handleClickToken = async (tokenId: string | undefined) => { - if (embeddedParams && tokenId) { - embeddedParams.setTokenId(tokenId); - } else { - navigate(`/tokens/${blockchain}/${contract}/${product}/${tokenId}`); - } + const handleClickToken = useCallback( + async (tokenId: string | undefined) => { + if (embeddedParams && tokenId) { + embeddedParams.setTokenId(tokenId); + } else { + navigate(`/tokens/${blockchain}/${contract}/${product}/${tokenId}`); + } - if ( - tokenData && - tokenId && - Object.keys(tokenData).length >= Number(tokenId) - ) { - setSelectedData( - tokenData && tokenData[tokenId] && tokenData[tokenId].metadata - ); - } + if ( + currentCollection && + tokenId && + Object.keys(currentCollection).length >= Number(tokenId) + ) { + setSelectedData( + currentCollection && + currentCollection[tokenId] && + currentCollection[tokenId].metadata + ); + } - setSelectedToken(tokenId); - }; + setSelectedToken(tokenId); + }, + [blockchain, contract, currentCollection, embeddedParams, navigate, product] + ); useEffect(() => { - dispatch(setTokenDataStart()); - }, [dispatch]); + if (blockchain) { + dispatch(setRequestedChain(blockchain)); + } + }, [blockchain, dispatch]); useEffect(() => { - dispatch(setRealChain(blockchain)); - }, [blockchain, dispatch]); + if (!tokenId || !currentCollectionMetadata.product) { + return; + } + const realNumber = ( + BigInt(tokenId) + + BigInt(currentCollectionMetadata.product?.firstTokenIndex) + ).toString(); + if (realNumber) { + setSelectedToken(realNumber); + } + }, [currentCollectionMetadata, tokenId]); useEffect(() => { - let tokenStart = BigNumber.from(0); - let tokenEnd = BigNumber.from(15); - if (tokenId) { - tokenStart = BigNumber.from(tokenId).sub(10); - if (tokenStart.lt(0)) { - tokenStart = BigNumber.from(0); - } - if (tokenNumber && tokenNumber > 20) { - tokenEnd = BigNumber.from(tokenNumber); - } else { - tokenEnd = tokenStart.add(showTokensRef.current); - setTokenNumber(undefined); - } + let tokenStart = BigInt(0); + let tokenEnd = tokenStart + BigInt(15); + if (tokenStart < BigInt(0)) { + tokenStart = BigInt(0); + } + if (tokenNumber && tokenNumber > 20) { + tokenEnd = BigInt(tokenNumber); + } else { + tokenEnd = tokenStart + BigInt(showTokensRef.current); + setTokenNumber(undefined); } getAllProduct(tokenStart.toString(), tokenEnd.toString(), undefined); - }, [ - getAllProduct, - showTokensRef, - tokenId, - tokenNumber, - setTokenNumber, - tokenBought - ]); + }, [setTokenNumber, tokenNumber]); useEffect(() => { getParticularOffer(); @@ -298,11 +297,11 @@ const NftDataCommonLinkComponent: React.FC = ({ }, []); useEffect(() => { - if (tokenData === undefined || !tokenData) { + if (currentCollection === undefined || !currentCollection) { setTokenNumber(undefined); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [tokenData]); + }, [currentCollection]); useEffect(() => { initialTokenData(); @@ -323,9 +322,7 @@ const NftDataCommonLinkComponent: React.FC = ({ offerPrice={offerPrice} someUsersData={someUsersData} selectedData={selectedData} - tokenData={tokenData} tokenDataFiltered={tokenDataFiltered} - totalCount={totalCount} getAllProduct={getAllProduct} setShowToken={setShowToken} showToken={showToken} @@ -342,10 +339,8 @@ const NftDataCommonLinkComponent: React.FC = ({ return ( = ({ someUsersData={someUsersData} selectedData={selectedData} selectedToken={selectedToken} - textColor={textColor} - totalCount={totalCount} product={product} ownerInfo={ownerInfo} offerDataInfo={offerDataInfo} - handleTokenBoughtButton={handleTokenBoughtButton} setTokenNumber={setTokenNumber} getProductsFromOffer={getProductsFromOffer} /> diff --git a/rair-front/src/components/MockUpPage/NftList/NftData/NftDataExternalLink.tsx b/rair-front/src/components/MockUpPage/NftList/NftData/NftDataExternalLink.tsx index cbd3b6a12..7ec8befb9 100644 --- a/rair-front/src/components/MockUpPage/NftList/NftData/NftDataExternalLink.tsx +++ b/rair-front/src/components/MockUpPage/NftList/NftData/NftDataExternalLink.tsx @@ -1,73 +1,60 @@ -//@ts-nocheck import { useCallback, useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; import { useNavigate, useParams } from 'react-router-dom'; import axios, { AxiosError } from 'axios'; -import { constants, utils } from 'ethers'; -import Swal from 'sweetalert2'; +import { isAddress, ZeroAddress } from 'ethers'; +import { Hex } from 'viem'; import NftDataPageMain from './NftDataPageMain'; import { - TContract, - TFileType, TMetadataType, // TNFTDataExternalLinkContractProduct, TNftFilesResponse, - TNftItemResponse, // TTokenData, TUserResponse } from '../../../../axios.responseTypes'; -import { RootState } from '../../../../ducks'; -import { ColorStoreType } from '../../../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../../../ducks/contracts/contracts.types'; import { - setTokenData, - setTokenDataStart -} from '../../../../ducks/nftData/action'; -import { UserType } from '../../../../ducks/users/users.types'; + useAppDispatch, + useAppSelector +} from '../../../../hooks/useReduxHooks'; +import useSwal from '../../../../hooks/useSwal'; +import { loadCollection } from '../../../../redux/tokenSlice'; +import { CatalogVideoItem } from '../../../../types/commonTypes'; +import { User } from '../../../../types/databaseTypes'; import { TOfferType } from '../../../marketplace/marketplace.types'; // import { TNftExternalLinkType } from '../nftList.types'; const NftDataExternalLink = () => { - const dispatch = useDispatch(); + const dispatch = useAppDispatch(); const navigate = useNavigate(); const params = useParams(); const { contractId, product, token } = params; - const { currentUserAddress } = useSelector( - (store) => store.contractStore - ); - const { textColor } = useSelector( - (store) => store.colorStore - ); + const { currentUserAddress } = useAppSelector((store) => store.web3); - const [dataForUser, setDataForUser] = useState(); + const [dataForUser, setDataForUser] = useState(); const [offer, setOffer] = useState([]); const [offerPrice, setOfferPrice] = useState(); - const [totalCount, setTotalCount] = useState(); const [selectedData, setSelectedData] = useState(); const [selectedToken, setSelectedToken] = useState(); - const [neededBlockchain, setNeededBlockchain] = useState< - BlockchainType | undefined - >(); - const [productsFromOffer, setProductsFromOffer] = useState([]); - const [someUsersData, setSomeUsersData] = useState(null); + const [neededBlockchain, setNeededBlockchain] = useState(); + const [productsFromOffer, setProductsFromOffer] = useState< + CatalogVideoItem[] + >([]); + const [someUsersData, setSomeUsersData] = useState(null); const [typeOfContract, setTypeOfContract] = useState(); const [neededContract, setNeededContract] = useState(); const [neededTokenOffer, setNeededTokenOffer] = useState(); - const [contractOfProduct, setContractOfProduct] = useState(); - const [neededProduct, setNeededProduct] = useState(); - const [lastToken, setLastToken] = useState(); + const [contractOfProduct, setContractOfProduct] = useState(); + const [neededProduct, setNeededProduct] = useState(''); + const [lastToken, setLastToken] = useState(0); const [showToken, setShowToken] = useState(15); - const [, /*dataFromOneToken*/ setDataFromOneToken] = useState(); - const [, /*dataFromOneContract*/ setDataFromOneContract] = useState(); - const [, /*dataFromOneOffer*/ setDataFromOneOffers] = useState(); - const [dataFromListTokens, setDataFromListTokens] = useState(); const [ifClassicContract, setIfClassicContract] = useState(); + const rSwal = useSwal(); + const getData = useCallback(async () => { if (contractId && product && token) { try { @@ -78,7 +65,6 @@ const NftDataExternalLink = () => { if (success) { setNeededContract(data.doc.contract); setNeededTokenOffer(data.doc.offer); - setDataFromOneToken(data.doc); setSelectedData(data.doc?.metadata); setSelectedToken(token); if (data.doc.offerPool) { @@ -87,10 +73,10 @@ const NftDataExternalLink = () => { } } catch (err) { const error = err as AxiosError; - Swal.fire('Error', `${error.message}`, 'error'); + rSwal.fire('Error', `${error.message}`, 'error'); } } else return null; - }, [contractId, product, token]); + }, [contractId, product, token, rSwal]); const getContractInfo = useCallback(async () => { if (neededContract) { @@ -98,27 +84,25 @@ const NftDataExternalLink = () => { const response = await axios.get(`/api/contracts/${neededContract}`); const { success, contract } = response.data; if (success) { - setDataFromOneContract(contract); setTypeOfContract(contract.diamond); setNeededBlockchain(contract.blockchain); setContractOfProduct(contract.contractAddress); } } catch (err) { const error = err as AxiosError; - Swal.fire('Error', `${error.message}`, 'error'); + rSwal.fire('Error', `${error.message}`, 'error'); } } else return null; - }, [neededContract]); + }, [neededContract, rSwal]); const getOfferInfo = useCallback( async (typeOfContract) => { switch (typeOfContract) { case true: // eslint-disable-next-line no-case-declarations - const diamondResponse = await axios.get( + const diamondResponse = await axios.get( `/api/offers/?contract=${neededContract}&diamondRangeIndex=${neededTokenOffer}` ); - setDataFromOneOffers(diamondResponse); setOfferPrice(diamondResponse.data.data.doc?.map((p) => p.price)); setOffer(diamondResponse.data.data.doc[0]); setNeededProduct(diamondResponse.data.data.doc[0].product); @@ -128,7 +112,6 @@ const NftDataExternalLink = () => { const classicResponse = await axios.get( `/api/offers/?contract=${neededContract}&offerPool=${ifClassicContract}&offerIndex=${product}` ); - setDataFromOneOffers(classicResponse); setOfferPrice(classicResponse.data.data.doc?.map((p) => p.price)); setOffer(classicResponse.data.data.doc[0]); setNeededProduct(classicResponse.data.data.doc[0].product); @@ -140,53 +123,28 @@ const NftDataExternalLink = () => { const getAllTokensData = useCallback( async (fromToken: number, toToken: number) => { - let responseAllProduct; - - if (token && neededBlockchain && contractOfProduct && neededProduct) { - responseAllProduct = await axios.get( - `/api/nft/network/${neededBlockchain}/${contractOfProduct}/${neededProduct}?fromToken=${fromToken}&toToken=${toToken}` + if (neededBlockchain && contractOfProduct && neededProduct !== '') { + dispatch( + loadCollection({ + blockchain: neededBlockchain, + contract: contractOfProduct, + product: neededProduct, + fromToken: fromToken.toString(), + toToken: toToken.toString() + }) ); - - const { success, result } = responseAllProduct.data; - const tokenMapping = {}; - - if (success) { - result.tokens.forEach((item) => { - tokenMapping[item.token] = item; - }); - dispatch(setTokenData(tokenMapping)); - setTotalCount(result.totalCount); - } } }, - - [token, neededBlockchain, contractOfProduct, neededProduct, dispatch] + [neededBlockchain, contractOfProduct, neededProduct, dispatch] ); - const getListTokensData = useCallback(async () => { - if (neededContract) { - try { - const response = await axios.get( - `/api/tokens/?contract=${neededContract}` - ); - const { success, tokens } = response.data; - if (success) { - setDataFromListTokens(tokens); - } - } catch (err) { - const error = err as AxiosError; - Swal.fire('Error', `${error.message}`, 'error'); - } - } else return null; - }, [neededContract]); - const getProductsFromOffer = useCallback(async () => { if (neededBlockchain && contractOfProduct) { const response = await axios.get( `/api/nft/network/${neededBlockchain}/${contractOfProduct}/${neededTokenOffer}/files` ); setProductsFromOffer(response.data.files); - setDataForUser(response.data.files[0]?.authorPublicAddress); + setDataForUser(response.data.files[0]?.uploader); } }, [neededBlockchain, contractOfProduct, neededTokenOffer]); @@ -220,24 +178,16 @@ const NftDataExternalLink = () => { currentUserAddress ]); - const handleTokenBoughtButton = () => { - setTokenBought((prev) => !prev); - }; - const handleClickToken = async (token: string | undefined) => { navigate( `/tokens/${neededBlockchain}/${contractOfProduct}/${product}/${token}` ); - token && setSelectedData(dataFromListTokens[token]?.metadata); - setSelectedToken(token); + //token && setSelectedData(dataFromListTokens[token]?.metadata); + //setSelectedToken(token); }; const getInfoFromUser = useCallback(async () => { - if ( - dataForUser && - utils.isAddress(dataForUser) && - dataForUser !== constants.AddressZero - ) { + if (dataForUser && isAddress(dataForUser) && dataForUser !== ZeroAddress) { const result = await axios .get(`/api/users/${dataForUser}`) .then((res) => res.data); @@ -245,10 +195,6 @@ const NftDataExternalLink = () => { } }, [dataForUser]); - useEffect(() => { - dispatch(setTokenDataStart()); - }, [dispatch]); - useEffect(() => { getAllTokensData(0, showToken); }, [getAllTokensData, showToken]); @@ -263,10 +209,6 @@ const NftDataExternalLink = () => { getListOfTokens(); }, [getListOfTokens]); - useEffect(() => { - getListTokensData(); - }, [getListTokensData]); - useEffect(() => { getInfoFromUser(); }, [getInfoFromUser]); @@ -281,17 +223,14 @@ const NftDataExternalLink = () => { contract={contractOfProduct} handleClickToken={handleClickToken} offerPrice={offerPrice} - offerDataInfo={offer.length > 0 && offer} - offerData={offer.length > 0 && offer} - totalCount={totalCount} - textColor={textColor} + offerDataInfo={offer} + offerData={offer[0]} selectedData={selectedData} selectedToken={selectedToken} someUsersData={someUsersData} setSelectedToken={setSelectedToken} productsFromOffer={productsFromOffer} product={product} - handleTokenBoughtButton={handleTokenBoughtButton} /> ); }; diff --git a/rair-front/src/components/MockUpPage/NftList/NftData/NftDataPage.tsx b/rair-front/src/components/MockUpPage/NftList/NftData/NftDataPage.tsx deleted file mode 100644 index 3eb9afa11..000000000 --- a/rair-front/src/components/MockUpPage/NftList/NftData/NftDataPage.tsx +++ /dev/null @@ -1,549 +0,0 @@ -//@ts-nocheck -//unused-component -import React, { useCallback, useEffect, useState } from 'react'; -import { - Accordion, - AccordionItem, - AccordionItemButton, - AccordionItemHeading, - AccordionItemPanel -} from 'react-accessible-accordion'; -import Carousel from 'react-multi-carousel'; -import { useNavigate, useParams } from 'react-router-dom'; - -import { rFetch } from '../../../../utils/rFetch'; -import ItemRank from '../../SelectBox/ItemRank'; -import SelectBox from '../../SelectBox/SelectBox'; -import OfferItem from '../OfferItem'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faLock } from '@fortawesome/free-solid-svg-icons'; - -const NftDataPage = ({ primaryColor, textColor }) => { - const navigate = useNavigate(); - const params = useParams(); - const { adminToken, contract, product, token, offer } = params; - - const [data, setData] = useState(); - const [tokenData, _setTokenData] = useState([]); - const setTokenData = useCallback( - (tokenDataToSet) => { - _setTokenData(tokenDataToSet); - }, - [_setTokenData] - ); - const [offerPrice, setOfferPrice] = useState([]); - const [selectedToken, setSelectedToken] = useState(token); - // const [allProducts, setAllProducts] = useState([]); - - // const [contractAddress, setContractAddress] = useState(); - - // console.log(params, "params"); - - const responsive = { - superLargeDesktop: { - breakpoint: { max: 4000, min: 3000 }, - items: 4 - }, - desktop: { - breakpoint: { max: 3000, min: 1024 }, - paddingLeft: '2rem', - items: 4 - }, - tablet: { - breakpoint: { max: 1024, min: 464 }, - items: 2 - }, - mobile: { - breakpoint: { max: 464, min: 0 }, - items: 1 - } - }; - - const handleClickToken = () => { - navigate(`/${adminToken}/${contract}/${product}/${offer}/${selectedToken}`); - }; - - function randomInteger(min, max) { - const rand = min + Math.random() * (max + 1 - min); - return Math.floor(rand); - } - - function percentToRGB(percent) { - if (percent) { - if (percent < 15) { - return '#95F619'; - } else if (15 <= percent && percent < 35) { - return '#F6ED19'; - } else { - return '#F63419'; - } - } - // if (percent === 100) { - // percent = 99; - // } - // let r, g, b; - - // if (percent < 50) { - // // green to yellow - // r = Math.floor(255 * (percent / 50)); - // g = 255; - // } else { - // // yellow to red - // r = 255; - // g = Math.floor(255 * ((50 - (percent % 50)) / 50)); - // } - // b = 0; - - // return "rgb(" + r + "," + g + "," + b + ")"; - } - function toUpper(string) { - if (string) { - return string[0].toUpperCase() + string.slice(1); - } - } - - function arrayMin(arr) { - let len = arr.length, - min = Infinity; - while (len--) { - if (arr[len] < min) { - min = arr[len]; - } - } - return min; - } - - function arrayMax(arr) { - let len = arr.length, - max = -Infinity; - while (len--) { - if (arr[len] > max) { - max = arr[len]; - } - } - return max; - } - - const minPrice = arrayMin(offerPrice); - const maxPrice = arrayMax(offerPrice); - - const getData = useCallback(async () => { - if (adminToken && contract && product) { - const { success, result } = await rFetch( - `/api/${adminToken}/${contract}/${product}` - ); - - const tokenMapping = {}; - - if (success) { - result.tokens.forEach((item) => { - tokenMapping[item.token] = item; - }); - } - - setTokenData(tokenMapping); - - setData(response.result); - - setOfferPrice( - response.result.product.products.offers.map((p) => p.price) - ); - - // setContractAddress(response.result.product.contractAddress) - // return response.result; - } else return null; - }, [adminToken, contract, product, setTokenData]); - - const getAllProduct = useCallback(async () => { - const { success, result } = await rFetch(`/api/nft/${contract}/${product}`); - - const tokenMapping = {}; - - if (success) { - result.tokens.forEach((item) => { - tokenMapping[item.token] = item; - }); - setTokenData(tokenMapping); - } - - setData(responseAllProduct); - setSelectedToken(0); - // if (!Object.keys(params).length) - // setSelected(responseAllProduct.result[0].metadata); - }, [product, contract, setTokenData]); - - useEffect(() => { - getData(); - getAllProduct(); - }, [getData, getAllProduct]); - - if (!tokenData[selectedToken]) { - return 'No token, sorry, go away:('; - } - if (!data?.tokens) { - return 'No data.tokens, sorry :('; - } - - return ( -
    - {tokenData && data && ( -
    - {/* */} -
    -
    -

    - {tokenData[selectedToken]?.metadata.name} -

    -
    - -
    -
    -
    -
    -
    - Price range -
    - NFT powered by Rair Tech - - {minPrice} – {maxPrice} ETH - - - ERC - -
    -
    -
    - Item rank -
    - -
    -
    -
    - Serial number -
    - { - return { - value: p.metadata.name, - id: p._id, - token: p.token - }; - }) - }> -
    -
    -
    - -
    -
    - - - - Properties - - -
    - {tokenData[selectedToken].metadata - ? Object.keys(tokenData[selectedToken]).length && - tokenData[selectedToken].metadata?.attributes.map( - (item, index) => { - if (item.trait_type === 'External URL') { - return ( -
    - {item?.trait_type}: -
    - - {item?.value} - -
    - ); - } - const percent = randomInteger(1, 40); - return ( -
    -
    - {item?.trait_type}: - - {item?.value} - -
    - - {percent} % - -
    - ); - } - ) - : null} -
    -
    -
    - - - Description - - -
    -
    - {toUpper(tokenData[selectedToken].metadata?.artist)} -
    -
    - {tokenData[selectedToken].metadata?.description} -
    - -
    -
    -
    - - - Unlockable content - - -
    -
    -
    -
    - -

    - Coming soon -

    -
    - NFT powered by Rair Tech -
    -
    -
    - {' '} -

    Video {data?.tokens[0].metadata?.name}

    {' '} -
    -
    -

    - 00:03:23 -

    -
    -
    -
    -
    -
    -
    - {/* - - Collection info - - VIDEO - */} - - - Authenticity - - Link - -
    -
    -
    - {tokenData && ( - - {tokenData.map((p, index) => ( - - ))} - - )} -
    -
    - )} -
    - ); -}; - -export default NftDataPage; diff --git a/rair-front/src/components/MockUpPage/NftList/NftData/NftDataPageMain.tsx b/rair-front/src/components/MockUpPage/NftList/NftData/NftDataPageMain.tsx index 14bdc8749..407aaaec2 100644 --- a/rair-front/src/components/MockUpPage/NftList/NftData/NftDataPageMain.tsx +++ b/rair-front/src/components/MockUpPage/NftList/NftData/NftDataPageMain.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'; import ReactPlayer from 'react-player'; -import { useDispatch, useSelector } from 'react-redux'; +import { useParams } from 'react-router'; import { faKey } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import axios from 'axios'; @@ -11,15 +11,15 @@ import SingleTokenViewProperties from './SingleTokenViewProperties'; import { TitleSingleTokenView } from './TitleSingleTokenView'; import UnlockableVideosSingleTokenPage from './UnlockableVideosSingleTokenPage'; -import { TFileType, TNftItemResponse } from '../../../../axios.responseTypes'; -import { RootState } from '../../../../ducks'; -import { ColorStoreType } from '../../../../ducks/colors/colorStore.types'; -import { setShowSidebarTrue } from '../../../../ducks/metadata/actions'; -import { InitialNftDataStateType } from '../../../../ducks/nftData/nftData.types'; import useIPFSImageLink from '../../../../hooks/useIPFSImageLink'; +import { + useAppDispatch, + useAppSelector +} from '../../../../hooks/useReduxHooks'; import { ExpandImageIcon } from '../../../../images'; +import { tokenNumbersResponse } from '../../../../types/apiResponseTypes'; +import { CatalogVideoItem } from '../../../../types/commonTypes'; import { checkIPFSanimation } from '../../../../utils/checkIPFSanimation'; -import { rFetch } from '../../../../utils/rFetch'; import setDocumentTitle from '../../../../utils/setTitle'; import LoadingComponent from '../../../common/LoadingComponent'; import PlayCircle from '../../assets/PlayCircle.svg?react'; @@ -29,7 +29,6 @@ import { BreadcrumbsView } from '../Breadcrumbs/Breadcrumbs'; import { changeIPFSLink } from '../utils/changeIPFSLink'; import TitleCollection from './TitleCollection/TitleCollection'; -import { useParams } from 'react-router'; const NftDataPageMain: React.FC = ({ blockchain, @@ -40,22 +39,19 @@ const NftDataPageMain: React.FC = ({ selectedData, selectedToken, setSelectedToken, - totalCount, - textColor, offerData, offerDataInfo, someUsersData, ownerInfo, embeddedParams, - setTokenNumber, - getProductsFromOffer + setTokenNumber }) => { - const { tokenData } = useSelector( - (state) => state.nftDataStore - ); - const {tokenId} = useParams(); + const { currentCollection } = useAppSelector((state) => state.tokens); + const { tokenId } = useParams(); - const [selectVideo, setSelectVideo] = useState(); + const [selectVideo, setSelectVideo] = useState< + CatalogVideoItem | undefined + >(); const [openVideoplayer, setOpenVideoPlayer] = useState(false); const [verticalImage, setVerticalImage] = useState(false); const [isFileUrl, setIsFileUrl] = useState(); @@ -63,37 +59,15 @@ const NftDataPageMain: React.FC = ({ const hotdropsVar = import.meta.env.VITE_TESTNET === 'true'; const [serialNumberData, setSerialNumberData] = useState([]); const [playing, setPlaying] = useState(false); - const [tokenDataForResale, setTokenDataForResale] = useState(undefined); const [, /*offersIndexesData*/ setOffersIndexesData] = useState(); const handlePlaying = () => { setPlaying((prev) => !prev); }; - const { primaryColor } = useSelector( - (store) => store.colorStore - ); + const { primaryColor, isDarkMode } = useAppSelector((store) => store.colors); - const [tokenFullData, setTokenFullData] = useState(undefined); - const dispatch = useDispatch(); - - const getTokenData = useCallback(async () => { - if (tokenData && tokenId) { - const response = await rFetch( - `/api/tokens/id/${tokenData[0]._id}`, - undefined, - undefined, - undefined - ); - if (response.success) { - setTokenDataForResale(response.tokenData); - } - } - }, [tokenData, selectedToken]); - - useEffect(() => { - getTokenData(); - }, [getTokenData]); + const dispatch = useAppDispatch(); useEffect(() => { if (productsFromOffer) { @@ -155,59 +129,19 @@ const NftDataPageMain: React.FC = ({ setOpenVideoPlayer(true); }; - const fetchSerialNumberData = useCallback( async() => { - if(tokenId) { - const { data } = await axios.get( - `/api/nft/network/${blockchain}/${contract}/${product}/numbers` - ); - - if(data.success && data?.tokens) { - setSerialNumberData(data.tokens); - } - - } - }, []) - - useEffect(() => { - fetchSerialNumberData(); - }, [fetchSerialNumberData]) - - const fetchTokenOneData = useCallback( async() => { - if(tokenId) { - const { data } = await axios.get( - `/api/nft/network/${blockchain}/${contract}/${product}?fromToken=${tokenId}&toToken=${tokenId}` - ); - } - }, [tokenId]) - - useEffect(() => { - fetchTokenOneData(); - }, [fetchTokenOneData]) - - const fetchTokenFullData = useCallback(async () => { - const { data } = await axios.get( - `/api/nft/network/${blockchain}/${contract}/${product}?fromToken=${tokenId}&toToken=${tokenId}` + const fetchSerialNumberData = useCallback(async () => { + const { data } = await axios.get( + `/api/nft/network/${blockchain}/${contract}/${product}/numbers` ); - if (data.success && tokenId) { - const response = await axios.get( - `/api/nft/network/${blockchain}/${contract}/${product}?fromToken=${tokenId}&toToken=${tokenId}` - ); - - const mapping = {}; - response.data.result.tokens.forEach((token) => { - mapping[token.token] = token; - }); - - setTokenFullData(mapping); - getProductsFromOffer(); + if (data.success && data?.tokens) { + setSerialNumberData(data.tokens); } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [blockchain, contract, product, setTokenFullData, tokenId]); + }, [blockchain, contract, product]); useEffect(() => { - fetchTokenFullData(); - }, [fetchTokenFullData]); + fetchSerialNumberData(); + }, [fetchSerialNumberData]); useEffect(() => { checkSizeImage(); @@ -221,7 +155,6 @@ const NftDataPageMain: React.FC = ({ useEffect(() => { setDocumentTitle('Single Token'); - dispatch(setShowSidebarTrue()); }, [dispatch]); useEffect(() => { @@ -262,13 +195,13 @@ const NftDataPageMain: React.FC = ({ }, [offerDataInfo]); useEffect(() => { - if (selectedToken) { + if (selectedToken && setTokenNumber) { setTokenNumber(Number(selectedToken)); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedToken]); - if (!selectedData?.name) { + if (!selectedData?.name || !tokenId) { return ; } @@ -288,7 +221,6 @@ const NftDataPageMain: React.FC = ({
    = ({ = ({ blockchain={blockchain} contract={contract} selectedToken={selectedToken} - currentTokenId={ - tokenDataForResale && tokenDataForResale?._id - } + currentTokenId={currentCollection?.[tokenId]?._id} classTitle={ selectedData?.animation_url && isFileUrl !== 'gif' ? 'nft-collection-single-video' @@ -412,29 +340,17 @@ const NftDataPageMain: React.FC = ({ )}
    - {tokenFullData === undefined ? ( - - ) : ( - - )} +
    - +
    = ({ )}
    - +
    {selectedData?.attributes && selectedData?.attributes?.length > 0 ? ( - + ) : (
    {`This ${ @@ -473,7 +383,7 @@ const NftDataPageMain: React.FC = ({
    {productsFromOffer && productsFromOffer.length > 0 ? ( @@ -494,7 +404,6 @@ const NftDataPageMain: React.FC = ({ openVideoplayer={openVideoplayer} setOpenVideoPlayer={setOpenVideoPlayer} handlePlayerClick={handlePlayerClick} - primaryColor={primaryColor} />
    diff --git a/rair-front/src/components/MockUpPage/NftList/NftData/NftListUnlockablesVideos.tsx b/rair-front/src/components/MockUpPage/NftList/NftData/NftListUnlockablesVideos.tsx index 3df508704..b4a611f16 100644 --- a/rair-front/src/components/MockUpPage/NftList/NftData/NftListUnlockablesVideos.tsx +++ b/rair-front/src/components/MockUpPage/NftList/NftData/NftListUnlockablesVideos.tsx @@ -1,10 +1,8 @@ -import { useSelector } from 'react-redux'; import { useNavigate } from 'react-router-dom'; - -import { RootState } from '../../../../ducks'; -import { ColorStoreType } from '../../../../ducks/colors/colorStore.types'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faLock } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; + +import { useAppSelector } from '../../../../hooks/useReduxHooks'; // import NftDifferentRarity from "./UnlockablesPage/NftDifferentRarity/NftDifferentRarity"; const NftListUnlockablesVideos = ({ @@ -21,9 +19,7 @@ const NftListUnlockablesVideos = ({ ? productsFromOffer.slice(0, 2) : 0; - const { primaryColor, textColor } = useSelector( - (store) => store.colorStore - ); + const { primaryColor, textColor } = useAppSelector((store) => store.colors); return (
    diff --git a/rair-front/src/components/MockUpPage/NftList/NftData/NftSingleUnlockables.tsx b/rair-front/src/components/MockUpPage/NftList/NftData/NftSingleUnlockables.tsx index 75f8382fd..ca88a4db1 100644 --- a/rair-front/src/components/MockUpPage/NftList/NftData/NftSingleUnlockables.tsx +++ b/rair-front/src/components/MockUpPage/NftList/NftData/NftSingleUnlockables.tsx @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react'; import { faLock } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { useAppSelector } from '../../../../hooks/useReduxHooks'; import { ImageLazy } from '../../ImageLazy/ImageLazy'; import { INftSingleUnlockables, @@ -17,10 +18,10 @@ const NftSingleUnlockables: React.FC = ({ embeddedParams, productsFromOffer, setTokenDataFiltered, - primaryColor, setSelectVideo, isDiamond }) => { + const { primaryColor } = useAppSelector((store) => store.colors); const [sections, setSections] = useState(null); const [rarity, setRarity] = useState([ @@ -41,7 +42,7 @@ const NftSingleUnlockables: React.FC = ({ useEffect(() => { const result = productsFromOffer?.reduce((acc, item) => { if (isDiamond) { - const key = item.offer.length; + const key = item.unlockData.offers.length; const value = acc[key]; if (value) { @@ -52,7 +53,7 @@ const NftSingleUnlockables: React.FC = ({ return acc; } - const key = item.offer[0]; + const key = item.unlockData.offers[0]._id!; const value = acc[key]; if (value) { diff --git a/rair-front/src/components/MockUpPage/NftList/NftData/NftUnlockablesPage.tsx b/rair-front/src/components/MockUpPage/NftList/NftData/NftUnlockablesPage.tsx index 11459a105..fd7389f92 100644 --- a/rair-front/src/components/MockUpPage/NftList/NftData/NftUnlockablesPage.tsx +++ b/rair-front/src/components/MockUpPage/NftList/NftData/NftUnlockablesPage.tsx @@ -1,10 +1,13 @@ import React, { useEffect, useRef, useState } from 'react'; -import { useDispatch } from 'react-redux'; import NftSingleUnlockables from './NftSingleUnlockables'; -import { TFileType } from '../../../../axios.responseTypes'; -import { setShowSidebarTrue } from '../../../../ducks/metadata/actions'; +import { + useAppDispatch, + useAppSelector +} from '../../../../hooks/useReduxHooks'; +import { CatalogVideoItem } from '../../../../types/commonTypes'; +import { MediaFile } from '../../../../types/databaseTypes'; import setDocumentTitle from '../../../../utils/setTitle'; import LoadingComponent from '../../../common/LoadingComponent'; import CustomButton from '../../utils/button/CustomButton'; @@ -17,23 +20,22 @@ import VideoPlayerView from './UnlockablesPage/VideoPlayerView'; const NftUnlockablesPage: React.FC = ({ embeddedParams, productsFromOffer, - primaryColor, selectedToken, - tokenData, someUsersData, collectionName, setTokenDataFiltered }) => { - const [selectVideo, setSelectVideo] = useState(); + const [selectVideo, setSelectVideo] = useState(); const [isDiamond, setIsDiamond] = useState(undefined); const myRef = useRef(null); - const dispatch = useDispatch(); + const { currentCollection } = useAppSelector((store) => store.tokens); + + const dispatch = useAppDispatch(); useEffect(() => { setDocumentTitle('Unlockables'); - dispatch(setShowSidebarTrue()); }, [dispatch]); useEffect(() => { @@ -46,10 +48,10 @@ const NftUnlockablesPage: React.FC = ({ }, []); useEffect(() => { - if (tokenData && Object.keys(tokenData).length > 0) { - setIsDiamond(tokenData[0].offer.diamond); + if (currentCollection && Object.keys(currentCollection).length > 0) { + setIsDiamond(currentCollection[0].offer.diamond); } - }, [tokenData]); + }, [currentCollection]); useEffect(() => { if (productsFromOffer) { @@ -64,18 +66,16 @@ const NftUnlockablesPage: React.FC = ({ return (
    - {tokenData && selectedToken && ( + {currentCollection && selectedToken && ( )}
    = ({ productsFromOffer={productsFromOffer} setSelectVideo={setSelectVideo} setTokenDataFiltered={setTokenDataFiltered} - primaryColor={primaryColor} isDiamond={isDiamond} />
    diff --git a/rair-front/src/components/MockUpPage/NftList/NftData/SellButton.tsx b/rair-front/src/components/MockUpPage/NftList/NftData/SellButton.tsx index b6b88f55d..0e7b4c16d 100644 --- a/rair-front/src/components/MockUpPage/NftList/NftData/SellButton.tsx +++ b/rair-front/src/components/MockUpPage/NftList/NftData/SellButton.tsx @@ -1,28 +1,22 @@ -import React, { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; -import { useParams } from 'react-router'; +import { FC, memo, useCallback } from 'react'; import { NavLink } from 'react-router-dom'; -import axios from 'axios'; -import { constants, utils } from 'ethers'; -import { parseEther } from 'ethers/lib/utils'; +import { parseEther } from 'ethers'; +import { Hex } from 'viem'; import { BuySellButton } from './BuySellButton'; -import { TUserResponse } from '../../../../axios.responseTypes'; import { erc721Abi } from '../../../../contracts'; -import { RootState } from '../../../../ducks'; -import { ContractsInitialType } from '../../../../ducks/contracts/contracts.types'; -import { UserType } from '../../../../ducks/users/users.types'; +import useContracts from '../../../../hooks/useContracts'; +import { useAppSelector } from '../../../../hooks/useReduxHooks'; +import useServerSettings from '../../../../hooks/useServerSettings'; import useSwal from '../../../../hooks/useSwal'; import useWeb3Tx from '../../../../hooks/useWeb3Tx'; import { rFetch } from '../../../../utils/rFetch'; -import useServerSettings from '../../../adminViews/useServerSettings'; import defaultImage from '../../../UserProfileSettings/images/defaultUserPictures.png'; import { ImageLazy } from '../../ImageLazy/ImageLazy'; import { ISellButton } from '../../mockupPage.types'; -const SellButton: React.FC = ({ - tokenData, +const SellButton: FC = ({ selectedToken, sellingPrice, isInputPriceExist, @@ -31,46 +25,51 @@ const SellButton: React.FC = ({ item, singleTokenPage }) => { - const { contractCreator, currentUserAddress, diamondMarketplaceInstance } = - useSelector( - (store) => store.contractStore - ); - - let { blockchain, contract, tokenId } = useParams(); - const [accountData, setAccountData] = useState(null); + const { contractCreator, diamondMarketplaceInstance } = useContracts(); + const { currentUserAddress } = useAppSelector((store) => store.web3); + const { currentCollection, currentCollectionMetadata } = useAppSelector( + (store) => store.tokens + ); const xMIN = Number(0.0001); const yMAX = item?.contract?.blockchain === '0x1' ? 10 : 10000.0; - if (!blockchain && !contract && !tokenId) { - blockchain = item.contract.blockchain; - contract = item.contract.contractAddress; - tokenId = item.uniqueIndexInContract; - } + const blockchain = + item?.contract?.blockchain || + currentCollectionMetadata?.contract?.blockchain; + const contract = + item?.contract?.contractAddress || + currentCollectionMetadata?.contract?.contractAddress; + const tokenId = item?.uniqueIndexInContract; const reactSwal = useSwal(); const { web3TxHandler, web3Switch, correctBlockchain } = useWeb3Tx(); - const { nodeAddress, settings, getBlockchainData } = useServerSettings(); + const { getBlockchainData } = useServerSettings(); + const { nodeAddress, databaseResales } = useAppSelector( + (store) => store.settings + ); const handleClickSellButton = useCallback(async () => { - if (!correctBlockchain(blockchain as BlockchainType)) { - web3Switch(blockchain as BlockchainType); + if (!correctBlockchain(blockchain as Hex)) { + web3Switch(blockchain as Hex); return; } - const tokenInformation = - item || (selectedToken && tokenData?.[selectedToken]); + const tokenInformation = item || { + ...(selectedToken && currentCollection?.[selectedToken]), + contract: currentCollectionMetadata + }; if ( !contractCreator || !sellingPrice || !blockchain || - !getBlockchainData(blockchain as `0x${string}`) || - !correctBlockchain(blockchain as BlockchainType) || + !getBlockchainData(blockchain as Hex) || + !correctBlockchain(blockchain as Hex) || !diamondMarketplaceInstance || !tokenInformation ) { return; } - const instance = contractCreator(contract, erc721Abi); + const instance = contractCreator(contract as Hex, erc721Abi); if (!instance) { return; } @@ -82,7 +81,7 @@ const SellButton: React.FC = ({ }); const isApprovedForAll = await web3TxHandler(instance, 'isApprovedForAll', [ currentUserAddress, - diamondMarketplaceInstance.address + await diamondMarketplaceInstance.getAddress() ]); if (!isApprovedForAll) { reactSwal.fire({ @@ -95,10 +94,10 @@ const SellButton: React.FC = ({ !(await web3TxHandler( instance, 'setApprovalForAll', - [diamondMarketplaceInstance.address, true], + [await diamondMarketplaceInstance.getAddress(), true], { - intendedBlockchain: item.contract.blockchain, - sponsored: tokenInformation.range.sponsored + intendedBlockchain: tokenInformation.contract.blockchain, + sponsored: tokenInformation.offer.sponsored } )) ) { @@ -112,14 +111,14 @@ const SellButton: React.FC = ({ } reactSwal.fire({ title: 'Creating resale offer', - html: `Posting NFT #${tokenId} up for sale with price ${sellingPrice} ${getBlockchainData( - blockchain as `0x${string}` - )?.symbol}`, + html: `Posting NFT #${tokenId} up for sale with price ${sellingPrice} ${ + getBlockchainData(blockchain as `0x${string}`)?.symbol + }`, icon: 'info', showConfirmButton: false }); let response; - if (settings.databaseResales) { + if (databaseResales) { response = await rFetch(`/api/resales/create`, { method: 'POST', body: JSON.stringify({ @@ -144,14 +143,14 @@ const SellButton: React.FC = ({ nodeAddress // Node address ], { - intendedBlockchain: item.contract.blockchain, - sponsored: tokenInformation.range.sponsored + intendedBlockchain: tokenInformation.contract.blockchain, + sponsored: tokenInformation.offer.sponsored } ) ) { response = { success: true }; } - if (response.success) { + if (response?.success) { reactSwal.fire({ title: 'Success', html: `Users will be able to purchase your NFT on the marketplace`, @@ -173,67 +172,23 @@ const SellButton: React.FC = ({ web3TxHandler, refreshResaleData, item, - tokenData, + currentCollection, selectedToken, nodeAddress, - settings, - getBlockchainData + getBlockchainData, + databaseResales, + currentCollectionMetadata ]); const openInputField = useCallback(() => { setIsInputPriceExist(true); }, [setIsInputPriceExist]); - const getInfoFromUser = useCallback(async () => { - // find user - if ( - !item && - selectedToken && - tokenData?.[selectedToken]?.ownerAddress && - utils.isAddress(tokenData?.[selectedToken]?.ownerAddress) && - tokenData?.[selectedToken]?.ownerAddress !== constants.AddressZero - ) { - try { - const result = await axios - .get( - `/api/users/${tokenData?.[selectedToken]?.ownerAddress}` - ) - .then((res) => res.data); - if (result.success) { - setAccountData(result.user); - } - } catch (e) { - setAccountData(null); - } - } else { - if ( - item && - utils.isAddress(item.ownerAddress) && - item.ownerAddress !== constants.AddressZero - ) { - try { - const result = await axios - .get(`/api/users/${item.ownerAddress}`) - .then((res) => res.data); - if (result.success) { - setAccountData(result.user); - } - } catch (e) { - setAccountData(null); - } - } - } - }, [selectedToken, setAccountData, tokenData, item]); - - useEffect(() => { - getInfoFromUser(); - }, [getInfoFromUser]); - const sellButton = useCallback(() => { if ( selectedToken && - currentUserAddress === tokenData?.[selectedToken]?.ownerAddress && - tokenData?.[selectedToken]?.isMinted + currentUserAddress === currentCollection?.[selectedToken]?.ownerAddress && + currentCollection?.[selectedToken]?.isMinted ) { return ( = ({ } /> ); - } else { + } else if (selectedToken) { + const ownerData = currentCollection?.[selectedToken].ownerData; return (
    Owned by{' '}
    {selectedToken && ( - +
    - {(accountData && - accountData.nickName && - accountData.nickName.length > 20 - ? accountData.nickName.slice(0, 5) + - '....' + - accountData.nickName.slice(length - 4) - : accountData && accountData.nickName) || - (tokenData?.[selectedToken]?.ownerAddress && - tokenData?.[selectedToken]?.ownerAddress.slice(0, 4) + - '....' + - tokenData?.[selectedToken]?.ownerAddress.slice( - length - 4 - ))} + {(ownerData && + ownerData.nickName && + ownerData.nickName.length > 20 + ? ownerData.nickName.slice(0, 5) + + '...' + + ownerData.nickName.slice(length - 4) + : ownerData && ownerData.nickName) || + (currentCollection?.[selectedToken]?.ownerAddress && + currentCollection?.[selectedToken]?.ownerAddress.slice( + 0, + 4 + ) + + '...' + + currentCollection?.[ + selectedToken + ]?.ownerAddress.slice(length - 4))}
    )} @@ -307,12 +267,11 @@ const SellButton: React.FC = ({ openInputField, sellingPrice, selectedToken, - tokenData, - isInputPriceExist, - accountData + currentCollection, + isInputPriceExist ]); return sellButton(); }; -export default React.memo(SellButton); +export default memo(SellButton); diff --git a/rair-front/src/components/MockUpPage/NftList/NftData/SellInputButton.tsx b/rair-front/src/components/MockUpPage/NftList/NftData/SellInputButton.tsx index 3ffa88ae7..89cd54701 100644 --- a/rair-front/src/components/MockUpPage/NftList/NftData/SellInputButton.tsx +++ b/rair-front/src/components/MockUpPage/NftList/NftData/SellInputButton.tsx @@ -1,24 +1,19 @@ -import React, { useCallback, useState } from 'react'; -import { useSelector } from 'react-redux'; +import { FC, useCallback, useState } from 'react'; import CloseIcon from '@mui/icons-material/Close'; import SellButton from './SellButton'; -import { RootState } from '../../../../ducks'; -import { ColorStoreType } from '../../../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../../../hooks/useReduxHooks'; import InputField from '../../../common/InputField'; import { ISellInputButton } from '../../mockupPage.types'; -const SellInputButton: React.FC = ({ - tokenData, +const SellInputButton: FC = ({ selectedToken, refreshResaleData }) => { const [inputSellValue, setInputSellValue] = useState(''); const [isInputPriceExist, setIsInputPriceExist] = useState(false); - const { textColor, iconColor } = useSelector( - (store) => store.colorStore - ); + const { textColor, iconColor } = useAppSelector((store) => store.colors); const handleInputClear = useCallback(() => { if (inputSellValue) { @@ -40,14 +35,12 @@ const SellInputButton: React.FC = ({ placeholder="Your price" /> = ({
    )} = ({ - tokenData, handleClickToken, blockchain, - product, - contract, - totalCount, selectedToken, setSelectedToken, offerData, - handleTokenBoughtButton, - tokenDataForResale + tokenDataForResale, + serialNumberData }) => { - const { - minterInstance, - diamondMarketplaceInstance, - currentUserAddress, - coingeckoRates - } = useSelector( - (state) => state.contractStore + const { diamondMarketplaceInstance } = useContracts(); + const { currentUserAddress, exchangeRates } = useAppSelector( + (state) => state.web3 ); - - const { primaryColor, textColor } = useSelector( - (store) => store.colorStore + const { primaryColor } = useAppSelector((store) => store.colors); + const { databaseResales } = useAppSelector((store) => store.settings); + const { currentCollection, currentCollectionMetadata } = useAppSelector( + (store) => store.tokens ); + const dispatch = useAppDispatch(); + const reactSwal = useSwal(); const { web3TxHandler, correctBlockchain, web3Switch } = useWeb3Tx(); - const numberTooBigThreshold = BigNumber.from(10000000000); + const numberTooBigThreshold = BigInt(10000000000); - const [accountData, setAccountData] = useState(null); const [contractData, setContractData] = useState(); const [resaleData, setResaleData] = useState(); const params = useParams(); - const getInfoFromUser = useCallback(async () => { - // find user + const buyContract = useCallback(async () => { if ( - params.tokenId && tokenData && - Object.values(tokenData)[0]?.ownerAddress && - utils.isAddress(Object.values(tokenData)[0]?.ownerAddress) && - Object.values(tokenData)[0]?.ownerAddress !== constants.AddressZero + !contractData || + !offerData || + !contractData.diamond || + !diamondMarketplaceInstance || + !selectedToken || + !currentCollectionMetadata.product ) { - try { - const result = await axios - .get( - `/api/users/${Object.values(tokenData)[0]?.ownerAddress}` - ) - .then((res) => res.data); - if (result.success) { - setAccountData(result.user); - } - } catch (e) { - setAccountData(null); - } - } - }, [params.tokenId, setAccountData, tokenData]); - - const buyContract = useCallback(async () => { - if (!contractData || !offerData) { return; } - let marketplaceContract, marketplaceMethod, marketplaceArguments; - if (contractData.diamond) { - if (!diamondMarketplaceInstance) { - return; - } - marketplaceContract = diamondMarketplaceInstance; - marketplaceMethod = 'buyMintingOffer'; - marketplaceArguments = [ - offerData.offerIndex, // Offer Index - selectedToken // Token Index - ]; - } else { - if (!minterInstance) { - return; - } - marketplaceContract = minterInstance; - marketplaceMethod = 'buyToken'; - marketplaceArguments = [ - offerData?.offerPool, // Catalog Index - offerData?.offerIndex, // Range Index - selectedToken // Internal Token Index - ]; - } + const realNumber = ( + BigInt(selectedToken) - + BigInt(currentCollectionMetadata.product?.firstTokenIndex) + ).toString(); + const marketplaceContract = diamondMarketplaceInstance; + const marketplaceMethod = 'buyMintingOffer'; + const marketplaceArguments: any[] = [ + offerData.offerIndex, // Offer Index + realNumber // Token Index + ]; marketplaceArguments.push({ value: offerData.price }); @@ -135,10 +101,16 @@ const SerialNumberBuySell: React.FC = ({ marketplaceMethod, marketplaceArguments, { - intendedBlockchain: blockchain as BlockchainType, + intendedBlockchain: blockchain as Hex, failureMessage: 'Sorry your transaction failed! When several people try to buy at once - only one transaction can get to the blockchain first. Please try again!', - callback: handleTokenBoughtButton, + callback: () => { + dispatch( + reloadTokenData({ + tokenId: currentCollection?.[selectedToken]?._id + }) + ); + }, sponsored: offerData.sponsored } ) @@ -148,21 +120,21 @@ const SerialNumberBuySell: React.FC = ({ 'Now, you are the owner of this token', 'success' ); - handleTokenBoughtButton(); } }, [ contractData, offerData, + diamondMarketplaceInstance, + selectedToken, reactSwal, web3TxHandler, blockchain, - handleTokenBoughtButton, - diamondMarketplaceInstance, - selectedToken, - minterInstance + dispatch, + currentCollection, + currentCollectionMetadata ]); - const { settings, getBlockchainData } = useServerSettings(); + const { getBlockchainData } = useServerSettings(); useEffect(() => { if (offerData) { @@ -179,7 +151,8 @@ const SerialNumberBuySell: React.FC = ({ if ( !diamondMarketplaceInstance || !selectedToken || - tokenData && !Object.values(tokenData)[0].uniqueIndexInContract + (currentCollection && + !currentCollection[selectedToken]?.uniqueIndexInContract) ) { return; } @@ -195,7 +168,9 @@ const SerialNumberBuySell: React.FC = ({ } setResaleData(undefined); const resaleResponse = await rFetch( - `/api/resales/open?contract=${params.contract}&blockchain=${params.blockchain}&index=${tokenData && Object.values(tokenData)[0].uniqueIndexInContract}` + `/api/resales/open?contract=${params.contract}&blockchain=${ + params.blockchain + }&index=${currentCollection[selectedToken].uniqueIndexInContract}` ); if (!resaleResponse.success) { return; @@ -215,25 +190,25 @@ const SerialNumberBuySell: React.FC = ({ diamondMarketplaceInstance, params.contract, params.blockchain, - tokenData, - selectedToken, - params.tokenId + currentCollection, + selectedToken ]); useEffect(() => { getResaleData(); }, [getResaleData]); - useEffect(() => { - getInfoFromUser(); - }, [getInfoFromUser]); - const resalePurchase = useCallback(async () => { - if (!correctBlockchain(blockchain as BlockchainType)) { - web3Switch(blockchain as BlockchainType); + if (!correctBlockchain(blockchain)) { + web3Switch(blockchain); return; } - if (!diamondMarketplaceInstance || !tokenData || !params?.tokenId) { + if ( + !selectedToken || + !diamondMarketplaceInstance || + !currentCollection || + !params?.tokenId + ) { return; } /* @@ -250,7 +225,7 @@ const SerialNumberBuySell: React.FC = ({ } */ const { isConfirmed } = await reactSwal.fire({ - imageUrl: Object.values(tokenData)[0].metadata.image, + imageUrl: currentCollection[selectedToken].metadata.image, imageHeight: '25vh', title: 'Purchase token', html: <>Currently owned by: {resaleData.seller}, @@ -265,7 +240,7 @@ const SerialNumberBuySell: React.FC = ({ icon: 'info', showConfirmButton: false }); - if (settings.databaseResales) { + if (databaseResales) { const { success, hash } = await rFetch( `/api/resales/purchase/${resaleData._id}` ); @@ -277,7 +252,7 @@ const SerialNumberBuySell: React.FC = ({ [ params.contract, // address erc721, currentUserAddress, // address buyer, - Object.values(tokenData)[0]?.ownerAddress, // address seller, + currentCollection[selectedToken]?.ownerAddress, // address seller, resaleData.tokenIndex, // uint token, resaleData.price, // uint tokenPrice, import.meta.env.VITE_NODE_ADDRESS, // address nodeAddress, @@ -287,9 +262,13 @@ const SerialNumberBuySell: React.FC = ({ { callback: () => { getResaleData(); - handleTokenBoughtButton(); + dispatch( + reloadTokenData({ + tokenId: currentCollection?.[selectedToken]?._id + }) + ); }, - intendedBlockchain: blockchain as BlockchainType + intendedBlockchain: blockchain } )) ) { @@ -306,20 +285,21 @@ const SerialNumberBuySell: React.FC = ({ reactSwal.fire('Success', 'Token purchased', 'success'); } }, [ - web3Switch, + correctBlockchain, + blockchain, diamondMarketplaceInstance, + currentCollection, + params?.tokenId, + params.contract, reactSwal, resaleData, + selectedToken, + databaseResales, web3TxHandler, - handleTokenBoughtButton, - blockchain, - params, + web3Switch, currentUserAddress, - selectedToken, - tokenData, getResaleData, - correctBlockchain, - settings.databaseResales + dispatch ]); const checkAllSteps = useCallback(() => { @@ -330,33 +310,36 @@ const SerialNumberBuySell: React.FC = ({ if (!currentUserAddress) { if ( selectedToken && - tokenData && - Object.values(tokenData)[0]?.isMinted === true + currentCollection && + currentCollection[selectedToken]?.isMinted === true ) { + const tokenData = currentCollection[selectedToken]; return (
    Owned by{' '}
    {selectedToken && ( - +
    - {(accountData && - accountData.nickName && - accountData.nickName.length > 20 - ? accountData.nickName.slice(0, 5) + - '....' + - accountData.nickName.slice(length - 4) - : accountData && accountData.nickName) || - (Object.values(tokenData)[0]?.ownerAddress && - Object.values(tokenData)[0]?.ownerAddress.slice(0, 4) + - '....' + - Object.values(tokenData)[0]?.ownerAddress.slice( - length - 4 - ))} + {(tokenData.ownerData && + tokenData.ownerData.nickName && + tokenData.ownerData.nickName.length > 20 + ? tokenData.ownerData.nickName.slice(0, 5) + + '...' + + tokenData.ownerData.nickName.slice(length - 4) + : tokenData.ownerData && tokenData.ownerData.nickName) || + (tokenData?.ownerAddress && + tokenData?.ownerAddress.slice(0, 4) + + '...' + + tokenData?.ownerAddress.slice(length - 4))}
    )} @@ -381,7 +364,9 @@ const SerialNumberBuySell: React.FC = ({ if (currentUserAddress && !correctBlockchain(blockchain)) { return ( web3Switch(blockchain)} + handleClick={() => { + web3Switch(blockchain); + }} isColorPurple={true} title={`Switch network`} /> @@ -389,11 +374,14 @@ const SerialNumberBuySell: React.FC = ({ } // Blockchain is correct and offer exists - if (tokenData && !Object.values(tokenData)[0]?.isMinted && offerData) { - const rawPrice = BigNumber.from(offerData?.price ? offerData?.price : 0); - const price = numberTooBigThreshold.gte(rawPrice) - ? '0.000+' - : formatEther(rawPrice); + if ( + selectedToken && + !currentCollection?.[selectedToken]?.isMinted && + offerData + ) { + const rawPrice = BigInt(offerData?.price ? offerData?.price : 0); + const price = + numberTooBigThreshold >= rawPrice ? '0.000+' : formatEther(rawPrice); const priceForUSD = formatEther(rawPrice); @@ -416,22 +404,23 @@ const SerialNumberBuySell: React.FC = ({ blockchain && getBlockchainData(blockchain)?.symbol }`} /> - {coingeckoRates && ( + {exchangeRates && (
    $ {( - Number(priceForUSD) * Number(coingeckoRates[blockchain]) + Number(priceForUSD) * Number(exchangeRates[blockchain]) ).toFixed(2)}
    )} ); // Token is minted - } else if (tokenData && Object.values(tokenData)[0]?.isMinted) { + } else if (selectedToken && currentCollection?.[selectedToken]?.isMinted) { if (resaleData) { - const price = numberTooBigThreshold.gte(resaleData.price) - ? '0.000+' - : formatEther(resaleData.price); + const price = + numberTooBigThreshold >= resaleData.price + ? '0.000+' + : formatEther(resaleData.price); const priceForUSD = formatEther(resaleData.price); return ( @@ -443,55 +432,61 @@ const SerialNumberBuySell: React.FC = ({ title={`Buy ${price} ${getBlockchainData(blockchain)?.symbol}`} /> Resale offer - {coingeckoRates && ( + {exchangeRates && (
    $ {( - Number(priceForUSD) * Number(coingeckoRates[blockchain]) + Number(priceForUSD) * Number(exchangeRates[blockchain]) ).toFixed(2)}
    )} ); } + + if (!selectedToken) { + return; + } // Current user is owner of the token if ( - Object.values(tokenData)[0].ownerAddress === + currentCollection[selectedToken].ownerAddress === currentUserAddress?.toLowerCase() ) { return ( ); // User is not owner and resale data exists } else { + const tokenData = currentCollection[selectedToken]; return (
    Owned by{' '}
    - {Object.values(tokenData)[0] && ( - + {tokenData && ( +
    - {(accountData && - accountData.nickName && - accountData.nickName.length > 20 - ? accountData.nickName.slice(0, 5) + + {(tokenData.ownerData && + tokenData.ownerData.nickName && + tokenData.ownerData.nickName.length > 20 + ? tokenData.ownerData.nickName.slice(0, 5) + '....' + - accountData.nickName.slice(length - 4) - : accountData && accountData.nickName) || - (Object.values(tokenData)[0]?.ownerAddress && - Object.values(tokenData)[0]?.ownerAddress.slice(0, 4) + + tokenData.ownerData.nickName.slice(length - 4) + : tokenData.ownerData && tokenData.ownerData.nickName) || + (tokenData.ownerAddress && + tokenData.ownerAddress.slice(0, 4) + '....' + - Object.values(tokenData)[0]?.ownerAddress.slice( - length - 4 - ))} + tokenData.ownerAddress.slice(length - 4))}
    )} @@ -500,24 +495,28 @@ const SerialNumberBuySell: React.FC = ({ ); } } - // eslint-disable-next-line react-hooks/exhaustive-deps }, [ blockchain, + currentUserAddress, correctBlockchain, - selectedToken, - tokenData, + currentCollection, offerData, + selectedToken, web3Switch, numberTooBigThreshold, contractData, buyContract, - currentUserAddress, + getBlockchainData, + exchangeRates, resaleData, resalePurchase, - accountData, getResaleData ]); + if (!selectedToken) { + return ; + } + return (
    @@ -529,37 +528,31 @@ const SerialNumberBuySell: React.FC = ({ Serial number
    - {tokenData && Object.keys(tokenData)?.length ? ( + {currentCollection && Object.keys(currentCollection)?.length ? ( ) : ( <> )}
    - {tokenData && + {currentCollection && selectedToken && tokenDataForResale && - Object.values(tokenData)[0]?.isMinted && - currentUserAddress === Object.values(tokenData)[0].ownerAddress && ( + currentCollection[selectedToken]?.isMinted && + currentUserAddress === + currentCollection[selectedToken].ownerAddress && (
    ); diff --git a/rair-front/src/components/MockUpPage/NftList/NftData/TitleCollection/MintPopUpCollection/StyledMintPopUpCollection.ts b/rair-front/src/components/MockUpPage/NftList/NftData/TitleCollection/MintPopUpCollection/StyledMintPopUpCollection.ts index acd20d79a..493d33d30 100644 --- a/rair-front/src/components/MockUpPage/NftList/NftData/TitleCollection/MintPopUpCollection/StyledMintPopUpCollection.ts +++ b/rair-front/src/components/MockUpPage/NftList/NftData/TitleCollection/MintPopUpCollection/StyledMintPopUpCollection.ts @@ -1,10 +1,13 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; interface IMintPopUpCollectionContainer { primaryColor: string; } -export const MintPopUpCollectionContainer = styled.div` +export const MintPopUpCollectionContainer = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` border-radius: 12px; height: auto; border: 1px solid diff --git a/rair-front/src/components/MockUpPage/NftList/NftData/TitleCollection/SharePopUp/SharePopUp.tsx b/rair-front/src/components/MockUpPage/NftList/NftData/TitleCollection/SharePopUp/SharePopUp.tsx index a2beb0295..26154721c 100644 --- a/rair-front/src/components/MockUpPage/NftList/NftData/TitleCollection/SharePopUp/SharePopUp.tsx +++ b/rair-front/src/components/MockUpPage/NftList/NftData/TitleCollection/SharePopUp/SharePopUp.tsx @@ -1,5 +1,4 @@ import React, { useState } from 'react'; -import { useSelector } from 'react-redux'; import { FacebookShareButton, TwitterShareButton } from 'react-share'; import FacebookRoundedIcon from '@mui/icons-material/FacebookRounded'; import TwitterIcon from '@mui/icons-material/Twitter'; @@ -10,8 +9,7 @@ import ListItem from '@mui/material/ListItem'; import ListItemAvatar from '@mui/material/ListItemAvatar'; import ListItemText from '@mui/material/ListItemText'; -import { RootState } from '../../../../../../ducks'; -import { ColorStoreType } from '../../../../../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../../../../../hooks/useReduxHooks'; import { ISharePopUp } from '../../../../mockupPage.types'; import './SharePopUp.css'; @@ -26,10 +24,9 @@ const SharePopUp: React.FC = ({ const hotdropsVar = import.meta.env.VITE_TESTNET; - const { headerLogo, primaryColor, textColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { headerLogo, primaryColor, textColor } = useAppSelector( + (store) => store.colors + ); const handleClose = () => { onClose(selectedValue); diff --git a/rair-front/src/components/MockUpPage/NftList/NftData/TitleCollection/TitleCollection.tsx b/rair-front/src/components/MockUpPage/NftList/NftData/TitleCollection/TitleCollection.tsx index 7ab307a86..6da7a97b6 100644 --- a/rair-front/src/components/MockUpPage/NftList/NftData/TitleCollection/TitleCollection.tsx +++ b/rair-front/src/components/MockUpPage/NftList/NftData/TitleCollection/TitleCollection.tsx @@ -1,15 +1,13 @@ import React, { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import { NavLink } from 'react-router-dom'; import { useLocation, useParams } from 'react-router-dom'; import Popup from 'reactjs-popup'; -import { RootState } from '../../../../../ducks'; -import { ColorStoreType } from '../../../../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../../../../hooks/useReduxHooks'; +import useServerSettings from '../../../../../hooks/useServerSettings'; import useWindowDimensions from '../../../../../hooks/useWindowDimensions'; import { rFetch } from '../../../../../utils/rFetch'; import { ContractType } from '../../../../adminViews/adminView.types'; -import useServerSettings from '../../../../adminViews/useServerSettings'; import { TooltipBox } from '../../../../common/Tooltip/TooltipBox'; import defaultImage from '../../../../UserProfileSettings/images/defaultUserPictures.png'; import EtherScanCollectionLogo from '../../../assets/EtherScanCollectionLogo.svg?react'; @@ -30,16 +28,12 @@ const TitleCollection: React.FC = ({ title, userName, someUsersData, - selectedData, offerDataCol - // collectionAttributes, - // toggleMetadataFilter }) => { const { contract, tokenId, blockchain } = useParams(); - const { primaryColor, primaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { primaryColor, primaryButtonColor } = useAppSelector( + (store) => store.colors + ); const [mintPopUp, setMintPopUp] = useState(false); const [purchaseStatus, setPurchaseStatus] = useState(false); @@ -264,7 +258,7 @@ const TitleCollection: React.FC = ({ href={`${ blockchain && getBlockchainData(blockchain)?.blockExplorerGateway - }address/${contract}`} + }/address/${contract}`} target="_blank" rel="noreferrer">
    = ({ : '' }`}> - +
    + +
    @@ -283,15 +279,12 @@ const TitleCollection: React.FC = ({
    diff --git a/rair-front/src/components/MockUpPage/NftList/NftData/TitleSingleTokenView.tsx b/rair-front/src/components/MockUpPage/NftList/NftData/TitleSingleTokenView.tsx index a0b218e81..0d3e3be88 100644 --- a/rair-front/src/components/MockUpPage/NftList/NftData/TitleSingleTokenView.tsx +++ b/rair-front/src/components/MockUpPage/NftList/NftData/TitleSingleTokenView.tsx @@ -4,13 +4,13 @@ import { ITitleSingleTokenView } from '../../mockupPage.types'; export const TitleSingleTokenView: React.FC = ({ title, - primaryColor + isDarkMode }) => { return (
    {title}
    diff --git a/rair-front/src/components/MockUpPage/NftList/NftData/UnlockableVideosSingleTokenPage.tsx b/rair-front/src/components/MockUpPage/NftList/NftData/UnlockableVideosSingleTokenPage.tsx index 19ab93151..4c97edb96 100644 --- a/rair-front/src/components/MockUpPage/NftList/NftData/UnlockableVideosSingleTokenPage.tsx +++ b/rair-front/src/components/MockUpPage/NftList/NftData/UnlockableVideosSingleTokenPage.tsx @@ -1,11 +1,9 @@ import React, { memo, useCallback, useEffect, useRef, useState } from 'react'; -import { Provider, useSelector, useStore } from 'react-redux'; +import { Provider, useStore } from 'react-redux'; -import { TFileType } from '../../../../axios.responseTypes'; -import { RootState } from '../../../../ducks'; -import { ContractsInitialType } from '../../../../ducks/contracts/contracts.types'; -import { TUsersInitialState } from '../../../../ducks/users/users.types'; +import { useAppSelector } from '../../../../hooks/useReduxHooks'; import useSwal from '../../../../hooks/useSwal'; +import { MediaFile } from '../../../../types/databaseTypes'; import { playImagesColored } from '../../../SplashPage/images/greyMan/grayMan'; import YotiPage from '../../../YotiPage/YotiPage'; import { TUnlockableVideosSingleTokenPage } from '../../mockupPage.types'; @@ -20,24 +18,21 @@ const UnlockableVideosSingleTokenPage: React.FC< setSelectVideo, openVideoplayer, setOpenVideoPlayer, - handlePlayerClick, - primaryColor + handlePlayerClick }) => { const videosListBlock = useRef(null); const [selectedItem, setSelectedItem] = useState< - TFileType | null | undefined + MediaFile | null | undefined >(undefined); - const { currentUserAddress } = useSelector( - (store) => store.contractStore - ); + const { currentUserAddress } = useAppSelector((store) => store.web3); const store = useStore(); - const { userData } = useSelector( - (store) => store.userStore - ); + const { ageVerified } = useAppSelector((store) => store.user); const [formatedVideoObj, setFormatedVideoObj] = useState(undefined); + + const { isDarkMode, primaryColor } = useAppSelector((store) => store.colors); const reactSwal = useSwal(); function renameKeys(obj, newKeys) { @@ -49,15 +44,11 @@ const UnlockableVideosSingleTokenPage: React.FC< } const ageVerificationPopUp = useCallback(() => { - if ( - selectVideo && - selectVideo?.ageRestricted === true && - (userData?.ageVerified === false || !userData?.ageVerified) - ) { + if (selectVideo && selectVideo?.ageRestricted === true && !ageVerified) { reactSwal.fire({ html: ( - + ), showConfirmButton: false, @@ -79,7 +70,7 @@ const UnlockableVideosSingleTokenPage: React.FC< } }, [ selectVideo, - userData?.ageVerified, + ageVerified, reactSwal, store, setOpenVideoPlayer, @@ -110,14 +101,14 @@ const UnlockableVideosSingleTokenPage: React.FC< } }, [productsFromOffer, setSelectVideo]); - const handleSelectedItem = (itemSelected: TFileType) => { + const handleSelectedItem = (itemSelected: MediaFile) => { setSelectedItem(itemSelected); }; return (
    {productsFromOffer && productsFromOffer.length && openVideoplayer ? (
    - {selectVideo && formatedVideoObj && ( + {selectVideo && formatedVideoObj && selectVideo?._id && ( {productsFromOffer?.length && - productsFromOffer.map((data: TFileType, index) => { + productsFromOffer.map((data, index) => { return (
    {data.title}
    {data.duration}
    diff --git a/rair-front/src/components/MockUpPage/NftList/NftData/UnlockablesPage/VideoPlayerView.tsx b/rair-front/src/components/MockUpPage/NftList/NftData/UnlockablesPage/VideoPlayerView.tsx index a83596158..887a660bb 100644 --- a/rair-front/src/components/MockUpPage/NftList/NftData/UnlockablesPage/VideoPlayerView.tsx +++ b/rair-front/src/components/MockUpPage/NftList/NftData/UnlockablesPage/VideoPlayerView.tsx @@ -1,4 +1,6 @@ import React, { useState } from 'react'; +import { faKey } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { playImagesColored } from '../../../../SplashPage/images/greyMan/grayMan'; import { @@ -8,8 +10,6 @@ import { import NftVideoplayer from '../NftVideoplayer/NftVideoplayer'; import cl from './VideoPlayerView.module.css'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faKey } from '@fortawesome/free-solid-svg-icons'; const VideoPlayerView: React.FC = ({ productsFromOffer, @@ -23,8 +23,6 @@ const VideoPlayerView: React.FC = ({ const [openVideoplayer, setOpenVideoplayer] = useState(false); const [selectedBg, setSelectedBg] = useState(); - const colorRarity = ['#E4476D', 'gold', 'silver']; - return (
    = ({ className={cl.ListOfVideosOneVideo}>
    Preview - +
    - + @@ -389,14 +361,12 @@ const SearchPanel: React.FC = ({ tabIndex, setTabIndex }) => { })}
    diff --git a/rair-front/src/components/MockUpPage/SelectBox/ItemRankItems.tsx b/rair-front/src/components/MockUpPage/SelectBox/ItemRankItems.tsx index 95e71d290..7e23c5e53 100644 --- a/rair-front/src/components/MockUpPage/SelectBox/ItemRankItems.tsx +++ b/rair-front/src/components/MockUpPage/SelectBox/ItemRankItems.tsx @@ -1,5 +1,6 @@ //unused-component +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; interface IItemRankContainerStyled { @@ -7,12 +8,16 @@ interface IItemRankContainerStyled { showItems?: boolean; } -export const ItemRankContainer = styled.div` +export const ItemRankContainer = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` background-color: ${(props) => props.primaryColor === 'rhyno' ? 'var(--rhyno)' : '#383637'}; `; -export const SelectBoxItemRank = styled.div` +export const SelectBoxItemRank = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` display: ${(props) => (props.showItems ? 'block' : 'none')}; background-color: ${(props) => props.primaryColor === 'rhyno' ? 'var(--rhyno)' : '#383637'}; @@ -22,6 +27,8 @@ export const SelectBoxItemRank = styled.div` z-index: 10; `; -export const SelectBoxContainer = styled.div` +export const SelectBoxContainer = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` backgroundcolor: var(--${(props) => props.primaryColor}); `; diff --git a/rair-front/src/components/MockUpPage/SelectBox/SelectNumber/CurrentTokens/CurrentTokens.tsx b/rair-front/src/components/MockUpPage/SelectBox/SelectNumber/CurrentTokens/CurrentTokens.tsx deleted file mode 100644 index d641359e1..000000000 --- a/rair-front/src/components/MockUpPage/SelectBox/SelectNumber/CurrentTokens/CurrentTokens.tsx +++ /dev/null @@ -1,141 +0,0 @@ -import React, { memo, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; -import { useParams } from 'react-router'; - -import { RootState } from '../../../../../ducks'; -import { ColorStoreType } from '../../../../../ducks/colors/colorStore.types'; -import useServerSettings from '../../../../adminViews/useServerSettings'; -import { StyledShevronIcon } from '../../../FilteringBlock/FilteringBlockItems/FilteringBlockItems'; -import { ICurrentTokensComponent } from '../../selectBox.types'; - -const CurrentTokensComponent: React.FC = ({ - primaryColor, - items, - isBack, - isOpen, - setIsOpen, - setIsOpens, - selectedToken, - handleIsOpen, - onClickItem, - numberRef, - totalCount -}) => { - const { primaryButtonColor, textColor, iconColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); - - const { customSecondaryColor } = useServerSettings(); - - const {tokenId} = useParams(); - - return ( - <> -
    -
    -
    {selectedToken}
    - {isOpen ? ( - - ) : ( - - )} -
    -
    -
    -
    { - setIsOpens?.(false); - setIsOpen(false); - }}> - ↩ -
    -
    Serial number
    -
    setIsOpen(false)}> - ✗ -
    -
    - {totalCount && totalCount.length > 0 && - totalCount.map((el,index) => { - return ( -
    onClickItem(el.token)}> - {el.sold ? 'Sold' : el.token} -
    - ); - })} -
    -
    - - ); -}; - -export const CurrentTokens = memo(CurrentTokensComponent); diff --git a/rair-front/src/components/MockUpPage/SelectBox/SelectNumber/ListOfTokens/ListOfTokens.tsx b/rair-front/src/components/MockUpPage/SelectBox/SelectNumber/ListOfTokens/ListOfTokens.tsx deleted file mode 100644 index 2b6acdb16..000000000 --- a/rair-front/src/components/MockUpPage/SelectBox/SelectNumber/ListOfTokens/ListOfTokens.tsx +++ /dev/null @@ -1,237 +0,0 @@ -import React, { memo, useCallback, useMemo, useRef, useState } from 'react'; -import { useEffect } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import axios from 'axios'; - -import { - TNftItemResponse, - TTokenData -} from '../../../../../axios.responseTypes'; -import { RootState } from '../../../../../ducks'; -import { setTokenData } from '../../../../../ducks/nftData/action'; -import { currentTokenData } from '../../../NftList/utils/currentTokenData'; -import { IListOfTokensComponent } from '../../selectBox.types'; -import { CurrentTokens } from '../CurrentTokens/CurrentTokens'; - -import '../../styles.css'; -import { useParams } from 'react-router'; - -const ListOfTokensComponent: React.FC = ({ - blockchain, - contract, - isOpen, - handleIsOpen, - numberRef, - onClickItem, - product, - primaryColor, - setSelectedToken, - selectedToken, - setIsOpen, - totalCount -}) => { - const [productTokenNumbers, setProductTokenNumbers] = useState([]); - const rootRef = useRef(null); - const appRef = useRef(null); - const listOfTokensRef = useRef(null); - const limit = 100; - const [isOpens, setIsOpens] = useState(false); - const [isBack /*setIsBack*/] = useState(true); - const [open, setOpen] = useState(true); - - const {} = useParams(); - - const hotdropsVar = import.meta.env.VITE_TESTNET; - - const tokenData = useSelector< - RootState, - { [index: string]: TTokenData } | undefined - >((state) => state.nftDataStore.tokenData); - const dispatch = useDispatch(); - - const getNumberFromStr = (str: string) => { - const newStr = str.replace(' -', ''); - const first = newStr.slice(0, newStr.indexOf(' ')); - const second = newStr.slice(newStr.indexOf(' ') + 1); - return [first, second]; - }; - - const handleOpenListOfTokens = () => { - setOpen(false); - }; - - const getPaginationData = useCallback( - async (target: HTMLElement) => { - const indexes = getNumberFromStr(target?.innerText); - const responseAllProduct = await axios.get( - `/api/nft/network/${blockchain}/${contract}/${product}/numbers?fromToken=${indexes[0]}&toToken=${indexes[1]}` - ); - const tokenMapping = {}; - if (responseAllProduct.data.success) { - responseAllProduct.data.result.tokens.forEach((item) => { - tokenMapping[item.token] = item; - }); - dispatch(setTokenData(tokenMapping)); - } - setSelectedToken(selectedToken); - onClickItem(selectedToken); - handleIsOpen(); - }, - [ - blockchain, - contract, - handleIsOpen, - onClickItem, - product, - setSelectedToken, - selectedToken, - dispatch - ] - ); - - const handleClickOutSideListOfTokens = useCallback( - (e: MouseEvent) => { - if (isOpens) { - return; - } else { - if (!listOfTokensRef.current?.contains(e.target as Node)) { - setOpen(true); - } - } - }, - [listOfTokensRef, isOpens] - ); - - const fetchSerialData = useCallback(async(fromToken?: number, toToken?: number) => { - const {data} = await axios.get( - `/api/nft/network/${blockchain}/${contract}/${product}/numbers${fromToken && toToken ? `?fromToken=${fromToken}&toToken=${toToken}` : ''}` - ); - - if(data.success && data.tokens) { - setProductTokenNumbers(data.tokens); - } - }, [blockchain,contract,product]) - - useEffect(() => { - document.addEventListener('mousedown', handleClickOutSideListOfTokens); - return () => - document.removeEventListener('mousedown', handleClickOutSideListOfTokens); - }, [handleClickOutSideListOfTokens, isOpen]); - - useEffect(() => { - fetchSerialData(); - }, []); - -const availableRanges = useMemo( - () => - totalCount?.reduce((acc, item) => { - const tokenRange = Math.floor(+item.token / 100) * 100; - return { - ...acc, - [tokenRange]: true - }; - }, {}), - [totalCount] -); - - const getPaginationToken = useCallback( - (e: React.MouseEvent) => { - getPaginationData(e.target as HTMLButtonElement); - setIsOpens(true); - }, - [getPaginationData, setIsOpens] - ); - - const ranges = useMemo(() => { - if (totalCount) { - const number = 999; - const rangesCount = Math.floor(number / 100) + 1; - return Array(rangesCount) - .fill(0) - .map((_, idx) => idx * 100); - } - return []; - }, [totalCount]); - - return !open ? ( - !isOpens ? ( -
    -
    -
    - Choose Range -
    -
    -
    - {ranges.map((i) => { - return ( - - ); - })} - setOpen(true)}> - ✗ - -
    -
    -
    - ) : ( - <> - {productTokenNumbers !== undefined && ( - index <= 99)} - /> - )} - - ) - ) : ( -
    { - handleOpenListOfTokens(); - }}> - Selected now : {Number(selectedToken)} -
    - ); -}; - -export const ListOfTokens = memo(ListOfTokensComponent); diff --git a/rair-front/src/components/MockUpPage/SelectBox/SelectNumber/SelectNumber.tsx b/rair-front/src/components/MockUpPage/SelectBox/SelectNumber/SelectNumber.tsx index 860d2629b..4b9d03338 100644 --- a/rair-front/src/components/MockUpPage/SelectBox/SelectNumber/SelectNumber.tsx +++ b/rair-front/src/components/MockUpPage/SelectBox/SelectNumber/SelectNumber.tsx @@ -1,84 +1,296 @@ -import { useCallback, useEffect, useRef, useState } from 'react'; -import { useSelector } from 'react-redux'; +import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import { useParams } from 'react-router-dom'; +import { + faChevronDown, + faChevronUp, + faRotateLeft, + faTimes +} from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { RootState } from '../../../../ducks'; -import { ColorStoreType } from '../../../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../../../hooks/useReduxHooks'; +import LoadingComponent from '../../../common/LoadingComponent'; import { ISelectNumber } from '../selectBox.types'; -import { CurrentTokens } from './CurrentTokens/CurrentTokens'; -import { ListOfTokens } from './ListOfTokens/ListOfTokens'; - import './SelectNumber.css'; +import '../styles.css'; const SelectNumber: React.FC = ({ - blockchain, - items, handleClickToken, - selectedToken, setSelectedToken, - totalCount, - product, - contract + serialNumberData }) => { - const { primaryColor } = useSelector( - (store) => store.colorStore + const { currentCollection, currentCollectionMetadata } = useAppSelector( + (store) => store.tokens ); + const { + primaryColor, + textColor, + isDarkMode, + primaryButtonColor, + secondaryColor, + iconColor + } = useAppSelector((store) => store.colors); + + const [tokenRange, setTokenRange] = useState>([]); + + const [rangePickerOpen, setRangePickerOpen] = useState(false); + const [tokenPickerOpen, setTokenPickerOpen] = useState(false); + const [tokenPickerVisible, setIsTokenPickerVisible] = + useState(false); - const [isOpen, setIsOpen] = useState(false); const numberRef = useRef(null); const handleClickOutSideNumberItem = useCallback( (e: MouseEvent) => { if (!numberRef.current?.contains(e.target as Node)) { - setIsOpen(false); + setIsTokenPickerVisible(false); } }, - [numberRef, setIsOpen] + [numberRef, setIsTokenPickerVisible] + ); + + const handleClickOutSideListOfTokens = useCallback( + (e: MouseEvent) => { + if (tokenPickerOpen) { + return; + } else { + if (!listOfTokensRef.current?.contains(e.target as Node)) { + setRangePickerOpen(false); + } + } + }, + [tokenPickerOpen] ); useEffect(() => { document.addEventListener('mousedown', handleClickOutSideNumberItem); - return () => + document.addEventListener('mousedown', handleClickOutSideListOfTokens); + return () => { document.removeEventListener('mousedown', handleClickOutSideNumberItem); - }, [handleClickOutSideNumberItem]); - - const handleIsOpen = () => { - setIsOpen((prev) => !prev); - }; + document.removeEventListener('mousedown', handleClickOutSideListOfTokens); + }; + }, [handleClickOutSideNumberItem, handleClickOutSideListOfTokens]); const onClickItem = (el: string | undefined) => { setSelectedToken(el); handleClickToken(el); - handleIsOpen(); + setIsTokenPickerVisible(!tokenPickerVisible); }; - return totalCount && totalCount.length < 100 ? ( - - ) : ( - + const { tokenId } = useParams(); + + const rootRef = useRef(null); + const appRef = useRef(null); + const listOfTokensRef = useRef(null); + + const hotdropsVar = import.meta.env.VITE_TESTNET; + + const getPaginationData = useCallback( + async (range) => { + setTokenRange(range); + setTokenPickerOpen(true); + setRangePickerOpen(false); + setIsTokenPickerVisible(!tokenPickerVisible); + }, + [tokenPickerVisible] + ); + + const ranges = useMemo(() => { + if (serialNumberData) { + const pages = + Math.floor(serialNumberData.length / 100) + + Number(serialNumberData.length % 100 > 0); + const arr = Array(pages) + .fill(0) + .map((_, pageNumber) => { + const expectedTopOfPage = (pageNumber + 1) * 100 - 1; + return [ + serialNumberData[pageNumber * 100]?.token, + serialNumberData[ + expectedTopOfPage > serialNumberData.length + ? serialNumberData.length - 1 + : expectedTopOfPage + ]?.token + ]; + }); + return arr; + } + return []; + }, [serialNumberData]); + + if (rangePickerOpen) { + return ( +
    +
    +
    + Select a Range +
    +
    +
    + {ranges.map((range, index) => { + return ( + + ); + })} + setRangePickerOpen(false)} + className="backClose-list-tokens" + icon={faTimes} + /> +
    +
    +
    + ); + } + + if (tokenPickerOpen) { + return ( +
    +
    setIsTokenPickerVisible(!tokenPickerVisible)} + className="select-field" + style={{ + borderColor: `${ + !isDarkMode + ? import.meta.env.VITE_TESTNET === 'true' + ? 'var(--hot-drops)' + : '#E882D5' + : `color-mix(in srgb, ${secondaryColor}, #888888)` + }`, + + backgroundColor: `${ + !isDarkMode + ? 'var(--rhyno-40)' + : `color-mix(in srgb, ${primaryColor} 40%, #888888)` + }` + }}> +
    + {!!tokenId && currentCollection[tokenId]?.token} +
    + +
    +
    +
    +
    100 ? 'visible' : 'hidden' + }} + onClick={() => { + setRangePickerOpen(false); + setTokenPickerOpen(false); + }}> + +
    +
    Serial number
    +
    setIsTokenPickerVisible(false)}> + +
    +
    + {serialNumberData?.length && + serialNumberData + .filter((token) => { + return ( + BigInt(token.token) >= BigInt(tokenRange[0]) && + BigInt(token.token) <= BigInt(tokenRange[1]) + ); + }) + .map((el, index) => { + return ( +
    onClickItem(el.token)}> + {el.sold ? 'Sold' : el.token} +
    + ); + })} +
    +
    + ); + } + + if (!tokenId || !currentCollectionMetadata.product) { + return ; + } + + const realNumber = ( + BigInt(tokenId) + BigInt(currentCollectionMetadata.product?.firstTokenIndex) + ).toString(); + + return ( +
    { + if (serialNumberData.length <= 100) { + getPaginationData(ranges[0]); + } else { + setRangePickerOpen(!rangePickerOpen); + } + }}> + Selected now: {!!realNumber && currentCollection[realNumber]?.token} +
    ); }; diff --git a/rair-front/src/components/MockUpPage/SelectBox/selectBox.types.ts b/rair-front/src/components/MockUpPage/SelectBox/selectBox.types.ts index 7f26916ee..136862556 100644 --- a/rair-front/src/components/MockUpPage/SelectBox/selectBox.types.ts +++ b/rair-front/src/components/MockUpPage/SelectBox/selectBox.types.ts @@ -1,20 +1,15 @@ +import { tokenNumberData } from '../../../types/commonTypes'; + export interface IListOfTokensComponent { - blockchain: BlockchainType | undefined; - contract: string | undefined; isOpen: boolean; handleIsOpen: () => void; numberRef: React.LegacyRef | undefined; onClickItem: (element: string | undefined) => void; - product: string | undefined; - primaryColor: string; - setSelectedToken: (tokenId: string | undefined) => void; - selectedToken: string | undefined; setIsOpen: (isOpen: boolean) => void; - totalCount: any; + serialNumberData: any; } export interface ICurrentTokensComponent { - primaryColor: string; items: SelectNumberItem[]; isBack?: boolean; isOpen: boolean; @@ -33,16 +28,10 @@ export type SelectNumberItem = { token: string; value: string; }; - export interface ISelectNumber { - blockchain: BlockchainType | undefined; - items: SelectNumberItem[]; handleClickToken: (tokenId: string | undefined) => Promise; - selectedToken: string | undefined; - totalCount: any; - product: string | undefined; - contract: string | undefined; setSelectedToken: (tokenId: string | undefined) => void; + serialNumberData: Array; } export interface IMockUpPage { tabIndex: number; diff --git a/rair-front/src/components/MockUpPage/assets/ArrowDown.svg b/rair-front/src/components/MockUpPage/assets/ArrowDown.svg deleted file mode 100644 index 492781c29..000000000 --- a/rair-front/src/components/MockUpPage/assets/ArrowDown.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/rair-front/src/components/MockUpPage/assets/ArrowUp.svg b/rair-front/src/components/MockUpPage/assets/ArrowUp.svg deleted file mode 100644 index c256d3bc3..000000000 --- a/rair-front/src/components/MockUpPage/assets/ArrowUp.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/rair-front/src/components/MockUpPage/mockUpPage.styles/NftDataPageMain.styledComponents.tsx b/rair-front/src/components/MockUpPage/mockUpPage.styles/NftDataPageMain.styledComponents.tsx index 2e2d6932b..95f7f2d60 100644 --- a/rair-front/src/components/MockUpPage/mockUpPage.styles/NftDataPageMain.styledComponents.tsx +++ b/rair-front/src/components/MockUpPage/mockUpPage.styles/NftDataPageMain.styledComponents.tsx @@ -1,10 +1,13 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; interface INftCollectionProps { primaryColor: string; } -export const NftCollection = styled.div` +export const NftCollection = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` position: relative; border-radius: 16px; height: '475px'; diff --git a/rair-front/src/components/MockUpPage/mockupPage.types.ts b/rair-front/src/components/MockUpPage/mockupPage.types.ts index 70980433f..02483c08a 100644 --- a/rair-front/src/components/MockUpPage/mockupPage.types.ts +++ b/rair-front/src/components/MockUpPage/mockupPage.types.ts @@ -1,27 +1,30 @@ +import { Hex } from 'viem'; + +import { TMetadataType, TProducts } from '../../axios.responseTypes'; +import { CollectionTokens } from '../../redux/tokenSlice'; import { - TFileType, - TMetadataType, - TProducts, - TTokenData -} from '../../axios.responseTypes'; -import { UserType } from '../../ducks/users/users.types'; + CatalogVideoItem, + NftItemToken, + tokenNumberData +} from '../../types/commonTypes'; +import { TokenMetadata, User } from '../../types/databaseTypes'; import { TOfferType } from '../marketplace/marketplace.types'; export interface ITitleSingleTokenView { title: string; - primaryColor: string; + isDarkMode: boolean; } export interface INftItemForCollectionView { embeddedParams?: TEmbeddedParams; - blockchain: BlockchainType | undefined; + blockchain: Hex | undefined; pict: string | undefined; offerPrice?: string[] | undefined; index: string; - metadata: TMetadataType; + metadata: TokenMetadata; offer: string | undefined; - selectedData?: TMetadataType | undefined; - someUsersData?: UserType | null | undefined; + selectedData?: TokenMetadata | undefined; + someUsersData?: User | null | undefined; userName: string | undefined; tokenDataLength?: number; playing: string | null; @@ -41,7 +44,7 @@ export interface INftItemForCollectionView { } export type TParamsNftItemForCollectionView = { - blockchain: BlockchainType; + blockchain: Hex; contract: string; product: string; tokenId: string; @@ -80,12 +83,12 @@ export interface IEtherscanIconComponent { classTitle: string; contract: string | undefined; selectedToken: string | undefined; - blockchain: BlockchainType | undefined; + blockchain: Hex | undefined; currentTokenId: string | undefined; } export type TParamsBreadcrumbsComponent = { - blockchain: BlockchainType; + blockchain: Hex; contract: string; product: string; tokenId: string; @@ -95,33 +98,25 @@ export interface ISharePopUp { onClose: (value: number) => void; selectedValue: number; open: boolean; - primaryColor: string; - selectedData?: TMetadataType | undefined; } export interface INftVideoplayer { - selectVideo: TFileType | undefined; + selectVideo: CatalogVideoItem | undefined; main?: boolean; - setSelectVideo?: (selectVideo: TFileType | undefined) => void; + setSelectVideo?: (selectVideo: CatalogVideoItem | undefined) => void; } export interface ISerialNumberBuySell { - tokenData: { [index: string]: TTokenData } | null; handleClickToken: (tokenId: string | undefined) => Promise; - blockchain: BlockchainType | undefined; - product: string | undefined; - contract: string | undefined; - totalCount: number | undefined; + blockchain: Hex | undefined; selectedToken: string | undefined; setSelectedToken: (tokenId: string | undefined) => void; - textColor: string | undefined; offerData: TOfferType | undefined; - handleTokenBoughtButton: () => void; - tokenDataForResale?: any; + tokenDataForResale?: NftItemToken | CollectionTokens; + serialNumberData: Array; } export interface ISellButton { currentUser?: string | undefined; - tokenData?: { [index: string]: TTokenData } | null; selectedToken?: string | undefined; sellingPrice?: string; isInputPriceExist: boolean; @@ -133,8 +128,7 @@ export interface ISellButton { } export interface ISingleTokenViewProperties { - selectedData: TMetadataType; - textColor: string | undefined; + selectedData: TokenMetadata; } export interface IBuySellButton { @@ -145,21 +139,19 @@ export interface IBuySellButton { } export type TUnlockableVideosSingleTokenPage = { - productsFromOffer: TFileType[] | undefined; - selectVideo: TFileType | undefined; - setSelectVideo: (videoFile: TFileType | undefined) => void; + productsFromOffer: CatalogVideoItem[] | undefined; + selectVideo: CatalogVideoItem | undefined; + setSelectVideo: (videoFile: CatalogVideoItem | undefined) => void; openVideoplayer: boolean; - setOpenVideoPlayer: (value: boolean) => void; + setOpenVideoPlayer: React.Dispatch>; handlePlayerClick: () => void; - primaryColor: string; }; export interface ITitleCollection { title: string | undefined; userName: string | undefined; - someUsersData: UserType | undefined | null; - selectedData: TMetadataType | undefined; - currentUser?: UserType; + someUsersData: User | undefined | null; + currentUser?: User; offerDataCol?: TOfferType[] | undefined; connectUserData?: any; collectionAttributes?: any; @@ -168,7 +160,6 @@ export interface ITitleCollection { export interface ICusmonShareButton { title: string; handleClick: () => void; - primaryColor: string; isCollectionPathExist?: boolean; moreUnlockablesClassName?: string; } @@ -176,36 +167,32 @@ export interface ICusmonShareButton { export type TParamsTitleCollection = { tokenId: string; contract: string; - blockchain: BlockchainType; + blockchain: Hex; tokens: 'tokens' | 'collection'; }; export interface ISellInputButton { - tokenData: { [index: string]: TTokenData } | null; selectedToken: string | undefined; refreshResaleData: () => void; } export interface INftDataPageMain { - blockchain: BlockchainType | undefined; - contract: string | undefined; + blockchain: Hex | undefined; + contract: Hex | undefined; handleClickToken: (tokenId: string | undefined) => Promise; product: string | undefined; - productsFromOffer: TFileType[] | undefined; - selectedData: TMetadataType | undefined; + productsFromOffer: CatalogVideoItem[] | undefined; + selectedData?: TokenMetadata; selectedToken: string | undefined; setSelectedToken: (tokenId: string | undefined) => void; - totalCount: number | undefined; - textColor: string | undefined; offerData?: TOfferType | undefined; offerDataInfo: TOfferType[] | undefined; offerPrice?: string[]; - someUsersData: UserType | null | undefined; + someUsersData: User | null | undefined; ownerInfo?: TProducts | undefined; embeddedParams?: TEmbeddedParams | undefined; - handleTokenBoughtButton: () => void; - setTokenNumber: (arg: undefined | number) => void; - getProductsFromOffer: () => void; + setTokenNumber?: (arg: undefined | number) => void; + getProductsFromOffer?: () => void; } export type TOffersIndexesData = { @@ -218,13 +205,11 @@ export type TOffersIndexesData = { }; export type TSwitchEthereumChainArgs = { - chainId: BlockchainType; + chainId: Hex; chainName: string; }; export interface ISearchPanel { - primaryColor: string; - textColor: string | undefined; tabIndex: number; setTabIndex: (index: number) => void; } @@ -232,9 +217,9 @@ export interface ISearchPanel { export type TModeType = 'collection' | 'tokens' | 'unlockables'; export type TEmbeddedParams = { - contract: string; + contract: Hex; product: string; - blockchain: BlockchainType | undefined; + blockchain: Hex | undefined; mode: TModeType; setMode: (mode: TModeType) => void; tokenId: string; diff --git a/rair-front/src/components/MockUpPage/utils/button/CustomButton.module.css b/rair-front/src/components/MockUpPage/utils/button/CustomButton.module.css index d262a636f..ea435189e 100644 --- a/rair-front/src/components/MockUpPage/utils/button/CustomButton.module.css +++ b/rair-front/src/components/MockUpPage/utils/button/CustomButton.module.css @@ -4,21 +4,6 @@ /* padding: 1px; */ border-radius: 6px; cursor: pointer; - background-image: linear-gradient( - 96.34deg, - #725bdb 0%, - #805fda 10.31%, - #8c63da 20.63%, - #9867d9 30.94%, - #a46bd9 41.25%, - #af6fd8 51.56%, - #af6fd8 51.56%, - #bb73d7 61.25%, - #c776d7 70.94%, - #d27ad6 80.62%, - #dd7ed6 90.31%, - #e882d5 100% - ); } .nftDataPageShowMore { /* background: #434343; */ @@ -27,23 +12,6 @@ justify-content: center; } .nftDataPageShowMore:hover { - /* background: #8d18916e; */ - background: linear-gradient( - 186.34deg, - #725bdb 0%, - #805fda 10.31%, - #8c63da 20.63%, - #9867d9 30.94%, - #a46bd9 41.25%, - #af6fd8 51.56%, - #af6fd8 51.56%, - #bb73d7 61.25%, - #c776d7 70.94%, - #d27ad6 80.62%, - #dd7ed6 90.31%, - #e882d5 100% - ), - linear-gradient(0deg, #ffffff, #ffffff); transition: all 2.2s ease; } .nftDataPageShowMoreText { diff --git a/rair-front/src/components/MockUpPage/utils/button/CustomButton.tsx b/rair-front/src/components/MockUpPage/utils/button/CustomButton.tsx index 3014887ce..556e19e5b 100644 --- a/rair-front/src/components/MockUpPage/utils/button/CustomButton.tsx +++ b/rair-front/src/components/MockUpPage/utils/button/CustomButton.tsx @@ -1,14 +1,13 @@ -import React from 'react'; -import { useSelector } from 'react-redux'; +import { FC } from 'react'; import { ShowMoreContainer, ShowMoreItem, ShowMoreText } from './ShowMoreItems'; -import { RootState } from '../../../../ducks'; +import { useAppSelector } from '../../../../hooks/useReduxHooks'; import { ICustomButton } from '../../NftList/nftList.types'; import cl from './CustomButton.module.css'; -const CustomButton: React.FC = ({ +const CustomButton: FC = ({ text, width, height, @@ -21,9 +20,7 @@ const CustomButton: React.FC = ({ padding, loading = false }) => { - const primaryColor = useSelector( - (store) => store.colorStore.primaryColor - ); + const { primaryColor } = useAppSelector((store) => store.colors); return ( ` +export const ShowMoreContainer = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` width: ${(props) => props.width}; height: ${(props) => props.height}; color: ${(props) => props.textColor}; @@ -22,7 +25,9 @@ export const ShowMoreContainer = styled.div` // } `; -export const ShowMoreItem = styled.div` +export const ShowMoreItem = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` width: ${(props) => props.width}; min-height: ${(props) => props.height}; color: ${(props) => props.textColor}; @@ -56,7 +61,9 @@ export const ShowMoreItem = styled.div` } `; -export const ModalContentCloseBtn = styled.div` +export const ModalContentCloseBtn = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` width: 32px; height: 32px; border-radius: 11.5px; @@ -65,11 +72,9 @@ export const ModalContentCloseBtn = styled.div` justify-content: center; transition: all 0.2s ease; cursor: pointer; - background: ${(props) => - props.primaryColor === 'rhyno' ? '#FFFFFF' : '#4E4D4D'}; + background: ${({ isDarkMode }) => (isDarkMode ? '#FFFFFF' : '#4E4D4D')}; &:hover { - background: ${(props) => - props.primaryColor === 'rhyno' ? '#4E4D4D' : '#FFFFFF'}; + background: ${({ isDarkMode }) => (isDarkMode ? '#4E4D4D' : '#FFFFFF')}; } i { color: #e882d5; @@ -79,7 +84,9 @@ export const ModalContentCloseBtn = styled.div` } `; -export const ShowMoreText = styled.span` +export const ShowMoreText = styled.span.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` font-family: ${(props) => props.font}; color: ${(props) => props.fontColor}; font-size: ${(props) => props.fontSize}; diff --git a/rair-front/src/components/Navigation/Menu.tsx b/rair-front/src/components/Navigation/Menu.tsx index 328f73821..d3dee6cb4 100644 --- a/rair-front/src/components/Navigation/Menu.tsx +++ b/rair-front/src/components/Navigation/Menu.tsx @@ -1,17 +1,15 @@ import React, { Suspense, useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import { NavLink } from 'react-router-dom'; import { faSearch } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import axios from 'axios'; -import { constants, ethers, utils } from 'ethers'; +import { formatEther, isAddress, ZeroAddress } from 'ethers'; import { TUserResponse } from '../../axios.responseTypes'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; -import { TUsersInitialState, UserType } from '../../ducks/users/users.types'; import useConnectUser from '../../hooks/useConnectUser'; +import useContracts from '../../hooks/useContracts'; +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; import { BellIcon, CloseIconMobile, @@ -20,14 +18,15 @@ import { RairTokenLogo, VerifiedIcon } from '../../images'; +import { dataStatuses } from '../../redux/commonTypes'; import { SocialBox, SocialBoxSearch, SocialMenuMobile, UserIconMobile } from '../../styled-components/SocialLinkIcons/SocialLinkIcons'; +import { User } from '../../types/databaseTypes'; import { rFetch } from '../../utils/rFetch'; -import useServerSettings from '../adminViews/useServerSettings'; import { SvgUserIcon } from '../UserProfileSettings/SettingsIcons/SettingsIcons'; import MobileChoiseNav from './MenuComponents/MobileChoiseNav'; @@ -42,15 +41,9 @@ import { import './Menu.css'; interface IMenuNavigation { - connectUserData: () => void; renderBtnConnect: boolean; currentUserAddress: string | undefined; - programmaticProvider: - | ethers.Wallet - | ethers.providers.JsonRpcSigner - | undefined; showAlert: boolean | null | undefined; - selectedChain: any | undefined; setTabIndexItems: (arg: number) => void; isSplashPage: boolean; isAboutPage: boolean; @@ -61,7 +54,6 @@ interface IMenuNavigation { const MenuNavigation: React.FC = ({ showAlert, - selectedChain, setTabIndexItems, isSplashPage, isAboutPage, @@ -70,11 +62,8 @@ const MenuNavigation: React.FC = ({ getNotificationsCount }) => { const [click, setClick] = useState(false); - const [userData, setUserData] = useState(null); + const [userData, setUserData] = useState(null); const [openProfile, setOpenProfile] = useState(false); - const { userData: userDataInfo } = useSelector( - (state) => state.userStore - ); const { getBlockchainData } = useServerSettings(); const { connectUserData } = useConnectUser(); // const [loading, setLoading] = useState(false); @@ -82,14 +71,14 @@ const MenuNavigation: React.FC = ({ const [activeSearch, setActiveSearch] = useState(false); const [isLoadingBalance, setIsLoadingBalance] = useState(false); const [messageAlert, setMessageAlert] = useState(null); - const { loggedIn, loginProcess } = useSelector( - (store) => store.userStore + const { isLoggedIn, loginStatus, ageVerified } = useAppSelector( + (store) => store.user ); const [realDataNotification, setRealDataNotification] = useState([]); - const { mainTokenInstance, currentUserAddress, currentChain } = useSelector< - RootState, - ContractsInitialType - >((state) => state.contractStore); + const { mainTokenInstance } = useContracts(); + const { currentUserAddress, connectedChain } = useAppSelector( + (state) => state.web3 + ); const { primaryButtonColor, @@ -97,7 +86,7 @@ const MenuNavigation: React.FC = ({ iconColor, secondaryColor, primaryColor - } = useSelector((store) => store.colorStore); + } = useAppSelector((store) => store.colors); const hotdropsVar = import.meta.env.VITE_TESTNET; @@ -110,13 +99,15 @@ const MenuNavigation: React.FC = ({ }; const getNotifications = useCallback(async () => { - if (currentUserAddress) { + if (currentUserAddress && isLoggedIn) { const result = await rFetch(`/api/notifications`); if (result.success) { setRealDataNotification(result.notifications); } + } else { + setRealDataNotification([]); } - }, [currentUserAddress]); + }, [currentUserAddress, isLoggedIn]); useEffect(() => { getNotificationsCount(); @@ -156,8 +147,8 @@ const MenuNavigation: React.FC = ({ // find user if ( currentUserAddress && - utils.isAddress(currentUserAddress) && - currentUserAddress !== constants.AddressZero + isAddress(currentUserAddress) && + currentUserAddress !== ZeroAddress ) { const result = await axios .get(`/api/users/${currentUserAddress}`) @@ -174,13 +165,15 @@ const MenuNavigation: React.FC = ({ }, [currentUserAddress, setUserData]); const getBalance = useCallback(async () => { - if (currentUserAddress && mainTokenInstance?.provider) { + if (currentUserAddress && mainTokenInstance?.runner?.provider) { setIsLoadingBalance(true); const balance = - await mainTokenInstance.provider.getBalance(currentUserAddress); + await mainTokenInstance.runner?.provider?.getBalance( + currentUserAddress + ); - if (balance) { - const result = utils.formatEther(balance); + if (balance !== undefined) { + const result = formatEther(balance.toString()); const final = Number(result.toString())?.toFixed(2)?.toString(); setUserBalance(final); @@ -213,7 +206,6 @@ const MenuNavigation: React.FC = ({ className="col-1 rounded burder-menu" showAlert={showAlert} secondaryColor={secondaryColor} - selectedChain={selectedChain} isSplashPage={isSplashPage} realChainId={realChainId}>
    - {!loggedIn && ( + {!isLoggedIn && ( = ({ click, messageAlert, - currentUserAddress, handleMessageAlert }) => { - const { primaryColor, headerLogoMobile } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); - const dispatch = useDispatch(); - const { userRd } = useSelector( - (state) => state.userStore + const { primaryColor, headerLogoMobile, isDarkMode } = useAppSelector( + (store) => store.colors + ); + const { currentUserAddress } = useAppSelector((store) => store.web3); + const dispatch = useAppDispatch(); + const { nickName, isLoggedIn, avatar } = useAppSelector( + (state) => state.user ); const [notificationCount, setNotificationCount] = useState(0); - const getNotificationsCount = useCallback( async () => { - if (currentUserAddress) { + 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, messageAlert]) + }, [currentUserAddress, isLoggedIn]); useEffect(() => { getNotificationsCount(); - }, [getNotificationsCount]) + }, [getNotificationsCount]); return (
    @@ -61,22 +59,22 @@ const MobileChoiseNav: React.FC = ({
    handleMessageAlert('profile')} - avatar={userRd && userRd.avatar} + avatar={avatar} marginRight={'16px'} messageAlert={messageAlert} primaryColor={primaryColor}> - {userRd && !userRd.avatar && ( + {isLoggedIn && !avatar && ( )}
    - {userRd && ( + {isLoggedIn && ( <> - {userRd.nickName && userRd.nickName.length > 13 - ? userRd.nickName.slice(0, 5) + + {nickName && nickName.length > 13 + ? nickName.slice(0, 5) + '...' + - userRd.nickName.slice(userRd.nickName.length - 4) - : userRd.nickName} + nickName.slice(nickName.length - 4) + : nickName} )}
    @@ -91,15 +89,19 @@ const MobileChoiseNav: React.FC = ({ marginLeft={'17px'}> {notificationCount > 0 && ( -
    {notificationCount > 9 ? "9+" : notificationCount}
    - )} +
    + {notificationCount > 9 ? '9+' : notificationCount} +
    + )} )}
    Notifications
    @@ -113,13 +115,9 @@ const MobileChoiseNav: React.FC = ({ width={'40px'} height={'40px'} onClick={() => { - dispatch( - setColorScheme( - primaryColor === '#dedede' ? 'charcoal' : 'rhyno' - ) - ); + dispatch(setColorScheme(isDarkMode ? 'light' : 'dark')); }}> - + )} diff --git a/rair-front/src/components/Navigation/MenuComponents/MobileEditProfile.tsx b/rair-front/src/components/Navigation/MenuComponents/MobileEditProfile.tsx index b03a908fc..24678322f 100644 --- a/rair-front/src/components/Navigation/MenuComponents/MobileEditProfile.tsx +++ b/rair-front/src/components/Navigation/MenuComponents/MobileEditProfile.tsx @@ -1,15 +1,10 @@ -//@ts-nocheck import React, { useCallback, useState } from 'react'; import { useForm } from 'react-hook-form'; -import { useDispatch, useSelector } from 'react-redux'; -import axios, { AxiosError } from 'axios'; -import Swal from 'sweetalert2'; +import axios from 'axios'; import { TUserResponse } from '../../../axios.responseTypes'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../../ducks/contracts/contracts.types'; -import { TUsersInitialState } from '../../../ducks/users/users.types'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; +import useSwal from '../../../hooks/useSwal'; import { MobileEditFields, MobileProfileBtnWrapper, @@ -24,18 +19,12 @@ const MobileEditProfile: React.FC = () => { formState: { errors }, getValues } = useForm(); - const { userRd } = useSelector( - (state) => state.userStore - ); - const { currentUserAddress } = useSelector( - (store) => store.contractStore - ); + const { isLoggedIn, nickName, email } = useAppSelector((state) => state.user); + const { currentUserAddress } = useAppSelector((store) => store.web3); - const { primaryColor } = useSelector( - (store) => store.colorStore - ); + const { primaryColor } = useAppSelector((store) => store.colors); - const dispatch = useDispatch(); + const dispatch = useAppDispatch(); const [editMode, setEditMode] = useState(false); @@ -43,6 +32,8 @@ const MobileEditProfile: React.FC = () => { setEditMode((prev) => !prev); }; + const rSwal = useSwal(); + // const { // register, // handleSubmit, @@ -75,15 +66,15 @@ const MobileEditProfile: React.FC = () => { const updateProfile = useCallback( async (data) => { if ( - userRd?.nickName.replace(/@/g, '') !== getValues('username') || - userRd?.email !== getValues('useremail') + nickName?.replace(/@/g, '') !== getValues('username') || + email !== getValues('useremail') ) { const formData = new FormData(); formData.append('nickName', data.username); formData.append('email', data.useremail); - // if (file) { - // formData.append('file', file); - // } + if (!currentUserAddress) { + return; + } try { const profileEditResponse = await axios.patch( `/api/users/${currentUserAddress.toLowerCase()}`, @@ -107,7 +98,7 @@ const MobileEditProfile: React.FC = () => { }); } } catch (err) { - const error = err as AxiosError; + const error = err as any; if ( error.response?.data.message === @@ -115,7 +106,7 @@ const MobileEditProfile: React.FC = () => { 'username' )}" }` ) { - Swal.fire( + rSwal.fire( 'Info', `The name ${getValues('username')} already exists`, 'question' @@ -125,9 +116,9 @@ const MobileEditProfile: React.FC = () => { // eslint-disable-next-line no-useless-escape, prettier/prettier '"email" must be a valid email' ) { - Swal.fire('Info', `Wrong email format`, 'question'); + rSwal.fire('Info', `Wrong email format`, 'question'); } else { - Swal.fire( + rSwal.fire( 'Info', `The ${error.response?.data.message} `, 'question' @@ -135,10 +126,10 @@ const MobileEditProfile: React.FC = () => { } } } else { - Swal.fire('Info', `You need to change something`, 'question'); + rSwal.fire('Info', `You need to change something`, 'question'); } }, - [currentUserAddress, getValues, dispatch, userRd] + [nickName, getValues, email, currentUserAddress, dispatch, rSwal] ); const onSubmit = (data) => { @@ -149,7 +140,7 @@ const MobileEditProfile: React.FC = () => { return ( - {userRd && ( + {isLoggedIn && ( <> {editMode ? (
    @@ -158,7 +149,7 @@ const MobileEditProfile: React.FC = () => { errors={errors.username}> { errors={errors.useremail}> {

    Name

    -
    - {userRd.nickName.length > 13 - ? userRd.nickName.slice(0, 5) + - '....' + - userRd.nickName.slice(userRd.nickName.length - 4) - : userRd.nickName} -
    + {nickName && ( +
    + {nickName.length > 13 + ? nickName.slice(0, 5) + + '....' + + nickName.slice(nickName.length - 4) + : nickName} +
    + )}

    E-mail

    - {userRd.email ? userRd.email : 'email@example.com'} + {email ? email : 'email@example.com'}
    diff --git a/rair-front/src/components/Navigation/MenuComponents/MobileListMenu.tsx b/rair-front/src/components/Navigation/MenuComponents/MobileListMenu.tsx index d3b037e7d..2a9ccd8da 100644 --- a/rair-front/src/components/Navigation/MenuComponents/MobileListMenu.tsx +++ b/rair-front/src/components/Navigation/MenuComponents/MobileListMenu.tsx @@ -1,5 +1,4 @@ import React, { useCallback, useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; import { useNavigate } from 'react-router'; import { faSearch } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -7,19 +6,9 @@ import axios from 'axios'; import MobileNavigationList from './MobileNavigationList'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../../ducks/contracts/contracts.types'; -import { - getDataAllClear, - getDataAllStart -} from '../../../ducks/search/actions'; -import { - TSearchDataProduct, - TSearchDataTokens, - TSearchDataUser, - TSearchInitialState -} from '../../../ducks/search/search.types'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; +import { clearResults, startSearch } from '../../../redux/searchbarSlice'; +import { MintedToken, User } from '../../../types/databaseTypes'; import { TAxiosCollectionData } from '../../Header/header.types'; import ImageCustomForSearch from '../../MockUpPage/utils/image/ImageCustomForSearch'; @@ -29,44 +18,36 @@ interface IMobileListMenu { click: boolean; messageAlert: string | null; activeSearch: boolean; - primaryColor: string; setMessageAlert; toggleMenu: (otherPage?: string | undefined) => void; setTabIndexItems: (arg: number) => void; isSplashPage: boolean; - secondaryColor?: string; } const MobileListMenu: React.FC = ({ - primaryColor, click, activeSearch, toggleMenu, messageAlert, setMessageAlert, setTabIndexItems, - isSplashPage, - secondaryColor + isSplashPage }) => { - const dispatch = useDispatch(); + const dispatch = useAppDispatch(); const navigate = useNavigate(); - const { currentUserAddress } = useSelector( - (store) => store.contractStore - ); - const { dataAll, message } = useSelector( - (store) => store.allInformationFromSearch - ); + const { currentUserAddress } = useAppSelector((store) => store.web3); + const { searchResults } = useAppSelector((store) => store.searchbar); const hotdropsVar = import.meta.env.VITE_TESTNET; - const { iconColor } = useSelector( - (store) => store.colorStore + const { iconColor, primaryColor, secondaryColor } = useAppSelector( + (store) => store.colors ); const [textSearch, setTextSearch] = useState(''); const goToExactlyContract = useCallback( async (addressId: string, collectionIndexInContract: string) => { - if (dataAll) { + if (searchResults) { const response = await axios.get( `/api/contracts/${addressId}` ); @@ -79,15 +60,15 @@ const MobileListMenu: React.FC = ({ `/collection/${exactlyContractData.blockchain}/${exactlyContractData.contractAddress}/${exactlyContractData.indexInContract}/0` ); setTextSearch(''); - dispatch(getDataAllClear()); + dispatch(clearResults()); } }, - [dataAll, dispatch, navigate] + [searchResults, dispatch, navigate] ); const goToExactlyToken = useCallback( async (addressId: string, token: string) => { - if (dataAll) { + if (searchResults) { const response = await axios.get( `/api/contracts/${addressId}` ); @@ -101,10 +82,10 @@ const MobileListMenu: React.FC = ({ `/tokens/${exactlyTokenData.blockchain}/${exactlyTokenData.contractAddress}/0/${token}` ); setTextSearch(''); - dispatch(getDataAllClear()); + dispatch(clearResults()); } }, - [dataAll, dispatch, navigate] + [searchResults, dispatch, navigate] ); const goToExactlyUser = (userAddress) => { @@ -146,7 +127,7 @@ const MobileListMenu: React.FC = ({ useEffect(() => { if (textSearch.length > 0) { - dispatch(getDataAllStart(textSearch)); + dispatch(startSearch({ searchTerm: textSearch })); } }, [dispatch, textSearch]); @@ -209,11 +190,12 @@ const MobileListMenu: React.FC = ({
    {textSearch && ( <> - {dataAll && dataAll?.products.length > 0 ? ( + {searchResults?.products?.length && + searchResults.products.length > 0 ? (
    Products
    - {dataAll?.products.map( - (item: TSearchDataProduct, index: number) => ( + {searchResults?.products.map( + (item, index: number) => (
    @@ -243,11 +225,12 @@ const MobileListMenu: React.FC = ({ ) : ( <> )} - {dataAll && dataAll?.tokens.length > 0 ? ( + {searchResults?.tokens?.length && + searchResults.tokens.length > 0 ? (
    Tokens
    - {dataAll?.tokens.map( - (item: TSearchDataTokens, index: number) => ( + {searchResults?.tokens.map( + (item: MintedToken, index: number) => (
    @@ -281,11 +264,12 @@ const MobileListMenu: React.FC = ({ ) : ( <> )} - {dataAll && dataAll?.users.length > 0 ? ( + {searchResults?.users?.length && + searchResults.users.length > 0 ? (
    Users
    - {dataAll?.users.map( - (item: TSearchDataUser, index: number) => ( + {searchResults?.users.map( + (item: User, index: number) => (
    = ({ )} )} - {textSearch !== '' && message === 'Nothing can found' ? ( + {textSearch !== '' ? ( No items found ) : ( <> @@ -335,9 +319,7 @@ const MobileListMenu: React.FC = ({ click={click} messageAlert={messageAlert} setMessageAlert={setMessageAlert} - primaryColor={primaryColor} toggleMenu={toggleMenu} - currentUserAddress={currentUserAddress} setTabIndexItems={setTabIndexItems} isSplashPage={isSplashPage} /> diff --git a/rair-front/src/components/Navigation/MenuComponents/MobileNavigationList.tsx b/rair-front/src/components/Navigation/MenuComponents/MobileNavigationList.tsx index 446c01e9d..8c7fd3977 100644 --- a/rair-front/src/components/Navigation/MenuComponents/MobileNavigationList.tsx +++ b/rair-front/src/components/Navigation/MenuComponents/MobileNavigationList.tsx @@ -1,21 +1,17 @@ import React, { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import { NavLink } from 'react-router-dom'; import { faChevronLeft, faSignOutAlt } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { BigNumber, utils } from 'ethers'; -import { formatEther } from 'ethers/lib/utils'; +import { formatEther } from 'ethers'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../../ducks/contracts/contracts.types'; -import { TUsersInitialState } from '../../../ducks/users/users.types'; import useConnectUser from '../../../hooks/useConnectUser'; +import useContracts from '../../../hooks/useContracts'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; +import useServerSettings from '../../../hooks/useServerSettings'; import useSwal from '../../../hooks/useSwal'; import useWeb3Tx from '../../../hooks/useWeb3Tx'; import { RairFavicon, RairTokenLogo } from '../../../images'; import { rFetch } from '../../../utils/rFetch'; -import useServerSettings from '../../adminViews/useServerSettings'; import LoadingComponent from '../../common/LoadingComponent'; import { TooltipBox } from '../../common/Tooltip/TooltipBox'; import { NavFooter, NavFooterBox } from '../../Footer/FooterItems/FooterItems'; @@ -26,8 +22,6 @@ import { BackBtnMobileNav } from '../NavigationItems/NavigationItems'; interface IMobileNavigationList { messageAlert: string | null; setMessageAlert: (arg: string | null) => void; - primaryColor?: string; - currentUserAddress: string | undefined; toggleMenu: (otherPage?: string) => void; setTabIndexItems: (arg: number) => void; isSplashPage: boolean; @@ -38,57 +32,59 @@ const MobileNavigationList: React.FC = ({ messageAlert, setMessageAlert, toggleMenu, - currentUserAddress, click }) => { const [userBalance, setUserBalance] = useState(''); - const [userRairBalance, setUserRairBalance] = useState( - BigNumber.from(0) - ); - const { userData } = useSelector( - (store) => store.userStore - ); - - const { primaryColor, primaryButtonColor, textColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const [userRairBalance, setUserRairBalance] = useState(BigInt(0)); + const { primaryColor, primaryButtonColor, textColor, isDarkMode } = + useAppSelector((store) => store.colors); const { web3TxHandler } = useWeb3Tx(); - const { mainTokenInstance, currentChain } = useSelector< - RootState, - ContractsInitialType - >((store) => store.contractStore); + const { currentUserAddress, connectedChain } = useAppSelector( + (store) => store.web3 + ); + const { isLoggedIn } = useAppSelector((store) => store.user); + const { mainTokenInstance } = useContracts(); const { getBlockchainData } = useServerSettings(); const getBalance = useCallback(async () => { - if (currentUserAddress && mainTokenInstance?.provider) { + if (currentUserAddress && mainTokenInstance?.runner?.provider) { const balance = - await mainTokenInstance.provider.getBalance(currentUserAddress); + await mainTokenInstance.runner.provider.getBalance(currentUserAddress); - if (balance) { - const result = utils.formatEther(balance); + if (balance !== undefined) { + const result = formatEther(balance.toString()); const final = Number(result.toString())?.toFixed(2)?.toString(); setUserBalance(final); } } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [currentUserAddress, mainTokenInstance, userData]); + }, [currentUserAddress, mainTokenInstance]); const getUserRairBalance = useCallback(async () => { - if (!mainTokenInstance || userRairBalance?.gt(0)) { + if ( + !isLoggedIn || + !currentUserAddress || + !mainTokenInstance || + userRairBalance > BigInt(0) + ) { return; } const result = await web3TxHandler(mainTokenInstance, 'balanceOf', [ currentUserAddress ]); - if (result?._isBigNumber) { + if (result) { setUserRairBalance(result); } - }, [mainTokenInstance, currentUserAddress, userRairBalance, web3TxHandler]); + }, [ + isLoggedIn, + currentUserAddress, + mainTokenInstance, + userRairBalance, + web3TxHandler + ]); const [copyEth, setCopyEth] = useState(false); const [notificationArray, setNotificationArray] = useState(); @@ -102,7 +98,7 @@ const MobileNavigationList: React.FC = ({ const getNotifications = useCallback( async (pageNum?: number) => { - if (messageAlert && currentUserAddress) { + if (isLoggedIn && messageAlert && currentUserAddress) { setFlagLoading(true); const result = await rFetch( `/api/notifications${pageNum ? `?pageNum=${Number(pageNum)}` : ''}` @@ -119,22 +115,25 @@ const MobileNavigationList: React.FC = ({ }); setNotificationArray(sortedNotifications); } + } else { + setNotificationArray([]); } }, - [messageAlert, currentUserAddress] + [messageAlert, currentUserAddress, isLoggedIn] ); const getNotificationsCount = useCallback(async () => { - if (currentUserAddress) { + 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]); + }, [currentUserAddress, isLoggedIn]); const changePageForVideo = (currentPage: number) => { setCurrentPageNotification(currentPage); @@ -161,7 +160,7 @@ const MobileNavigationList: React.FC = ({ } setFlagLoading(false); } - }, [currentUserAddress]); + }, [currentUserAddress, getNotifications, getNotificationsCount, reactSwal]); useEffect(() => { getNotificationsCount(); @@ -190,9 +189,7 @@ const MobileNavigationList: React.FC = ({ return ( {messageAlert && messageAlert === 'notification' ? ( - + setMessageAlert(null)}> @@ -233,11 +230,9 @@ const MobileNavigationList: React.FC = ({ return ( ); @@ -262,9 +257,7 @@ const MobileNavigationList: React.FC = ({ )} ) : messageAlert === 'profile' ? ( - + setMessageAlert(null)}> @@ -287,7 +280,7 @@ const MobileNavigationList: React.FC = ({ ) : messageAlert === 'profileEdit' ? (
    = ({ {/* {isLoadingBalance ? : userBalance} */}
    - {currentChain && getBlockchainData(currentChain) && ( + {connectedChain && getBlockchainData(connectedChain) && ( logo )} @@ -407,9 +400,7 @@ const MobileNavigationList: React.FC = ({ )} ) : ( - + {currentUserAddress && (
  • diff --git a/rair-front/src/components/Navigation/MenuComponents/MobileProfileInfo.tsx b/rair-front/src/components/Navigation/MenuComponents/MobileProfileInfo.tsx index af48f6f0b..4688ef612 100644 --- a/rair-front/src/components/Navigation/MenuComponents/MobileProfileInfo.tsx +++ b/rair-front/src/components/Navigation/MenuComponents/MobileProfileInfo.tsx @@ -5,7 +5,7 @@ import CircularProgress from '@mui/material/CircularProgress'; import MobileEditProfile from './MobileEditProfile'; -import { UserType } from '../../../ducks/users/users.types'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; import defaultPictures from './../../UserProfileSettings/images/defaultUserPictures.png'; import { @@ -16,20 +16,18 @@ import { } from './../NavigationItems/NavigationItems'; interface IMobileProfileInfo { - primaryColor: string; click: boolean; toggleOpenProfile: () => void; - userData: UserType | null; } const MobileProfileInfo: React.FC = ({ - primaryColor, click, - toggleOpenProfile, - userData + toggleOpenProfile }) => { + const userData = useAppSelector((store) => store.user); const [profileData, setProfileData] = useState(userData); const [editMode, setEditMode] = useState(false); + const { isDarkMode } = useAppSelector((store) => store.colors); const toggleEditMode = useCallback(() => { setEditMode((prev) => !prev); @@ -55,7 +53,7 @@ const MobileProfileInfo: React.FC = ({ if (!userData) { return ( - + @@ -71,7 +69,7 @@ const MobileProfileInfo: React.FC = ({ } return ( - + {editMode ? ( ) : ( diff --git a/rair-front/src/components/Navigation/NavigationItems/NavigationItems.tsx b/rair-front/src/components/Navigation/NavigationItems/NavigationItems.tsx index a9c400e22..794ab3b33 100644 --- a/rair-front/src/components/Navigation/NavigationItems/NavigationItems.tsx +++ b/rair-front/src/components/Navigation/NavigationItems/NavigationItems.tsx @@ -1,38 +1,38 @@ -import { FieldErrors } from 'react-hook-form'; +import { FieldError, FieldErrorsImpl, Merge } from 'react-hook-form'; +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; interface IMenuMobileWrapper { showAlert?: boolean | undefined | null; - selectedChain?: any | null; primaryColor?: string; editMode?: boolean; click?: boolean; - errors?: FieldErrors | undefined; + errors?: FieldError | Merge>; isSplashPage?: boolean; hotdrops?: string; realChainId?: string | undefined; secondaryColor?: string; + isDarkMode?: boolean; } -export const MenuMobileWrapper = styled.div` +export const MenuMobileWrapper = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` z-index: 50; position: fixed; width: 100%; padding: 0; margin-top: ${(props) => - props.realChainId && - props.showAlert && - !props.isSplashPage && - !props.selectedChain - ? '50px' - : ''}; + props.realChainId && props.showAlert && !props.isSplashPage ? '50px' : ''}; `; -export const Nav = styled.nav` -background: ${(props) => - props.primaryColor === '#dedede' - ? '#fff' - : `color-mix(in srgb, ${props.secondaryColor}, #888888)`}; +export const Nav = styled.nav.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` + background: ${(props) => + props.primaryColor === '#dedede' + ? '#fff' + : `color-mix(in srgb, ${props.secondaryColor}, #888888)`}; display: flex; justify-content: space-between; align-items: center; @@ -40,15 +40,16 @@ background: ${(props) => z-index: 12; width: 100%; position: ${(props) => (props.editMode ? 'fixed' : 'reletive')}; - margin-top: ${(props) => - props.showAlert && props.selectedChain ? '50px' : ''}; + margin-top: ${(props) => (props.showAlert ? '50px' : '')}; @media screen and (max-width: 400px) { padding: 22px 20px; } `; -export const ListItem = styled.li` +export const ListItem = styled.li.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` font-size: 18px; display: flex; align-items: center; @@ -83,11 +84,11 @@ export const TitleEditProfile = styled.h4` } `; -export const List = styled.ul` -background: ${(props) => - props.primaryColor === '#dedede' - ? '#fff' - : `color-mix(in srgb, ${props.secondaryColor}, #888888)`}; +export const List = styled.ul.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` + background: ${({ secondaryColor }) => + `color-mix(in srgb, ${secondaryColor}, #888888)`}; overflow: ${(props) => props.click && 'hidden'}; border-bottom-right-radius: 16px; border-bottom-left-radius: 16px; @@ -140,7 +141,9 @@ export const ListProfileLoading = styled.div` } `; -export const ListEditProfileMode = styled.div` +export const ListEditProfileMode = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` padding: 20px; height: 100%; background: ${(props) => @@ -261,7 +264,9 @@ export const RightSideMenu = styled.div` } `; -export const SearchInputMobile = styled.div` +export const SearchInputMobile = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` position: relative; width: 100%; border-radius: 12px; @@ -305,7 +310,9 @@ export const BackBtnMobileNav = styled.div` export const MobileEditFields = styled.div``; -export const MobileProfileField = styled.div` +export const MobileProfileField = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` display: flex; flex-direction: column; margin-bottom: 8px; @@ -355,7 +362,9 @@ export const MobileProfileField = styled.div` } `; -export const MobileProfileBtnWrapper = styled.div` +export const MobileProfileBtnWrapper = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` display: flex; justify-content: space-between; diff --git a/rair-front/src/components/ResalePage/ItemOffer.tsx b/rair-front/src/components/ResalePage/ItemOffer.tsx index da46c323c..0e09db13f 100644 --- a/rair-front/src/components/ResalePage/ItemOffer.tsx +++ b/rair-front/src/components/ResalePage/ItemOffer.tsx @@ -1,5 +1,4 @@ import React, { memo, useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import { faPause, faPlay } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { useStateIfMounted } from 'use-state-if-mounted'; @@ -8,15 +7,15 @@ import { INftItemComponent } from './listOffers.types'; import { TTokenData } from '../../axios.responseTypes'; import { diamondFactoryAbi } from '../../contracts'; -import { RootState } from '../../ducks'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; -import { UserType } from '../../ducks/users/users.types'; +import useContracts from '../../hooks/useContracts'; +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; import useSwal from '../../hooks/useSwal'; import useWeb3Tx from '../../hooks/useWeb3Tx'; import useWindowDimensions from '../../hooks/useWindowDimensions'; +import { User } from '../../types/databaseTypes'; import { rFetch } from '../../utils/rFetch'; import { ContractType } from '../adminViews/adminView.types'; -import useServerSettings from '../adminViews/useServerSettings'; import { SvgKey } from '../MockUpPage/NftList/SvgKey'; import { gettingPrice } from '../MockUpPage/NftList/utils/gettingPrice'; import defaultAvatar from '../UserProfileSettings/images/defaultUserPictures.png'; @@ -31,9 +30,7 @@ const ItemOfferComponent: React.FC = ({ const [tokenMetadata, setTokenMetadata] = useStateIfMounted< TTokenData | undefined >(undefined); - const [accountData, setAccountData] = useStateIfMounted( - null - ); + const [accountData, setAccountData] = useStateIfMounted(null); const { getBlockchainData } = useServerSettings(); const [playing, setPlaying] = useState(false); const [isFileUrl, setIsFileUrl] = useState(); @@ -44,13 +41,9 @@ const ItemOfferComponent: React.FC = ({ const reactSwal = useSwal(); const { web3TxHandler, correctBlockchain, web3Switch } = useWeb3Tx(); - const { - diamondMarketplaceInstance, - currentUserAddress, - currentChain, - contractCreator - } = useSelector( - (store) => store.contractStore + const { diamondMarketplaceInstance, contractCreator } = useContracts(); + const { currentUserAddress, connectedChain } = useAppSelector( + (store) => store.web3 ); const getTokenMetadata = useCallback(async () => { @@ -133,7 +126,7 @@ const ItemOfferComponent: React.FC = ({ TRADERHash && (await web3TxHandler(instance, 'hasRole', [ TRADERHash, - diamondMarketplaceInstance.address + await diamondMarketplaceInstance.getAddress() ])); if (!can) { reactSwal.fire( @@ -277,7 +270,7 @@ const ItemOfferComponent: React.FC = ({ onClick={purchaseToken} disabled={operatorIsUser} className="btn btn-rhyno mt-5"> - {currentChain !== contractData?.blockchain + {connectedChain !== contractData?.blockchain ? 'Switch network' : operatorIsUser ? 'Cannot purchase your own offer' diff --git a/rair-front/src/components/ResalePage/listOffers.types.ts b/rair-front/src/components/ResalePage/listOffers.types.ts index dc5846398..333d5e979 100644 --- a/rair-front/src/components/ResalePage/listOffers.types.ts +++ b/rair-front/src/components/ResalePage/listOffers.types.ts @@ -1,9 +1,11 @@ -import { UserType } from '../../ducks/users/users.types'; +import { Hex } from 'viem'; + +import { User } from '../../types/databaseTypes'; import { TMetadataType } from './../../axios.responseTypes'; export type TNftDataItem = { - blockchain: BlockchainType | undefined; + blockchain?: Hex; contract: string; operator: string; status: string; @@ -14,7 +16,7 @@ export type TNftDataItem = { }; export interface INftItemComponent { - blockchain: BlockchainType | undefined; + blockchain?: Hex; contract: string; operator: string; status: string; @@ -48,7 +50,7 @@ export type TEmbeddedParamsType = { export interface INftItemForCollectionView { embeddedParams: TEmbeddedParamsType; - blockchain: BlockchainType | undefined; + blockchain: Hex | undefined; pict: string; price: string; offerPrice: string[]; @@ -56,13 +58,13 @@ export interface INftItemForCollectionView { metadata: TMetadataType; offer: string; selectedData: TMetadataType; - someUsersData: UserType; + someUsersData: User; userName: string; tokenDataLength: number; } export type TParamsNftItemForCollectionView = { - blockchain: BlockchainType; + blockchain: Hex; contract: string; product: string; tokenId: string; diff --git a/rair-front/src/components/ServerSettings/TextSettings.tsx b/rair-front/src/components/ServerSettings/TextSettings.tsx new file mode 100644 index 000000000..420afa037 --- /dev/null +++ b/rair-front/src/components/ServerSettings/TextSettings.tsx @@ -0,0 +1,90 @@ +import { useEffect, useState } from 'react'; + +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; +import InputField from '../common/InputField'; + +const TextSettings = () => { + const [customNodeAddress, setCustomNodeAddress] = useState(''); + const [customLegalInfo, setCustomLegalInfo] = useState(''); + const [customSignupMessage, setCustomSignupMessage] = useState(''); + + const { nodeAddress, legal, signupMessage } = useAppSelector( + (store) => store.settings + ); + const { secondaryButtonColor, textColor } = useAppSelector( + (store) => store.colors + ); + + const { updateServerSetting } = useServerSettings(); + + useEffect(() => { + if (nodeAddress) { + setCustomNodeAddress(nodeAddress); + } else { + setCustomNodeAddress(import.meta.env.VITE_NODE_ADDRESS); + } + }, [nodeAddress]); + + useEffect(() => { + if (legal) { + setCustomLegalInfo(legal); + } + }, [legal]); + useEffect(() => { + if (signupMessage) { + setCustomSignupMessage(signupMessage); + } + }, [signupMessage]); + + return ( + <> + {[ + { + title: 'Node address', + getter: customNodeAddress, + setter: setCustomNodeAddress, + setting: 'nodeAddress' + }, + { + title: 'Legal info', + getter: customLegalInfo, + setter: setCustomLegalInfo, + setting: 'legal' + }, + { + title: 'Signup message', + getter: customSignupMessage, + setter: setCustomSignupMessage, + setting: 'signupMessage' + } + ].map((setting, index) => { + return ( +
    +

    {setting.title}

    + + +
    + ); + })} + + ); +}; + +export default TextSettings; diff --git a/rair-front/src/components/ServerSettings/blockchainSettings.tsx b/rair-front/src/components/ServerSettings/blockchainSettings.tsx new file mode 100644 index 000000000..ee009b617 --- /dev/null +++ b/rair-front/src/components/ServerSettings/blockchainSettings.tsx @@ -0,0 +1,332 @@ +import { useCallback, useEffect, useState } from 'react'; +import { AlchemyChainMap } from '@alchemy/aa-core'; +import { Hex } from 'viem'; + +import { useAppDispatch, useAppSelector } from '../../hooks/useReduxHooks'; +import useSwal from '../../hooks/useSwal'; +import { loadSettings } from '../../redux/settingsSlice'; +import { Blockchain } from '../../types/databaseTypes'; +import { rFetch } from '../../utils/rFetch'; +import InputField from '../common/InputField'; + +interface NewBlockchain extends Blockchain { + isNew?: boolean; +} + +const BlockchainSettings = () => { + const dispatch = useAppDispatch(); + const [blockchainSettingsCopy, setBlockchainSettingCopy] = useState< + Array + >([]); + const { blockchainSettings } = useAppSelector((store) => store.settings); + const { textColor, secondaryButtonColor, primaryButtonColor } = + useAppSelector((store) => store.colors); + const reactSwal = useSwal(); + + useEffect(() => { + setBlockchainSettingCopy([...blockchainSettings]); + }, [blockchainSettings]); + + const setBlockchainSetting = useCallback( + async (chain: Hex | undefined, method = 'PUT') => { + if (!chain) { + return; + } + const settings = blockchainSettingsCopy.find( + (chainData) => chainData.hash === chain + ); + + if (!settings) { + return; + } + + const { _id, isNew, ...cleanChainData } = settings; + + if (_id && method === 'POST') { + console.error( + 'error, trying to create a blockchain that already has an ID' + ); + return; + } + if (isNew && method === 'PUT') { + console.error('error, trying to update a blockchain that is new'); + return; + } + + Object.keys(cleanChainData).forEach((field) => { + if (cleanChainData[field] === '') { + cleanChainData[field] = undefined; + } + }); + const { success } = await rFetch(`/api/settings/${chain}`, { + method, + body: JSON.stringify(cleanChainData), + headers: { + 'Content-Type': 'application/json' + } + }); + if (success) { + dispatch(loadSettings()); + reactSwal.fire('Success', 'Blockchain settings updated', 'success'); + } + }, + [blockchainSettingsCopy, dispatch, reactSwal] + ); + + const updateBlockchainSetting = useCallback( + (chain: Hex | undefined, values: Partial) => { + if (!chain) { + return; + } + const aux = blockchainSettingsCopy.map((chainData) => { + if (chainData.hash === chain) { + return { ...chainData, ...values }; + } + return chainData; + }); + setBlockchainSettingCopy(aux); + }, + [blockchainSettingsCopy] + ); + + return ( +
    +

    Blockchain settings:

    + {blockchainSettingsCopy?.map((chain, index) => { + return ( +
    + + {chain.testnet ? ( + + + + ) : ( + '' + )}{' '} + {chain.name} ({chain.hash}) + + {[ + { + label: 'Sync contracts', + setting: 'sync' + }, + { + label: 'Display contracts', + setting: 'display' + }, + { + label: 'Test network', + setting: 'testnet' + }, + { + label: 'Supported by Alchemy SDK', + setting: 'alchemySupport' + } + ].map((booleanSetting, boolSettingIndex) => { + return ( +
    +
    + {booleanSetting.label} +
    +
    + + +
    +
    + ); + })} + {[ + { + label: 'Chain Id (Hexadecimal)', + type: 'text', + setting: 'hash', + effect: (chain) => { + const alchemyData = AlchemyChainMap.get(Number(chain)); + updateBlockchainSetting(chain, { + alchemySupport: !!alchemyData + }); + if (alchemyData) { + updateBlockchainSetting(chain, { + testnet: !!alchemyData?.testnet, + blockExplorerGateway: + alchemyData.blockExplorers?.default?.url || '', + rpcEndpoint: alchemyData.rpcUrls.default.http.at(0) || '', + numericalId: alchemyData.id, + name: alchemyData.name, + symbol: alchemyData.nativeCurrency.symbol + }); + } + } + }, + { + label: 'Name', + type: 'text', + setting: 'name' + }, + { + label: 'Symbol', + type: 'text', + setting: 'symbol' + }, + { + label: 'Block Explorer URL', + type: 'text', + setting: 'blockExplorerGateway' + }, + { + label: 'RPC endpoint', + type: 'text', + setting: 'rpcEndpoint' + }, + { + label: 'Chain ID (Decimal)', + type: 'number', + setting: 'numericalId' + }, + { + label: 'Main ERC20 address', + type: 'text', + setting: 'mainTokenAddress' + }, + { + label: 'Classic Factory Address', + type: 'text', + setting: 'classicFactoryAddress' + }, + { + label: 'Diamond Factory Address', + type: 'text', + setting: 'diamondFactoryAddress' + }, + { + label: 'Marketplace Address', + type: 'text', + setting: 'diamondMarketplaceAddress' + }, + { + label: 'License exchange address', + type: 'text', + setting: 'licenseExchangeAddress' + } + ].map((inputSetting, inputSettingIndex) => { + return ( +
    + { + if (inputSetting.effect) { + inputSetting.effect(chain[inputSetting.setting]); + } + }} + getter={chain[inputSetting.setting]} + setter={(value) => + updateBlockchainSetting(chain.hash, { + [inputSetting.setting]: value + }) + } + type={inputSetting.type} + /> +
    + ); + })} + + +
    +
    + ); + })} + +
    + ); +}; + +export default BlockchainSettings; diff --git a/rair-front/src/components/ServerSettings/booleanSettings.tsx b/rair-front/src/components/ServerSettings/booleanSettings.tsx new file mode 100644 index 000000000..79638913b --- /dev/null +++ b/rair-front/src/components/ServerSettings/booleanSettings.tsx @@ -0,0 +1,65 @@ +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; +import { dataStatuses } from '../../redux/commonTypes'; + +const BooleanSettings = () => { + const { secondaryButtonColor, textColor, primaryButtonColor } = + useAppSelector((store) => store.colors); + const { updateServerSetting } = useServerSettings(); + const { dataStatus, ...settings } = useAppSelector((store) => store.settings); + + return ( +
    + {[ + { + title: 'Only return minted tokens on collection page', + value: 'onlyMintedTokensResult' + }, + { + title: 'Allow demo page uploads', + value: 'demoUploadsEnabled' + }, + { + title: 'Use Vault for super admin verification', + value: 'superAdminsOnVault' + }, + { + title: 'Use gasless resales', + value: 'databaseResales' + } + ].map((item, index) => { + return ( +
    +
    {item.title}
    + + +
    + ); + })} +
    + ); +}; + +export default BooleanSettings; diff --git a/rair-front/src/components/ServerSettings/categorySettings.tsx b/rair-front/src/components/ServerSettings/categorySettings.tsx new file mode 100644 index 000000000..caa8258fb --- /dev/null +++ b/rair-front/src/components/ServerSettings/categorySettings.tsx @@ -0,0 +1,120 @@ +import { useCallback, useEffect, useState } from 'react'; +import { faTrash } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; + +import { useAppDispatch, useAppSelector } from '../../hooks/useReduxHooks'; +import useSwal from '../../hooks/useSwal'; +import { loadCategories } from '../../redux/settingsSlice'; +import { Category } from '../../types/databaseTypes'; +import { rFetch } from '../../utils/rFetch'; +import InputField from '../common/InputField'; + +const CategorySettings = () => { + const dispatch = useAppDispatch(); + const { primaryButtonColor, textColor } = useAppSelector( + (store) => store.colors + ); + const reactSwal = useSwal(); + const [categoryListCopy, setCategoryListCopy] = useState>([]); + + const setCategoryList = useCallback(async () => { + const result = await rFetch('/api/categories', { + method: 'POST', + body: JSON.stringify({ + list: categoryListCopy.map((item) => ({ + _id: item._id, + name: item.name + })) + }), + headers: { + 'Content-Type': 'application/json' + } + }); + if (result.success) { + reactSwal.fire('Success', 'Categories updated', 'success'); + dispatch(loadCategories()); + } + }, [categoryListCopy, dispatch, reactSwal]); + + const { categories } = useAppSelector((store) => store.settings); + + useEffect(() => { + setCategoryListCopy(categories); + }, [categories]); + + const deleteCategory = useCallback( + (index) => { + const aux = [...categoryListCopy]; + aux.splice(index, 1); + setCategoryListCopy(aux); + }, + [categoryListCopy] + ); + + const updateCategory = useCallback( + (index) => (value) => { + const aux = [...categoryListCopy]; + aux[index] = { + ...aux[index], + name: value + }; + setCategoryListCopy(aux); + }, + [categoryListCopy] + ); + + return ( +
    +

    Categories

    + {categoryListCopy.map((categoryData, index) => { + return ( +
    +
    + +
    + +
    + ); + })} + + +
    + ); +}; + +export default CategorySettings; diff --git a/rair-front/src/components/ServerSettings/colorSettings.tsx b/rair-front/src/components/ServerSettings/colorSettings.tsx new file mode 100644 index 000000000..42fd5390c --- /dev/null +++ b/rair-front/src/components/ServerSettings/colorSettings.tsx @@ -0,0 +1,326 @@ +import { useCallback, useEffect, useState } from 'react'; +import { faArrowUp, faTrash } from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; + +import { useAppDispatch, useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; +import useSwal from '../../hooks/useSwal'; +import { + arcticBlue, + bubblegum, + charcoal, + rhyno, + royalPurple +} from '../../redux/colorSlice'; +import { loadSettings } from '../../redux/settingsSlice'; +import { rFetch } from '../../utils/rFetch'; +import InputField from '../common/InputField'; + +const ColorSettings = () => { + const dispatch = useAppDispatch(); + + const [customPrimaryColor, setCustomPrimaryColor] = useState(''); + const [customSecondaryColor, setCustomSecondaryColor] = useState(''); + const [customTextColor, setCustomTextColor] = useState(''); + const [customPrimaryButtonColor, setCustomPrimaryButtonColor] = + useState(''); + const [customSecondaryButtonColor, setCustomSecondaryButtonColor] = + useState(''); + const [customFadeButtonColor, setCustomFadeButtonColor] = + useState(''); + const [customIconColor, setCustomIconColor] = useState(''); + + const [customDarkModeLogo, setCustomDarkModeLogo] = useState(''); + const [customDarkModeMobileLogo, setCustomDarkModeMobileLogo] = + useState(''); + const [customLightModeLogo, setCustomLightModeLogo] = useState(''); + const [customLightModeMobileLogo, setCustomLightModeMobileLogo] = + useState(''); + const [customFavicon, setCustomFavicon] = useState(''); + + const { updateServerSetting } = useServerSettings(); + const reactSwal = useSwal(); + const { primaryButtonColor, textColor } = useAppSelector( + (store) => store.colors + ); + const { + darkModePrimary, + darkModeSecondary, + darkModeText, + buttonPrimaryColor, + buttonSecondaryColor, + buttonFadeColor, + iconColor, + darkModeBannerLogo, + darkModeMobileLogo, + lightModeBannerLogo, + lightModeMobileLogo, + favicon + } = useAppSelector((store) => store.settings); + + useEffect(() => { + if (darkModePrimary) { + setCustomPrimaryColor(darkModePrimary); + } + if (darkModeSecondary) { + setCustomSecondaryColor(darkModeSecondary); + } + if (darkModeText) { + setCustomTextColor(darkModeText); + } + if (buttonPrimaryColor) { + setCustomPrimaryButtonColor(buttonPrimaryColor); + } + if (buttonSecondaryColor) { + setCustomSecondaryButtonColor(buttonSecondaryColor); + } + if (buttonFadeColor) { + setCustomFadeButtonColor(buttonFadeColor); + } + if (iconColor) { + setCustomIconColor(iconColor); + } + if (darkModeBannerLogo) { + setCustomDarkModeLogo(darkModeBannerLogo); + } + if (darkModeMobileLogo) { + setCustomDarkModeMobileLogo(darkModeMobileLogo); + } + if (lightModeBannerLogo) { + setCustomLightModeLogo(lightModeBannerLogo); + } + if (lightModeMobileLogo) { + setCustomLightModeMobileLogo(lightModeMobileLogo); + } + if (favicon) { + setCustomFavicon(favicon); + } + }, [ + buttonFadeColor, + buttonPrimaryColor, + buttonSecondaryColor, + darkModeBannerLogo, + darkModeMobileLogo, + darkModePrimary, + darkModeSecondary, + darkModeText, + favicon, + iconColor, + lightModeBannerLogo, + lightModeMobileLogo + ]); + + const loadImage = useCallback( + (setterTarget) => (file: Blob) => { + const reader = new FileReader(); + reader.onloadend = () => { + if (file.type !== 'video/mp4') { + setterTarget(file); + } else { + reactSwal.fire( + 'Info', + `You cannot upload video as a logo`, + 'warning' + ); + } + }; + if (file) { + reader.readAsDataURL(file); + } + }, + [reactSwal] + ); + + const setAppLogos = useCallback( + async (target: string, image: any) => { + const formData = new FormData(); + if (image) { + formData.append('logoImage', image); + } + formData.append('target', target); + const { success } = await rFetch(`/api/settings/appLogo`, { + method: 'POST', + body: formData + }); + if (success) { + dispatch(loadSettings()); + reactSwal.fire( + 'Success', + `App Logo ${image ? 'Set' : 'Removed'}`, + 'success' + ); + } + }, + [dispatch, reactSwal] + ); + + return ( + <> +
    +

    Custom Dark Mode Colors

    + {[ + { + getter: customPrimaryColor, + setter: setCustomPrimaryColor, + label: 'Primary Color' + }, + { + getter: customSecondaryColor, + setter: setCustomSecondaryColor, + label: 'Secondary Color' + }, + { + getter: customTextColor, + setter: setCustomTextColor, + label: 'Text Color' + }, + { + getter: customPrimaryButtonColor, + setter: setCustomPrimaryButtonColor, + label: 'Primary Button Color' + }, + { + getter: customSecondaryButtonColor, + setter: setCustomSecondaryButtonColor, + label: 'Secondary Button Color' + }, + { + getter: customFadeButtonColor, + setter: setCustomFadeButtonColor, + label: 'Fade Button Color' + }, + { + getter: customIconColor, + setter: setCustomIconColor, + label: 'Icon color' + } + ].map((item, index) => { + return ( +
    +
    + +
    +
    + +
    +
    + ); + })} +
    + + +
    +
    +
    +

    Custom Logos

    + {[ + { + label: 'Dark Mode Desktop Logo', + getter: customDarkModeLogo, + setter: setCustomDarkModeLogo, + target: 'darkModeBannerLogo' + }, + { + label: 'Dark Mode Mobile logo', + getter: customDarkModeMobileLogo, + setter: setCustomDarkModeMobileLogo, + target: 'darkModeMobileLogo' + }, + { + label: 'Light Mode Desktop Logo', + getter: customLightModeLogo, + setter: setCustomLightModeLogo, + target: 'lightModeBannerLogo' + }, + { + label: 'Light Mode Mobile Logo', + getter: customLightModeMobileLogo, + setter: setCustomLightModeMobileLogo, + target: 'lightModeMobileLogo' + }, + { + label: 'Favicon', + getter: customFavicon, + setter: setCustomFavicon, + target: 'favicon' + } + ].map((item, index) => { + return ( +
    +
    + +
    + + +
    + ); + })} +
    + + ); +}; + +export default ColorSettings; diff --git a/rair-front/src/components/ServerSettings/contractManager.tsx b/rair-front/src/components/ServerSettings/contractManager.tsx new file mode 100644 index 000000000..f5e299ad5 --- /dev/null +++ b/rair-front/src/components/ServerSettings/contractManager.tsx @@ -0,0 +1,139 @@ +import { useCallback, useState } from 'react'; +import { + faEye, + faEyeSlash, + faGem, + faLink, + faLinkSlash +} from '@fortawesome/free-solid-svg-icons'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import axios from 'axios'; + +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; +import InputField from '../common/InputField'; + +const ContractManager = ({ contractList, getContractList }) => { + const [textFilter, setTextFilter] = useState(''); + + const { getBlockchainData } = useServerSettings(); + const { primaryButtonColor, textColor, secondaryButtonColor, primaryColor } = + useAppSelector((store) => store.colors); + + const updateContractData = useCallback( + async (id: string, setting: string, value: boolean) => { + await axios.patch( + `/api/contracts/${id}`, + { + [setting]: value + }, + { + headers: { + Accept: 'application/json' + } + } + ); + getContractList(); + }, + [getContractList] + ); + + return ( +
    +
    + +
    +
    + + + + + + + + + {contractList + .filter( + ({ title, contractAddress }) => + title.includes(textFilter) || + contractAddress.includes(textFilter) + ) + .map( + ( + { + title, + diamond, + contractAddress, + _id, + blockchain, + blockView, + blockSync + }, + index + ) => { + const chainData = getBlockchainData(blockchain); + return ( + + + + + ); + } + )} + +
    ContractActions
    + {diamond && }{' '} + {title} ( + {chainData?.symbol}) + + + +
    +
    +
    + ); +}; + +export default ContractManager; diff --git a/rair-front/src/components/ServerSettings/customValues.tsx b/rair-front/src/components/ServerSettings/customValues.tsx new file mode 100644 index 000000000..e87b77196 --- /dev/null +++ b/rair-front/src/components/ServerSettings/customValues.tsx @@ -0,0 +1,100 @@ +import { useEffect, useState } from 'react'; + +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; +import { CustomValue } from '../../types/databaseTypes'; +import InputField from '../common/InputField'; + +const CustomValues = () => { + const [customValuesCopy, setCustomValuesCopy] = useState>( + [] + ); + const { customValues } = useAppSelector((store) => store.settings); + + const { primaryButtonColor, textColor } = useAppSelector( + (store) => store.colors + ); + const { updateServerSetting } = useServerSettings(); + + useEffect(() => { + if (customValues) { + // Redux is passing readonly references + setCustomValuesCopy(JSON.parse(JSON.stringify(customValues))); + } + }, [customValues]); + + const modifyCustomValues = (index, field) => (value) => { + const aux = [...customValuesCopy]; + aux[index][field] = value; + setCustomValuesCopy(aux); + }; + + const deleteCustomValues = (index) => { + const aux = [...customValuesCopy]; + aux.splice(index, 1); + setCustomValuesCopy(aux); + }; + + return ( +
    +

    Server values

    + {customValuesCopy && + customValuesCopy.map((customValue, index) => { + return ( +
    +
    + +
    +
    + +
    + +
    + ); + })} + + +
    + ); +}; + +export default CustomValues; diff --git a/rair-front/src/components/ServerSettings/featuredBanner.tsx b/rair-front/src/components/ServerSettings/featuredBanner.tsx new file mode 100644 index 000000000..78727b90c --- /dev/null +++ b/rair-front/src/components/ServerSettings/featuredBanner.tsx @@ -0,0 +1,104 @@ +import { useCallback, useEffect, useState } from 'react'; + +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; +import { rFetch } from '../../utils/rFetch'; +import { OptionsType } from '../common/commonTypes/InputSelectTypes.types'; +import InputSelect from '../common/InputSelect'; + +const FeaturedBanner = ({ contractList }) => { + const [selectedContract, setSelectedContract] = useState('null'); + const [selectedProduct, setSelectedProduct] = useState('null'); + const [productOptions, setProductOptions] = useState>([]); + const { primaryButtonColor, textColor } = useAppSelector( + (store) => store.colors + ); + const { getBlockchainData, updateServerSetting } = useServerSettings(); + + const { featuredCollection } = useAppSelector((store) => store.settings); + + useEffect(() => { + if (!featuredCollection) { + return; + } + setSelectedContract(featuredCollection.contract); + setSelectedProduct(featuredCollection._id!); + }, [featuredCollection]); + + const getProductData = useCallback(async () => { + if (selectedContract === 'null') { + return; + } + setSelectedProduct('null'); + setProductOptions([]); + const { success, products } = await rFetch( + `/api/contracts/${selectedContract}/products` + ); + if (success) { + setProductOptions( + products.map((product) => { + return { + label: product.name, + value: product._id + }; + }) + ); + } + }, [selectedContract]); + + useEffect(() => { + getProductData(); + }, [getProductData]); + + return ( +
    +

    Featured banner

    +
    +
    + { + const chainData = getBlockchainData(contract.blockchain); + return { + label: `${contract.title} (${chainData?.symbol})`, + value: contract._id + }; + })} + /> +
    +
    + +
    +
    + +
    + ); +}; + +export default FeaturedBanner; diff --git a/rair-front/src/components/ServerSettings/footerSettings.tsx b/rair-front/src/components/ServerSettings/footerSettings.tsx new file mode 100644 index 000000000..44756db6c --- /dev/null +++ b/rair-front/src/components/ServerSettings/footerSettings.tsx @@ -0,0 +1,100 @@ +import { useEffect, useState } from 'react'; + +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; +import { FooterLink } from '../../types/databaseTypes'; +import InputField from '../common/InputField'; + +const FooterSettings = () => { + const [footerLinksCopy, setFooterLinksCopy] = useState>([]); + + const { footerLinks } = useAppSelector((store) => store.settings); + const { primaryButtonColor, textColor } = useAppSelector( + (store) => store.colors + ); + + const { updateServerSetting } = useServerSettings(); + + useEffect(() => { + if (footerLinks) { + // Redux is passing readonly references + setFooterLinksCopy(JSON.parse(JSON.stringify(footerLinks))); + } + }, [footerLinks]); + + const modifyFooterLinks = + (index: number, field: string) => (value: string) => { + const aux = [...footerLinksCopy]; + aux[index][field] = value; + setFooterLinksCopy(aux); + }; + + const deleteFooterLinks = (index: number) => { + const aux = [...footerLinksCopy]; + aux.splice(index, 1); + setFooterLinksCopy(aux); + }; + + return ( +
    +

    Footer items

    + {footerLinksCopy && + footerLinksCopy.map((footerLink, index) => { + return ( +
    +
    + +
    +
    + +
    + +
    + ); + })} + + +
    + ); +}; + +export default FooterSettings; diff --git a/rair-front/src/components/ServerSettings/index.tsx b/rair-front/src/components/ServerSettings/index.tsx new file mode 100644 index 000000000..91d5a230b --- /dev/null +++ b/rair-front/src/components/ServerSettings/index.tsx @@ -0,0 +1,70 @@ +import { useCallback, useEffect, useState } from 'react'; + +import BlockchainSettings from './blockchainSettings'; +import BooleanSettings from './booleanSettings'; +import CategorySettings from './categorySettings'; +import ColorSettings from './colorSettings'; +import ContractManager from './contractManager'; +import CustomValues from './customValues'; +import FeaturedBanner from './featuredBanner'; +import FooterSettings from './footerSettings'; +import SuperAdminSettings from './superAdmins'; +import TextSettings from './TextSettings'; + +import { useAppDispatch } from '../../hooks/useReduxHooks'; +import { loadSettings } from '../../redux/settingsSlice'; +import { Contract } from '../../types/databaseTypes'; +import { rFetch } from '../../utils/rFetch'; + +const ServerSettings = () => { + const [contractList, setContractList] = useState< + Array< + Pick< + Contract, + | 'blockchain' + | 'contractAddress' + | 'diamond' + | 'title' + | '_id' + | 'blockSync' + | 'blockView' + > + > + >([]); + + const dispatch = useAppDispatch(); + + const getContractList = useCallback(async () => { + const { success, contracts } = await rFetch('/api/contracts/factoryList'); + if (success) { + setContractList(contracts); + } + }, []); + + useEffect(() => { + getContractList(); + }, [getContractList]); + + useEffect(() => { + dispatch(loadSettings()); + }, []); + + return ( +
    +
    Server Settings
    + + + + + + + + + +
    + +
    + ); +}; + +export default ServerSettings; diff --git a/rair-front/src/components/ServerSettings/superAdmins.tsx b/rair-front/src/components/ServerSettings/superAdmins.tsx new file mode 100644 index 000000000..9f5a72187 --- /dev/null +++ b/rair-front/src/components/ServerSettings/superAdmins.tsx @@ -0,0 +1,100 @@ +import { useEffect, useState } from 'react'; +import { isAddress } from 'ethers'; +import { Hex } from 'viem'; + +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; +import InputField from '../common/InputField'; + +const SuperAdminSettings = () => { + const [superAdminsCopy, setSuperAdminsCopy] = useState>([]); + + const { superAdmins, superAdminsOnVault } = useAppSelector( + (store) => store.settings + ); + const { primaryButtonColor, textColor } = useAppSelector( + (store) => store.colors + ); + + const { updateServerSetting } = useServerSettings(); + + useEffect(() => { + if (superAdmins) { + setSuperAdminsCopy(JSON.parse(JSON.stringify(superAdmins))); + } + }, [superAdmins]); + + const modifySuperAdminAddress = (index) => (value) => { + const aux = [...superAdminsCopy]; + aux[index] = value; + setSuperAdminsCopy(aux); + }; + + const deleteSuperAdminAddress = (index) => { + const aux = [...superAdminsCopy]; + aux.splice(index, 1); + setSuperAdminsCopy(aux); + }; + + return ( +
    +

    Super admins:

    + {superAdminsOnVault ? 'Currently using Vault' : ''} + {superAdminsCopy && + superAdminsCopy.map((user, index) => { + return ( +
    + + +
    + ); + })} + + +
    + ); +}; + +export default SuperAdminSettings; diff --git a/rair-front/src/components/SplashPage/CoinAgenda2021/CoinAgenda2021.tsx b/rair-front/src/components/SplashPage/CoinAgenda2021/CoinAgenda2021.tsx index 5a442657d..43a18dd42 100644 --- a/rair-front/src/components/SplashPage/CoinAgenda2021/CoinAgenda2021.tsx +++ b/rair-front/src/components/SplashPage/CoinAgenda2021/CoinAgenda2021.tsx @@ -1,18 +1,16 @@ -import { useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { FC, useEffect, useState } from 'react'; import { teamCoinAgendaArray } from './AboutUsTeam'; -import { RootState } from '../../../ducks'; -import { setRealChain } from '../../../ducks/contracts/actions'; -import { setInfoSEO } from '../../../ducks/seo/actions'; -import { TInfoSeo } from '../../../ducks/seo/seo.types'; import { useOpenVideoPlayer } from '../../../hooks/useOpenVideoPlayer'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; import useSwal from '../../../hooks/useSwal'; +import { setSEOInfo } from '../../../redux/seoSlice'; +import { setRequestedChain } from '../../../redux/web3Slice'; +import { SplashPageProps } from '../../../types/commonTypes'; import { splashData } from '../../../utils/infoSplashData/coicAgenda2021'; import MetaTags from '../../SeoTags/MetaTags'; import NotCommercialTemplate from '../NotCommercial/NotCommercialTemplate'; -import { ISplashPageProps } from '../splashPage.types'; import SplashCardButton from '../SplashPageConfig/CardBlock/CardButton/SplashCardButton'; import { handleReactSwal } from '../SplashPageConfig/utils/reactSwalModal'; import UnlockableVideosWrapper from '../SplashPageConfig/VideoBlock/UnlockableVideosWrapper/UnlockableVideosWrapper'; @@ -31,11 +29,9 @@ import '../SplashPageTemplate/AuthorCard/AuthorCard.css'; import '../../AboutPage/AboutPageNew/AboutPageNew.css'; import './CoinAgenda2021.css'; -const CoinAgenda2021SplashPage: React.FC = ({ - setIsSplashPage -}) => { - const dispatch = useDispatch(); - const seo = useSelector((store) => store.seoStore); +const CoinAgenda2021SplashPage: FC = ({ setIsSplashPage }) => { + const dispatch = useAppDispatch(); + const seo = useAppSelector((store) => store.seo); const [openVideoplayer, setOpenVideoPlayer, handlePlayerClick] = useOpenVideoPlayer(); @@ -43,7 +39,7 @@ const CoinAgenda2021SplashPage: React.FC = ({ useEffect(() => { dispatch( - setInfoSEO({ + setSEOInfo({ title: 'CoinAGENDA 2021', ogTitle: 'CoinAGENDA 2021', twitterTitle: 'CoinAGENDA 2021', @@ -59,13 +55,8 @@ const CoinAgenda2021SplashPage: React.FC = ({ faviconMobile: favicon_CoinAgenda21 }) ); - //eslint-disable-next-line }, []); - const primaryColor = useSelector( - (store) => store.colorStore.primaryColor - ); - /* UTILITIES FOR VIDEO PLAYER VIEW */ const [productsFromOffer, selectVideo, setSelectVideo] = useGetProducts(splashData); @@ -81,9 +72,8 @@ const CoinAgenda2021SplashPage: React.FC = ({ }, [setIsSplashPage]); useEffect(() => { - dispatch(setRealChain(ukraineglitchChainId)); - //eslint-disable-next-line - }, []); + dispatch(setRequestedChain(ukraineglitchChainId)); + }, [dispatch]); const togglePurchaseList = () => { setPurchaseList((prev) => !prev); @@ -122,7 +112,6 @@ const CoinAgenda2021SplashPage: React.FC = ({ openVideoplayer={openVideoplayer} setOpenVideoPlayer={setOpenVideoPlayer} handlePlayerClick={handlePlayerClick} - primaryColor={primaryColor} />
    @@ -130,10 +119,7 @@ const CoinAgenda2021SplashPage: React.FC = ({
    - +
  • ); diff --git a/rair-front/src/components/SplashPage/Greyman/GreymanSplashPage.tsx b/rair-front/src/components/SplashPage/Greyman/GreymanSplashPage.tsx index e76d25301..602a1c3c9 100644 --- a/rair-front/src/components/SplashPage/Greyman/GreymanSplashPage.tsx +++ b/rair-front/src/components/SplashPage/Greyman/GreymanSplashPage.tsx @@ -1,24 +1,23 @@ -import React, { useCallback, useEffect, useState } from 'react'; +import { FC, useCallback, useEffect, useState } from 'react'; //Google Analytics import ReactGA from 'react-ga'; import Modal from 'react-modal'; -import { useDispatch, useSelector } from 'react-redux'; import { faArrowRight } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { teamGreymanArray } from './AboutUsTeam'; import { diamondFactoryAbi } from '../../../contracts/index'; -import { RootState } from '../../../ducks'; -import { setRealChain } from '../../../ducks/contracts/actions'; -import { ContractsInitialType } from '../../../ducks/contracts/contracts.types'; -import { setInfoSEO } from '../../../ducks/seo/actions'; -import { TInfoSeo } from '../../../ducks/seo/seo.types'; -import { TUsersInitialState } from '../../../ducks/users/users.types'; +import useConnectUser from '../../../hooks/useConnectUser'; +import useContracts from '../../../hooks/useContracts'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; import useSwal from '../../../hooks/useSwal'; import useWeb3Tx from '../../../hooks/useWeb3Tx'; /* importing images*/ import { metaMaskIcon } from '../../../images'; +import { setSEOInfo } from '../../../redux/seoSlice'; +import { setRequestedChain } from '../../../redux/web3Slice'; +import { CustomModalStyle, SplashPageProps } from '../../../types/commonTypes'; import MobileCarouselNfts from '../../AboutPage/AboutPageNew/ExclusiveNfts/MobileCarouselNfts'; import PurchaseTokenButton from '../../common/PurchaseToken'; import { ImageLazy } from '../../MockUpPage/ImageLazy/ImageLazy'; @@ -33,7 +32,7 @@ import { import NotCommercial from '../NotCommercial/NotCommercial'; import ButtonHelp from '../PurchaseChecklist/ButtonHelp'; import PurchaseChecklist from '../PurchaseChecklist/PurchaseChecklist'; -import { ISplashPageProps, TSplashPageIsActive } from '../splashPage.types'; +import { TSplashPageIsActive } from '../splashPage.types'; /* importing Components*/ import TeamMeet from '../TeamMeet/TeamMeetList'; import { Timeline } from '../Timeline/Timeline'; @@ -50,7 +49,7 @@ import './../../AboutPage/AboutPageNew/AboutPageNew.css'; const TRACKING_ID = 'UA-209450870-5'; // YOUR_OWN_TRACKING_ID ReactGA.initialize(TRACKING_ID); -const customStyles = { +const customStyles: CustomModalStyle = { overlay: { zIndex: '3' }, @@ -71,7 +70,7 @@ const customStyles = { borderRadius: '16px' } }; -const customStylesForVideo = { +const customStylesForVideo: CustomModalStyle = { overlay: { zIndex: '5' }, @@ -97,12 +96,9 @@ const customStylesForVideo = { }; Modal.setAppElement('#root'); -const GreymanSplashPage: React.FC = ({ - connectUserData, - setIsSplashPage -}) => { - const dispatch = useDispatch(); - const seo = useSelector((store) => store.seoStore); +const GreymanSplashPage: FC = ({ setIsSplashPage }) => { + const dispatch = useAppDispatch(); + const seo = useAppSelector((store) => store.seo); const [timerLeft, setTimerLeft] = useState(); const [copies, setCopies] = useState(); const [soldCopies, setSoldCopies] = useState(); @@ -116,22 +112,19 @@ const GreymanSplashPage: React.FC = ({ policy: false, use: false }); + const { connectUserData } = useConnectUser(); const GraymanSplashPageTESTNET = '0xbA947797AA2f1De2cD101d97B1aE6b04182fF3e6'; const GreymanChainId = '0x89'; const offerIndexInMarketplace = '2'; - const primaryColor = useSelector( - (store) => store.colorStore.primaryColor - ); + const { primaryColor } = useAppSelector((store) => store.colors); const [modalIsOpen, setIsOpen] = useState(false); const [modalVideoIsOpen, setVideoIsOpen] = useState(false); - const { loggedIn } = useSelector( - (store) => store.userStore - ); + const { isLoggedIn } = useAppSelector((store) => store.user); useEffect(() => { dispatch( - setInfoSEO({ + setSEOInfo({ title: '#Cryptogreyman', ogTitle: '#Cryptogreyman', twitterTitle: '#Cryptogreyman', @@ -147,16 +140,11 @@ const GreymanSplashPage: React.FC = ({ faviconMobile: GreymanFavicon }) ); - //eslint-disable-next-line }, []); - const { - diamondMarketplaceInstance, - contractCreator, - currentUserAddress, - currentChain - } = useSelector( - (store) => store.contractStore + const { contractCreator, diamondMarketplaceInstance } = useContracts(); + const { currentUserAddress, connectedChain } = useAppSelector( + (store) => store.web3 ); const toggleCheckList = () => { @@ -164,9 +152,8 @@ const GreymanSplashPage: React.FC = ({ }; useEffect(() => { - dispatch(setRealChain(GreymanChainId)); - //eslint-disable-next-line - }, []); + dispatch(setRequestedChain(GreymanChainId)); + }, [dispatch]); const openModal = useCallback(() => { setIsOpen(true); @@ -286,7 +273,7 @@ const GreymanSplashPage: React.FC = ({ }; const showVideoToLogginedUsers = () => { - if (loggedIn) { + if (isLoggedIn) { return ( <> = ({ const getAllProduct = useCallback(async () => { try { - if ( - diamondMarketplaceInstance && - window.ethereum && - currentChain === GreymanChainId - ) { + if (diamondMarketplaceInstance && connectedChain === GreymanChainId) { const responseAllProduct = await web3TxHandler( diamondMarketplaceInstance, 'getOfferInfo', @@ -398,7 +381,7 @@ const GreymanSplashPage: React.FC = ({ } catch (err) { console.error(err); } - }, [diamondMarketplaceInstance, currentChain, web3TxHandler]); + }, [diamondMarketplaceInstance, connectedChain, web3TxHandler]); useEffect(() => { if (!diamondMarketplaceInstance) { @@ -628,11 +611,7 @@ const GreymanSplashPage: React.FC = ({
    {timerLeft === 0 && ( - + )}
    {timerLeft === 0 && ( @@ -914,7 +893,7 @@ const GreymanSplashPage: React.FC = ({ classNameHeadSpan={'text-gradient'} teamArray={teamGreymanArray} /> - + )}
    diff --git a/rair-front/src/components/SplashPage/ImmersiVerse/ImmersiVerseSplashPage.tsx b/rair-front/src/components/SplashPage/ImmersiVerse/ImmersiVerseSplashPage.tsx index 5a379959f..921fd24b3 100644 --- a/rair-front/src/components/SplashPage/ImmersiVerse/ImmersiVerseSplashPage.tsx +++ b/rair-front/src/components/SplashPage/ImmersiVerse/ImmersiVerseSplashPage.tsx @@ -1,20 +1,19 @@ -import React, { useEffect, useState } from 'react'; +import { FC, useEffect, useState } from 'react'; import Modal from 'react-modal'; -import { useDispatch, useSelector } from 'react-redux'; import { teamImmersiverseArray } from './AboutUsTeam'; -import { RootState } from '../../../ducks'; -import { setInfoSEO } from '../../../ducks/seo/actions'; -import { TInfoSeo } from '../../../ducks/seo/seo.types'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; import { DocumentIcon, metaMaskIcon } from '../../../images'; +import { setSEOInfo } from '../../../redux/seoSlice'; +import { CustomModalStyle, SplashPageProps } from '../../../types/commonTypes'; import MobileCarouselNfts from '../../AboutPage/AboutPageNew/ExclusiveNfts/MobileCarouselNfts'; import { ImageLazy } from '../../MockUpPage/ImageLazy/ImageLazy'; import MetaTags from '../../SeoTags/MetaTags'; import AuthorBlock from '../AuthorBlock/AuthorBlock'; import { SXSW1, SXSW2, SXSW3 } from '../images/SxSw/sxSw'; import NotCommercialGeneric from '../NotCommercial/NotCommercialGeneric'; -import { ISplashPageProps, TSplashPageIsActive } from '../splashPage.types'; +import { TSplashPageIsActive } from '../splashPage.types'; import TeamMeet from '../TeamMeet/TeamMeetList'; import favion_Immersil from './../images/favicons/ImmersiverseATX.ico'; @@ -24,7 +23,7 @@ import './../SplashPage.css'; import './../Greyman/./GreymanSplashPageMobile.css'; import './../../AboutPage/AboutPageNew/AboutPageNew.css'; -const customStyles = { +const customStyles: CustomModalStyle = { overlay: { zIndex: '1' }, @@ -48,26 +47,19 @@ const customStyles = { Modal.setAppElement('#root'); -const ImmersiVerseSplashPage: React.FC = ({ - setIsSplashPage -}) => { - const dispatch = useDispatch(); - const seo = useSelector((store) => store.seoStore); +const ImmersiVerseSplashPage: FC = ({ setIsSplashPage }) => { + const dispatch = useAppDispatch(); + const seo = useAppSelector((store) => store.seo); const [, /*active*/ setActive] = useState({ policy: false, use: false }); - const primaryColor = useSelector( - (store) => store.colorStore.primaryColor - ); const [modalIsOpen, setIsOpen] = useState(false); - const currentUserAddress = useSelector( - (store) => store.contractStore.currentUserAddress - ); + const { currentUserAddress } = useAppSelector((store) => store.web3); useEffect(() => { dispatch( - setInfoSEO({ + setSEOInfo({ title: '#ImmersiverseATX', ogTitle: '#ImmersiverseATX', twitterTitle: '#ImmersiverseATX', @@ -93,8 +85,12 @@ const ImmersiVerseSplashPage: React.FC = ({ const [carousel, setCarousel] = useState(carousel_match.matches); window.addEventListener('resize', () => setCarousel(carousel_match.matches)); + let subtitle: Modal; + function afterOpenModal() { - return (subtitle.style.color = '#9013FE'); + if (subtitle?.props?.style?.content) { + return (subtitle.props.style.content.color = '#9013FE'); + } } function closeModal() { @@ -106,8 +102,6 @@ const ImmersiVerseSplashPage: React.FC = ({ })); } - let subtitle: Modal; - const formHyperlink = () => { window.open( 'https://docs.google.com/forms/d/e/1FAIpQLSeSoeMejqA_DntWIJTcJQA4UbWSSUaYfXrj4hFKPPkyzDuByw/viewform', @@ -168,8 +162,7 @@ const ImmersiVerseSplashPage: React.FC = ({ fontWeight: 'bold', paddingTop: '3rem', cursor: 'default' - }} - ref={(_subtitle) => (subtitle = _subtitle)}> + }}> Terms of Service
    @@ -304,7 +297,7 @@ const ImmersiVerseSplashPage: React.FC = ({ arraySplash={'immersiverse'} titleHeadFirst={'About'} /> - +
    ); diff --git a/rair-front/src/components/SplashPage/MarkKohler/MarkKohler.tsx b/rair-front/src/components/SplashPage/MarkKohler/MarkKohler.tsx index ce11214c0..305e58107 100644 --- a/rair-front/src/components/SplashPage/MarkKohler/MarkKohler.tsx +++ b/rair-front/src/components/SplashPage/MarkKohler/MarkKohler.tsx @@ -1,18 +1,15 @@ -import React, { useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import Swal from 'sweetalert2'; +import { FC, useEffect, useState } from 'react'; import { teamTaxHacksSummit } from './AboutUsTeam'; import { AccessTextMarkKohler } from './InformationText'; -import { RootState } from '../../../ducks'; -import { setRealChain } from '../../../ducks/contracts/actions'; -import { setInfoSEO } from '../../../ducks/seo/actions'; -import { TInfoSeo } from '../../../ducks/seo/seo.types'; -import { TUsersInitialState } from '../../../ducks/users/users.types'; import useConnectUser from '../../../hooks/useConnectUser'; import { useOpenVideoPlayer } from '../../../hooks/useOpenVideoPlayer'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; import useSwal from '../../../hooks/useSwal'; +import { setSEOInfo } from '../../../redux/seoSlice'; +import { setRequestedChain } from '../../../redux/web3Slice'; +import { SplashPageProps } from '../../../types/commonTypes'; import { blockchain, contract, @@ -22,7 +19,6 @@ import { rFetch } from '../../../utils/rFetch'; import PurchaseTokenButton from '../../common/PurchaseToken'; import MetaTags from '../../SeoTags/MetaTags'; import NotCommercialTemplate from '../NotCommercial/NotCommercialTemplate'; -import { ISplashPageProps } from '../splashPage.types'; import SplashPageCardWrapper from '../SplashPageConfig/CardBlock/CardBlockWrapper/SplashPageCardWrapper'; import SplashCardButton from '../SplashPageConfig/CardBlock/CardButton/SplashCardButton'; import SplashCardButtonsWrapper from '../SplashPageConfig/CardBlock/CardButtonWrapper/SplashCardButtonsWrapper'; @@ -43,9 +39,9 @@ import KohlerFavicon from './assets/favicon.ico'; import './markKohler.css'; -const MarkKohler: React.FC = ({ setIsSplashPage }) => { - const dispatch = useDispatch(); - const seo = useSelector((store) => store.seoStore); +const MarkKohler: FC = ({ setIsSplashPage }) => { + const dispatch = useAppDispatch(); + const seo = useAppSelector((store) => store.seo); const [productsFromOffer, selectVideo, setSelectVideo] = useGetProducts(splashData); @@ -61,9 +57,9 @@ const MarkKohler: React.FC = ({ setIsSplashPage }) => { /* UTILITIES FOR NFT PURCHASE */ const { connectUserData } = useConnectUser(); - const { loggedIn } = useSelector( - (store) => store.userStore - ); + const { isLoggedIn } = useAppSelector((store) => store.user); + + const rSwal = useSwal(); const [openCheckList, setOpenCheckList] = useState(false); const [purchaseList, setPurchaseList] = useState(true); @@ -76,7 +72,7 @@ const MarkKohler: React.FC = ({ setIsSplashPage }) => { `/api/nft/network/${blockchain}/${contract}/0/token/${nextToken}` ); if (tokenMetadata.success && tokenMetadata?.result?.metadata?.image) { - Swal.fire({ + rSwal.fire({ imageUrl: tokenMetadata.result.metadata.image, imageHeight: 'auto', imageWidth: '65%', @@ -85,17 +81,12 @@ const MarkKohler: React.FC = ({ setIsSplashPage }) => { icon: 'success' }); } else { - Swal.fire('Success', `Bought token #${nextToken}`, 'success'); + rSwal.fire('Success', `Bought token #${nextToken}`, 'success'); } setHasNFT(undefined); }; } - const reactSwal = useSwal(); - - const primaryColor = useSelector( - (store) => store.colorStore.primaryColor - ); const [openVideoplayer, setOpenVideoPlayer, handlePlayerClick] = useOpenVideoPlayer(); @@ -122,14 +113,14 @@ const MarkKohler: React.FC = ({ setIsSplashPage }) => { setMeetingInvite(unlockResponse?.data?.invite?.join_url); } } catch (requestError) { - Swal.fire('NFT Required to unlock this meeting', '', 'info'); + rSwal.fire('NFT Required to unlock this meeting', '', 'info'); setHasNFT(false); } }; useEffect(() => { dispatch( - setInfoSEO({ + setSEOInfo({ title: '#Mark Kohler', ogTitle: '#Mark Kohler', twitterTitle: '#Mark Kohler', @@ -164,7 +155,7 @@ const MarkKohler: React.FC = ({ setIsSplashPage }) => { }, [carousel_match.matches]); useEffect(() => { - dispatch(setRealChain('0x5')); + dispatch(setRequestedChain('0x5')); //eslint-disable-next-line }, []); @@ -223,14 +214,14 @@ const MarkKohler: React.FC = ({ setIsSplashPage }) => { className="card-button-mark-kohler" buttonImg={splashData.button3?.buttonImg || ''} buttonLabel={ - !loggedIn + !isLoggedIn ? splashData.button3?.buttonLabel : hasNFT ? 'Join Zoom' : 'Unlock Meeting' } buttonAction={ - loggedIn + isLoggedIn ? hasNFT ? joinZoom : unlockZoom @@ -461,7 +452,7 @@ const MarkKohler: React.FC = ({ setIsSplashPage }) => { /> @@ -472,7 +463,6 @@ const MarkKohler: React.FC = ({ setIsSplashPage }) => { openVideoplayer={openVideoplayer} setOpenVideoPlayer={setOpenVideoPlayer} handlePlayerClick={handlePlayerClick} - primaryColor={primaryColor} /> {/* )} */} @@ -483,10 +473,7 @@ const MarkKohler: React.FC = ({ setIsSplashPage }) => { classNameGap={true} />
    - +
    ); diff --git a/rair-front/src/components/SplashPage/NFTLA/NFTLASplashPage.tsx b/rair-front/src/components/SplashPage/NFTLA/NFTLASplashPage.tsx index 51187cf8a..cbc5cf6f0 100644 --- a/rair-front/src/components/SplashPage/NFTLA/NFTLASplashPage.tsx +++ b/rair-front/src/components/SplashPage/NFTLA/NFTLASplashPage.tsx @@ -1,14 +1,12 @@ -//@ts-nocheck -import { useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { FC, useEffect, useState } from 'react'; import { teamNFTLAarray } from './AboutUsTeam'; -import { ISplashPageProps } from './splashPage.types'; -import { RootState } from '../../../ducks'; -import { setInfoSEO } from '../../../ducks/seo/actions'; import { useOpenVideoPlayer } from '../../../hooks/useOpenVideoPlayer'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; import useSwal from '../../../hooks/useSwal'; +import { setSEOInfo } from '../../../redux/seoSlice'; +import { SplashPageProps } from '../../../types/commonTypes'; import { splashData } from '../../../utils/infoSplashData/nftla'; import MetaTags from '../../SeoTags/MetaTags'; /* importing images*/ @@ -38,13 +36,10 @@ import './../SplashPageTemplate/AuthorCard/AuthorCard.css'; //const TRACKING_ID = 'UA-209450870-5'; // YOUR_OWN_TRACKING_ID //ReactGA.initialize(TRACKING_ID); -const NFTLASplashPage: React.FC = ({ setIsSplashPage }) => { - const dispatch = useDispatch(); - const seo = useSelector((store) => store.seoStore); +const NFTLASplashPage: FC = ({ setIsSplashPage }) => { + const dispatch = useAppDispatch(); + const seo = useAppSelector((store) => store.seo); // TODO: Until we have a contract it will be commented - const primaryColor = useSelector( - (store) => store.colorStore.primaryColor - ); const reactSwal = useSwal(); const carousel_match = window.matchMedia('(min-width: 900px)'); const [carousel, setCarousel] = useState(carousel_match.matches); @@ -56,7 +51,7 @@ const NFTLASplashPage: React.FC = ({ setIsSplashPage }) => { useEffect(() => { dispatch( - setInfoSEO({ + setSEOInfo({ title: 'Official NFTLA Streaming NFTs', ogTitle: 'Official NFTLA Streaming NFTs', twitterTitle: 'Official NFTLA Streaming NFTs', @@ -114,7 +109,6 @@ const NFTLASplashPage: React.FC = ({ setIsSplashPage }) => { openVideoplayer={openVideoplayer} setOpenVideoPlayer={setOpenVideoPlayer} handlePlayerClick={handlePlayerClick} - primaryColor={primaryColor} /> = ({ setIsSplashPage }) => { titleHeadFirst={'About'} teamArray={teamNFTLAarray} /> - +
    ); diff --git a/rair-front/src/components/SplashPage/NFTNYC/NFTNYC.tsx b/rair-front/src/components/SplashPage/NFTNYC/NFTNYC.tsx index 66943d615..d10aae9a7 100644 --- a/rair-front/src/components/SplashPage/NFTNYC/NFTNYC.tsx +++ b/rair-front/src/components/SplashPage/NFTNYC/NFTNYC.tsx @@ -1,14 +1,14 @@ -import { useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { FC, useEffect, useState } from 'react'; import { teamNFTNYCArray } from './AboutUsTeam'; -import { RootState } from '../../../ducks'; -import { setRealChain } from '../../../ducks/contracts/actions'; -import { setInfoSEO } from '../../../ducks/seo/actions'; -import { TInfoSeo } from '../../../ducks/seo/seo.types'; +import useConnectUser from '../../../hooks/useConnectUser'; import { useOpenVideoPlayer } from '../../../hooks/useOpenVideoPlayer'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; import useSwal from '../../../hooks/useSwal'; +import { setSEOInfo } from '../../../redux/seoSlice'; +import { setRequestedChain } from '../../../redux/web3Slice'; +import { SplashPageProps } from '../../../types/commonTypes'; import { useNFTNYC } from '../../../utils/infoSplashData/nftnyc'; import { ImageLazy } from '../../MockUpPage/ImageLazy/ImageLazy'; import CustomButton from '../../MockUpPage/utils/button/CustomButton'; @@ -16,7 +16,6 @@ import MetaTags from '../../SeoTags/MetaTags'; import NFTNYC_favicon from '../images/favicons/NFTNYX_TITLE.ico'; import { NFTNYC_TITLE, warning0 } from '../images/NFTNYC/nftnyc'; import NotCommercialTemplate from '../NotCommercial/NotCommercialTemplate'; -import { ISplashPageProps } from '../splashPage.types'; import SplashCardButton from '../SplashPageConfig/CardBlock/CardButton/SplashCardButton'; import { handleReactSwal } from '../SplashPageConfig/utils/reactSwalModal'; import UnlockableVideosWrapper from '../SplashPageConfig/VideoBlock/UnlockableVideosWrapper/UnlockableVideosWrapper'; @@ -33,21 +32,17 @@ import '../SplashPageTemplate/AuthorCard/AuthorCard.css'; import '../../AboutPage/AboutPageNew/AboutPageNew.css'; import './NFTNYC.css'; -const NFTNYCSplashPage: React.FC = ({ - connectUserData, - setIsSplashPage -}) => { - const dispatch = useDispatch(); - const seo = useSelector((store) => store.seoStore); - const primaryColor = useSelector( - (store) => store.colorStore.primaryColor - ); +const NFTNYCSplashPage: FC = ({ setIsSplashPage }) => { + const dispatch = useAppDispatch(); + const seo = useAppSelector((store) => store.seo); + const { primaryColor } = useAppSelector((store) => store.colors); + const { connectUserData } = useConnectUser(); const { splashData } = useNFTNYC(connectUserData); const reactSwal = useSwal(); useEffect(() => { dispatch( - setInfoSEO({ + setSEOInfo({ title: 'NFTNYC X RAIR', ogTitle: 'NFTNYC X RAIR', twitterTitle: 'NFTNYC X RAIR', @@ -83,7 +78,7 @@ const NFTNYCSplashPage: React.FC = ({ }; useEffect(() => { - dispatch(setRealChain(ukraineglitchChainId)); + dispatch(setRequestedChain(ukraineglitchChainId)); //eslint-disable-next-line }, []); @@ -177,7 +172,6 @@ const NFTNYCSplashPage: React.FC = ({ openVideoplayer={openVideoplayer} setOpenVideoPlayer={setOpenVideoPlayer} handlePlayerClick={handlePlayerClick} - primaryColor={primaryColor} /> {/* = ({ titleHeadFirst={'About'} teamArray={teamNFTNYCArray} /> - +
    ); diff --git a/rair-front/src/components/SplashPage/Nipseyverse/index.tsx b/rair-front/src/components/SplashPage/Nipseyverse/index.tsx index 61802121e..a16946ce9 100644 --- a/rair-front/src/components/SplashPage/Nipseyverse/index.tsx +++ b/rair-front/src/components/SplashPage/Nipseyverse/index.tsx @@ -1,6 +1,5 @@ -import React, { useCallback, useEffect, useState } from 'react'; +import { FC, useCallback, useEffect, useState } from 'react'; import Modal from 'react-modal'; -import { useDispatch, useSelector } from 'react-redux'; import { useNavigate } from 'react-router-dom'; import { faFacebookF, @@ -14,19 +13,13 @@ import axios from 'axios'; import { teamNipseyverseArray } from './AboutUsTeam'; import { TProductResponseType } from '../../../axios.responseTypes'; -import { erc721Abi } from '../../../contracts/index'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; -import { setRealChain } from '../../../ducks/contracts/actions'; -import { ContractsInitialType } from '../../../ducks/contracts/contracts.types'; -import { setInfoSEO } from '../../../ducks/seo/actions'; -import { InitialState } from '../../../ducks/seo/reducers'; -import { TInfoSeo } from '../../../ducks/seo/seo.types'; -import useSwal from '../../../hooks/useSwal'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; import useWeb3Tx from '../../../hooks/useWeb3Tx'; /* importing images*/ import { discrodIconNoBorder, metaMaskIcon } from '../../../images'; -import { rFetch } from '../../../utils/rFetch'; +import { setSEOInfo } from '../../../redux/seoSlice'; +import { setRequestedChain } from '../../../redux/web3Slice'; +import { CustomModalStyle, SplashPageProps } from '../../../types/commonTypes'; import MetaTags from '../../SeoTags/MetaTags'; import ExclusiveNft from '../ExclusiveNft/ExclusiveNft'; import { LogoAuthor } from '../images/commingSoon/commingSoonImages'; @@ -48,7 +41,7 @@ import { } from '../images/splashPageImages/splashPage'; import NipseyRelease from '../NipseyRelease/NipseyRelease'; import RoadMap from '../Roadmap/RoadMap'; -import { ISplashPageProps, TSplashPageIsActive } from '../splashPage.types'; +import { TSplashPageIsActive } from '../splashPage.types'; import TeamMeet from '../TeamMeet/TeamMeetList'; import { Countdown } from '../Timer/CountDown'; /* importing Components*/ @@ -57,7 +50,7 @@ import UnlockVideos from '../UnlockVideos/UnlockVideos'; import './../SplashPage.css'; -const customStyles = { +const customStyles: CustomModalStyle = { overlay: { zIndex: '1' }, @@ -79,23 +72,22 @@ const customStyles = { } }; -const SplashPage: React.FC = ({ setIsSplashPage }) => { - const dispatch = useDispatch(); +const SplashPage: FC = ({ setIsSplashPage }) => { + const dispatch = useAppDispatch(); const navigate = useNavigate(); const [dataNipsey, setDataNipsey] = useState(); const [copies, setCopies] = useState(); const [timerLeft, setTimerLeft] = useState(); - const seo = useSelector((store) => store.seoStore); + const seo = useAppSelector((store) => store.seo); useEffect(() => { - dispatch(setInfoSEO(InitialState)); + dispatch(setSEOInfo()); //eslint-disable-next-line }, []); - const reactSwal = useSwal(); - const { web3TxHandler, correctBlockchain, web3Switch } = useWeb3Tx(); + const { correctBlockchain, web3Switch } = useWeb3Tx(); useEffect(() => { - dispatch(setRealChain('0x1')); + dispatch(setRequestedChain('0x1')); //eslint-disable-next-line }, []); @@ -106,55 +98,8 @@ const SplashPage: React.FC = ({ setIsSplashPage }) => { // let params = `scrollbars=no,resizable=no,status=no,location=no, // toolbar=no,menubar=no,width=700,height=800,left=100,top=100`; - const { minterInstance, contractCreator } = useSelector< - RootState, - ContractsInitialType - >((store) => store.contractStore); - const targetBlockchain = '0x5'; - const nipseyAddress = '0xCB0252EeD5056De450Df4D8D291B4c5E8Af1D9A6'; - - const buyNipsey = async () => { - const { /*success*/ products } = await rFetch( - `/api/contracts/${nipseyAddress}/products/offers` - ); - const instance = contractCreator?.(nipseyAddress, erc721Abi); - const nextToken = await instance?.getNextSequentialIndex(0, 50, 250); - reactSwal.fire({ - title: 'Please wait...', - html: `Buying token #${nextToken.toString()}`, - icon: 'info', - showConfirmButton: false - }); - const [firstPressingOffer] = products[0].offers.filter( - (item) => item.offerName === '1st Pressing' - ); - if (!firstPressingOffer || !minterInstance) { - reactSwal.fire('Error', 'An error has ocurred', 'error'); - return; - } - if ( - await web3TxHandler( - minterInstance, - 'buyToken', - [ - products[0].offerPool.marketplaceCatalogIndex, - firstPressingOffer.offerIndex, - nextToken, - { - value: firstPressingOffer.price - } - ], - { - intendedBlockchain: targetBlockchain, - failureMessage: - 'Sorry your transaction failed! When several people try to buy at once - only one transaction can get to the blockchain first. Please try again!' - } - ) - ) { - reactSwal.fire('Success', `Bought token #${nextToken}!`, 'success'); - } - }; + // const nipseyAddress = '0xCB0252EeD5056De450Df4D8D291B4c5E8Af1D9A6'; let subtitle: Modal; const [modalIsOpen, setIsOpen] = useState(false); @@ -168,7 +113,9 @@ const SplashPage: React.FC = ({ setIsSplashPage }) => { }, []); function afterOpenModal() { - subtitle.style.color = '#9013FE'; + if (subtitle?.props.style?.content?.color) { + subtitle.props.style.content.color = '#9013FE'; + } } function closeModal() { @@ -180,10 +127,9 @@ const SplashPage: React.FC = ({ setIsSplashPage }) => { })); } - const { primaryColor, headerLogoMobile } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { primaryColor, headerLogoMobile } = useAppSelector( + (store) => store.colors + ); const getAllProduct = useCallback(async () => { const responseAllProduct = await axios.get( @@ -262,8 +208,7 @@ const SplashPage: React.FC = ({ setIsSplashPage }) => { fontWeight: 'bold', paddingTop: '3rem', cursor: 'default' - }} - ref={(_subtitle) => (subtitle = _subtitle)}> + }}> Terms of Service
    @@ -326,7 +271,7 @@ const SplashPage: React.FC = ({ setIsSplashPage }) => {
    - + = ({ - primaryColor, NFTName }) => { + const { isDarkMode } = useAppSelector((store) => store.colors); return (
    Your {NFTName} is released under Attribution-NonCommercial 4.0 @@ -22,13 +23,13 @@ const NotCommercialTemplate2: React.FC = ({

    You are free to:

    = ({

    = ({

    The licensor cannot revoke these freedoms as long as you follow the license terms.

    Under the following terms:

    = ({

    {/* className="non-commercial-par-under"> */} = ({ primaryColor }) => { +const NotCommercial: FC = () => { + const { isDarkMode } = useAppSelector((store) => store.colors); return (

    Your cryptogreyman is released under Attribution-NonCommercial 4.0 @@ -17,39 +18,39 @@ const NotCommercial: React.FC = ({ primaryColor }) => {

    You are free to:

    Share — copy and redistribute the material in any medium or format

    Adapt — remix, transform, and build upon the material

    The licensor cannot revoke these freedoms as long as you follow the license terms.

    Under the following terms:

    Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in @@ -59,7 +60,7 @@ const NotCommercial: React.FC = ({ primaryColor }) => {

    NonCommercial — You may not use the material for commercial diff --git a/rair-front/src/components/SplashPage/NotCommercial/NotCommercialGeneric.tsx b/rair-front/src/components/SplashPage/NotCommercial/NotCommercialGeneric.tsx index c7b444fcb..05ad28fc2 100644 --- a/rair-front/src/components/SplashPage/NotCommercial/NotCommercialGeneric.tsx +++ b/rair-front/src/components/SplashPage/NotCommercial/NotCommercialGeneric.tsx @@ -1,17 +1,16 @@ -import React from 'react'; +import { FC } from 'react'; -import { INotCommercialGeneric } from '../splashPage.types'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; import './NotCommercial.css'; -const NotCommercialGeneric: React.FC = ({ - primaryColor -}) => { +const NotCommercialGeneric: FC = () => { + const { isDarkMode } = useAppSelector((store) => store.colors); return (

    Your NFT art is released under Attribution-NonCommercial 4.0 @@ -19,39 +18,39 @@ const NotCommercialGeneric: React.FC = ({

    You are free to:

    Share — copy and redistribute the material in any medium or format

    Adapt — remix, transform, and build upon the material

    The licensor cannot revoke these freedoms as long as you follow the license terms.

    Under the following terms:

    Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in @@ -61,7 +60,7 @@ const NotCommercialGeneric: React.FC = ({

    NonCommercial — You may not use the material for commercial diff --git a/rair-front/src/components/SplashPage/NotCommercial/NotCommercialTemplate.tsx b/rair-front/src/components/SplashPage/NotCommercial/NotCommercialTemplate.tsx index fa6f50289..bbe6ed075 100644 --- a/rair-front/src/components/SplashPage/NotCommercial/NotCommercialTemplate.tsx +++ b/rair-front/src/components/SplashPage/NotCommercial/NotCommercialTemplate.tsx @@ -1,18 +1,17 @@ -import React from 'react'; +import { FC } from 'react'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; import { INotCommercialTemplate } from '../splashPage.types'; import './NotCommercial.css'; -const NotCommercialTemplate: React.FC = ({ - primaryColor, - NFTName -}) => { +const NotCommercialTemplate: FC = ({ NFTName }) => { + const { isDarkMode } = useAppSelector((store) => store.colors); return (

    Your {NFTName} is released under Attribution-NonCommercial 4.0 @@ -20,39 +19,39 @@ const NotCommercialTemplate: React.FC = ({

    You are free to:

    Share — copy and redistribute the material in any medium or format

    Adapt — remix, transform, and build upon the material

    The licensor cannot revoke these freedoms as long as you follow the license terms.

    Under the following terms:

    Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in @@ -62,7 +61,7 @@ const NotCommercialTemplate: React.FC = ({

    NonCommercial — You may not use the material for commercial diff --git a/rair-front/src/components/SplashPage/Nutcrackers/Nutcrackers.tsx b/rair-front/src/components/SplashPage/Nutcrackers/Nutcrackers.tsx index 1f34da182..acb267343 100644 --- a/rair-front/src/components/SplashPage/Nutcrackers/Nutcrackers.tsx +++ b/rair-front/src/components/SplashPage/Nutcrackers/Nutcrackers.tsx @@ -1,23 +1,17 @@ /* eslint-disable react/no-unescaped-entities */ -import { useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { FC, useEffect, useState } from 'react'; import Box from '@mui/material/Box'; import CircularProgress from '@mui/material/CircularProgress'; +import { Hex } from 'viem'; import { teamNutArray } from './AboutUsTeam'; -import { erc721Abi } from '../../../contracts/index'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; -import { setRealChain } from '../../../ducks/contracts/actions'; -import { ContractsInitialType } from '../../../ducks/contracts/contracts.types'; -import { setInfoSEO } from '../../../ducks/seo/actions'; -import { InitialState } from '../../../ducks/seo/reducers'; -import { TInfoSeo } from '../../../ducks/seo/seo.types'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; import useSwal from '../../../hooks/useSwal'; -import useWeb3Tx from '../../../hooks/useWeb3Tx'; import { metaMaskIcon } from '../../../images'; -import { rFetch } from '../../../utils/rFetch'; +import { setSEOInfo } from '../../../redux/seoSlice'; +import { setRequestedChain } from '../../../redux/web3Slice'; +import { SplashPageProps } from '../../../types/commonTypes'; import PurchaseTokenButton from '../../common/PurchaseToken'; import { ImageLazy } from '../../MockUpPage/ImageLazy/ImageLazy'; import MetaTags from '../../SeoTags/MetaTags'; @@ -35,90 +29,26 @@ import { PoweredRair } from '../images/splashPageImages/splashPage'; // import photoNut from '../images/block-nuts-photos.png'; import TeamMeet from '../TeamMeet/TeamMeetList'; -const Nutcrackers = ({ connectUserData, setIsSplashPage }) => { - const dispatch = useDispatch(); - const { primaryColor } = useSelector( - (store) => store.colorStore - ); +const Nutcrackers: FC = ({ setIsSplashPage }) => { + const dispatch = useAppDispatch(); + const { primaryColor } = useAppSelector((store) => store.colors); const [, /*percentTokens*/ setPresentTokens] = useState(0); - const seo = useSelector((store) => store.seoStore); + const seo = useAppSelector((store) => store.seo); const leftTokensNumber = 50; const wholeTokens = 50; - const { currentUserAddress, minterInstance, contractCreator } = useSelector< - RootState, - ContractsInitialType - >((store) => store.contractStore); const reactSwal = useSwal(); - const { web3TxHandler, web3Switch, correctBlockchain } = useWeb3Tx(); useEffect(() => { - dispatch(setInfoSEO(InitialState)); + dispatch(setSEOInfo()); //eslint-disable-next-line }, []); - const targetBlockchain = '0x89'; - const nutcrackerAddress = - '0xF4ca90d4a796f57133c6de47c2261BF237cfF780'.toLowerCase(); - const mintNutcracker = async () => { - if (!currentUserAddress) { - connectUserData(); - return; - } - - if (correctBlockchain(targetBlockchain)) { - web3Switch(targetBlockchain); - return; - } - - const { success, products } = await rFetch( - `/api/contracts/network/0x89/${nutcrackerAddress}/offers` - ); - if (success && contractCreator && minterInstance) { - const instance = contractCreator(nutcrackerAddress, erc721Abi); - if (!instance) { - return; - } - const nextToken = await instance.getNextSequentialIndex(0, 0, 50); - reactSwal.fire({ - title: 'Please wait...', - html: `Buying Nutcracker #${nextToken.toString()}`, - icon: 'info', - showConfirmButton: false - }); - const [nutsOffer] = products[0].offers.filter( - (item) => item.offerName === 'Nuts' - ); - if (!nutsOffer) { - reactSwal.fire('Error', 'An error has ocurred', 'error'); - return; - } - if ( - await web3TxHandler( - minterInstance, - 'buyToken', - [ - products[0].offerPool.marketplaceCatalogIndex, - nutsOffer.offerIndex, - nextToken, - { - value: nutsOffer.price - } - ], - { - intendedBlockchain: targetBlockchain, - failureMessage: - 'Sorry your transaction failed! When several people try to buy at once - only one transaction can get to the blockchain first. Please try again!' - } - ) - ) { - reactSwal.fire('Success', `Bought token #${nextToken}!`, 'success'); - } - } - }; + const targetBlockchain: Hex = '0x89'; + const nutcrackerAddress: Hex = '0xF4ca90d4a796f57133c6de47c2261BF237cfF780'; useEffect(() => { - dispatch(setRealChain('0x89')); + dispatch(setRequestedChain(targetBlockchain)); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); @@ -172,7 +102,6 @@ const Nutcrackers = ({ connectUserData, setIsSplashPage }) => { diamond: false, requiredBlockchain: '0x89', offerIndex: ['1', '0'], - connectUserData, buttonLabel: 'Mint with Matic', customSuccessAction: (nextToken) => { reactSwal.fire( @@ -186,7 +115,7 @@ const Nutcrackers = ({ connectUserData, setIsSplashPage }) => { {false && (

    -
    ); diff --git a/rair-front/src/components/SplashPage/SimDogs/SimDogs.tsx b/rair-front/src/components/SplashPage/SimDogs/SimDogs.tsx index 3c1246a69..7b0d1bd32 100644 --- a/rair-front/src/components/SplashPage/SimDogs/SimDogs.tsx +++ b/rair-front/src/components/SplashPage/SimDogs/SimDogs.tsx @@ -1,19 +1,17 @@ import { useCallback, useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; import axios from 'axios'; import { teamSimDogsArray } from './AboutUsTeam'; import { BackStorySimDogs } from './InformationText'; -import { TFileType, TNftFilesResponse } from '../../../axios.responseTypes'; -import RairFavicon from '../../../components/MockUpPage/assets/rair_favicon.ico'; -import { RootState } from '../../../ducks'; -import { setRealChain } from '../../../ducks/contracts/actions'; -import { setInfoSEO } from '../../../ducks/seo/actions'; -import { TInfoSeo } from '../../../ducks/seo/seo.types'; +import { TNftFilesResponse } from '../../../axios.responseTypes'; import useConnectUser from '../../../hooks/useConnectUser'; import { useOpenVideoPlayer } from '../../../hooks/useOpenVideoPlayer'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; import useSwal from '../../../hooks/useSwal'; +import { setSEOInfo } from '../../../redux/seoSlice'; +import { setRequestedChain } from '../../../redux/web3Slice'; +import { CatalogVideoItem, SplashPageProps } from '../../../types/commonTypes'; import { donationGridData, splashData @@ -21,7 +19,7 @@ import { import MetaTags from '../../SeoTags/MetaTags'; import { SimDogs0 } from '../images/simDogs/simDogs'; import NotCommercialTemplate from '../NotCommercial/NotCommercialTemplate'; -import { ICustomButtonBlock, ISplashPageProps } from '../splashPage.types'; +import { ICustomButtonBlock } from '../splashPage.types'; import SplashCardButton from '../SplashPageConfig/CardBlock/CardButton/SplashCardButton'; import CardParagraphText from '../SplashPageConfig/CardParagraphText/CardParagraphText'; import { handleReactSwal } from '../SplashPageConfig/utils/reactSwalModal'; @@ -48,14 +46,16 @@ import '../SplashPageTemplate/AuthorCard/AuthorCard.css'; //const TRACKING_ID = 'UA-209450870-5'; // YOUR_OWN_TRACKING_ID //ReactGA.initialize(TRACKING_ID); -const SimDogsSplashPage: React.FC = ({ setIsSplashPage }) => { - const dispatch = useDispatch(); - const seo = useSelector((store) => store.seoStore); +const SimDogsSplashPage: React.FC = ({ setIsSplashPage }) => { + const dispatch = useAppDispatch(); + const seo = useAppSelector((store) => store.seo); const reactSwal = useSwal(); /* UTILITIES FOR NFT PURCHASE */ /* UTILITIES FOR VIDEO PLAYER VIEW */ - const [productsFromOffer, setProductsFromOffer] = useState([]); - const [selectVideo, setSelectVideo] = useState(); + const [productsFromOffer, setProductsFromOffer] = useState< + CatalogVideoItem[] + >([]); + const [selectVideo, setSelectVideo] = useState(); const [openVideoplayer, setOpenVideoPlayer, handlePlayerClick] = useOpenVideoPlayer(); @@ -63,27 +63,6 @@ const SimDogsSplashPage: React.FC = ({ setIsSplashPage }) => { const { connectUserData } = useConnectUser(); - useEffect(() => { - dispatch( - setInfoSEO({ - title: 'Sim Dogs', - ogTitle: 'Sim Dogs', - twitterTitle: 'Sim Dogs', - contentName: 'author', - content: '', - description: 'BUY A DOG, WIN A LAWSUIT & END SIM SWAP CRIME!', - ogDescription: 'BUY A DOG, WIN A LAWSUIT & END SIM SWAP CRIME!', - twitterDescription: 'BUY A DOG, WIN A LAWSUIT & END SIM SWAP CRIME!', - image: SimDogs0, - favicon: RairFavicon, - faviconMobile: RairFavicon - }) - ); - //eslint-disable-next-line - }, []); - - //an option for custom button arrangment - const getProductsFromOffer = useCallback(async () => { const response = await axios.get( `/api/nft/network/0x1/0xA5A823294AF53B983969BB48cAA3cDb28545828F/0/files` @@ -110,9 +89,7 @@ const SimDogsSplashPage: React.FC = ({ setIsSplashPage }) => { const customButtonBlock = ; - const primaryColor = useSelector( - (store) => store.colorStore.primaryColor - ); + const { primaryColor } = useAppSelector((store) => store.colors); /* UTILITIES FOR NFT PURCHASE */ const [openCheckList /*setOpenCheckList*/] = useState(false); @@ -124,7 +101,7 @@ const SimDogsSplashPage: React.FC = ({ setIsSplashPage }) => { useEffect(() => { dispatch( - setInfoSEO({ + setSEOInfo({ title: 'Sim Dogs', ogTitle: 'Sim Dogs', twitterTitle: 'Sim Dogs', @@ -149,9 +126,8 @@ const SimDogsSplashPage: React.FC = ({ setIsSplashPage }) => { }, [setIsSplashPage]); useEffect(() => { - dispatch(setRealChain(mainChain)); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + dispatch(setRequestedChain(mainChain)); + }, [dispatch]); return (
    @@ -173,30 +149,6 @@ const SimDogsSplashPage: React.FC = ({ setIsSplashPage }) => { customButtonBlock }} /> -
    - {/* */} -
    {productsFromOffer && productsFromOffer.length > 0 && ( @@ -218,7 +170,6 @@ const SimDogsSplashPage: React.FC = ({ setIsSplashPage }) => { openVideoplayer={openVideoplayer} setOpenVideoPlayer={setOpenVideoPlayer} handlePlayerClick={handlePlayerClick} - primaryColor={primaryColor} /> )} @@ -235,7 +186,7 @@ const SimDogsSplashPage: React.FC = ({ setIsSplashPage }) => { arraySplash={'sim-dogs'} teamArray={teamSimDogsArray} /> - +
    ); diff --git a/rair-front/src/components/SplashPage/SlideLock/SlideLock.tsx b/rair-front/src/components/SplashPage/SlideLock/SlideLock.tsx index a89200e31..829fccb87 100644 --- a/rair-front/src/components/SplashPage/SlideLock/SlideLock.tsx +++ b/rair-front/src/components/SplashPage/SlideLock/SlideLock.tsx @@ -1,14 +1,10 @@ -import React, { useCallback, useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { FC, useEffect, useState } from 'react'; import { teamSlideLockArray } from './AboutUsTeam'; -import { RootState } from '../../../ducks'; -import { ContractsInitialType } from '../../../ducks/contracts/contracts.types'; -import { setInfoSEO } from '../../../ducks/seo/actions'; -import { InitialState } from '../../../ducks/seo/reducers'; -import { TInfoSeo } from '../../../ducks/seo/seo.types'; -import { TUsersInitialState } from '../../../ducks/users/users.types'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; +import { setSEOInfo } from '../../../redux/seoSlice'; +import { SplashPageProps } from '../../../types/commonTypes'; import { splashData } from '../../../utils/infoSplashData/slideLock'; import MetaTags from '../../SeoTags/MetaTags'; /* importing images*/ @@ -21,7 +17,6 @@ import { videoBackground } from '../images/slideLock/slideLock'; import NotCommercialTemplate from '../NotCommercial/NotCommercialTemplate'; -import { ISplashPageProps } from '../splashPage.types'; import AuthorCard from '../SplashPageTemplate/AuthorCard/AuthorCard'; import NFTImages from '../SplashPageTemplate/NFTImages/NFTImages'; import VideoPlayerModule from '../SplashPageTemplate/VideoPlayer/VideoPlayerModule'; @@ -46,28 +41,15 @@ import './SlideLock.css'; //const TRACKING_ID = 'UA-209450870-5'; // YOUR_OWN_TRACKING_ID //ReactGA.initialize(TRACKING_ID); -const SlideLock: React.FC = ({ - connectUserData, - setIsSplashPage -}) => { - const dispatch = useDispatch(); +const SlideLock: FC = ({ setIsSplashPage }) => { + const dispatch = useAppDispatch(); const [soldCopies, setSoldCopies] = useState(0); - const primaryColor = useSelector( - (store) => store.colorStore.primaryColor - ); - const { loggedIn } = useSelector( - (store) => store.userStore - ); - const seo = useSelector((store) => store.seoStore); - const { currentChain, minterInstance } = useSelector< - RootState, - ContractsInitialType - >((store) => store.contractStore); + const seo = useAppSelector((store) => store.seo); const carousel_match = window.matchMedia('(min-width: 900px)'); const [carousel, setCarousel] = useState(carousel_match.matches); useEffect(() => { - dispatch(setInfoSEO(InitialState)); + dispatch(setSEOInfo()); //eslint-disable-next-line }, []); @@ -81,26 +63,6 @@ const SlideLock: React.FC = ({ ); }, [carousel_match.matches]); - const getAllProduct = useCallback(async () => { - if (loggedIn && minterInstance && splashData.purchaseButton?.offerIndex) { - if (currentChain === splashData.purchaseButton?.requiredBlockchain) { - setSoldCopies( - ( - await minterInstance.getOfferRangeInfo( - ...(splashData.purchaseButton?.offerIndex || []) - ) - ).tokensAllowed.toString() - ); - } else { - setSoldCopies(0); /*it was empty but I put 0*/ - } - } - }, [setSoldCopies, loggedIn, currentChain, minterInstance]); - - useEffect(() => { - getAllProduct(); - }, [getAllProduct]); - useEffect(() => { setIsSplashPage?.(true); }, [setIsSplashPage]); @@ -113,7 +75,7 @@ const SlideLock: React.FC = ({
    - + {/* = ({
    @@ -149,10 +110,7 @@ const SlideLock: React.FC = ({ colorHeadSecond={'#57B69C'} teamArray={teamSlideLockArray} /> - +
    ); diff --git a/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardBlockWrapper/StyledSplashPageCardWrapper.ts b/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardBlockWrapper/StyledSplashPageCardWrapper.ts index 7d1a1c261..9fd609ab0 100644 --- a/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardBlockWrapper/StyledSplashPageCardWrapper.ts +++ b/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardBlockWrapper/StyledSplashPageCardWrapper.ts @@ -1,8 +1,11 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; import { TStyledSplashPageCardWrapper } from '../../splashConfig.types'; -export const StyledSplashPageCardWrapper = styled.div` +export const StyledSplashPageCardWrapper = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` display: flex; justify-content: space-between; align-items: center; diff --git a/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardButtonWrapper/StyledSplashCardButtonsWrapper.ts b/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardButtonWrapper/StyledSplashCardButtonsWrapper.ts index ee3f14339..cce162d23 100644 --- a/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardButtonWrapper/StyledSplashCardButtonsWrapper.ts +++ b/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardButtonWrapper/StyledSplashCardButtonsWrapper.ts @@ -1,8 +1,11 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; import { TStyledSplashCardButtonsWrapper } from '../../splashConfig.types'; -export const StyledSplashCardButtonsWrapper = styled.div` +export const StyledSplashCardButtonsWrapper = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` display: flex; flex-direction: ${({ flexDirection }) => flexDirection || 'row'}; flex-wrap: ${({ flexWrap }) => flexWrap || 'nowrap'}; diff --git a/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardImage/StyledSplashCardImage.ts b/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardImage/StyledSplashCardImage.ts index f463c9aa0..a8c3f7e60 100644 --- a/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardImage/StyledSplashCardImage.ts +++ b/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardImage/StyledSplashCardImage.ts @@ -1,8 +1,11 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; import { TStyledSplashCardImage } from '../../splashConfig.types'; -export const StyledSplashCardImage = styled.img` +export const StyledSplashCardImage = styled.img.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` width: 100%; height: auto; min-width: 400px; diff --git a/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardInfoBlock/StyledSplashCardInfoBlock.ts b/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardInfoBlock/StyledSplashCardInfoBlock.ts index c45f9cb1d..399fc4066 100644 --- a/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardInfoBlock/StyledSplashCardInfoBlock.ts +++ b/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardInfoBlock/StyledSplashCardInfoBlock.ts @@ -1,8 +1,11 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; import { TStyledSplashCardInfoBlock } from '../../splashConfig.types'; -export const StyledSplashCardInfoBlock = styled.div` +export const StyledSplashCardInfoBlock = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` display: flex; flex-direction: column; align-items: flex-start; diff --git a/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardText/StyledSplashCardText.ts b/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardText/StyledSplashCardText.ts index c0e025a36..0845b8de3 100644 --- a/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardText/StyledSplashCardText.ts +++ b/rair-front/src/components/SplashPage/SplashPageConfig/CardBlock/CardText/StyledSplashCardText.ts @@ -1,8 +1,11 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; import { TStyledSplashCardText } from '../../splashConfig.types'; -export const StyledSplashCardText = styled.div` +export const StyledSplashCardText = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` color: ${({ color }) => color}; font-size: ${({ fontSize }) => fontSize}; font-weight: ${({ fontWeight }) => fontWeight}; diff --git a/rair-front/src/components/SplashPage/SplashPageConfig/CardParagraphText/styled/CardParagraghText.styled.tsx b/rair-front/src/components/SplashPage/SplashPageConfig/CardParagraphText/styled/CardParagraghText.styled.tsx index 68465c062..b3c7a5f4d 100644 --- a/rair-front/src/components/SplashPage/SplashPageConfig/CardParagraphText/styled/CardParagraghText.styled.tsx +++ b/rair-front/src/components/SplashPage/SplashPageConfig/CardParagraphText/styled/CardParagraghText.styled.tsx @@ -1,3 +1,4 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; import { ICardParagraghWrapperStyled } from '../types/CardParagragh.types'; @@ -8,7 +9,9 @@ export const CardParagraghWrapper = styled.div` white-space: normal; `; -export const CardParagrashTitle = styled.h2` +export const CardParagrashTitle = styled.h2.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` font-family: ${(props) => props.fontFamily && props.fontFamily}; font-size: 42px; text-align: ${(props) => props.fontAlign && props.fontAlign}; diff --git a/rair-front/src/components/SplashPage/SplashPageConfig/VideoBlock/UnlockableVideosWrapper/StyledVideoComponents.ts b/rair-front/src/components/SplashPage/SplashPageConfig/VideoBlock/UnlockableVideosWrapper/StyledVideoComponents.ts index a975407f6..a2b0e6fdc 100644 --- a/rair-front/src/components/SplashPage/SplashPageConfig/VideoBlock/UnlockableVideosWrapper/StyledVideoComponents.ts +++ b/rair-front/src/components/SplashPage/SplashPageConfig/VideoBlock/UnlockableVideosWrapper/StyledVideoComponents.ts @@ -1,13 +1,16 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; import { TStyledUnlockableVideosWrapper } from '../../splashConfig.types'; -export const StyledUnlockableVideosWrapper = styled.div` +export const StyledUnlockableVideosWrapper = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` width: 100%; border-radius: 16px; height: 475px; - background-color: ${({ primaryColor }) => - primaryColor === 'rhyno' ? 'var(--rhyno-40)' : '#383637'}; + background-color: ${({ isDarkMode }) => + !isDarkMode ? 'var(--rhyno-40)' : '#383637'}; @media screen and (max-width: 844px) { height: auto; diff --git a/rair-front/src/components/SplashPage/SplashPageConfig/VideoBlock/UnlockableVideosWrapper/UnlockableVideosWrapper.tsx b/rair-front/src/components/SplashPage/SplashPageConfig/VideoBlock/UnlockableVideosWrapper/UnlockableVideosWrapper.tsx index b301a17f0..5114b3c3a 100644 --- a/rair-front/src/components/SplashPage/SplashPageConfig/VideoBlock/UnlockableVideosWrapper/UnlockableVideosWrapper.tsx +++ b/rair-front/src/components/SplashPage/SplashPageConfig/VideoBlock/UnlockableVideosWrapper/UnlockableVideosWrapper.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { StyledUnlockableVideosWrapper } from './StyledVideoComponents'; +import { useAppSelector } from '../../../../../hooks/useReduxHooks'; import UnlockableVideosSingleTokenPage from '../../../../MockUpPage/NftList/NftData/UnlockableVideosSingleTokenPage'; import { TUnlockableVideosWrapper } from '../../splashConfig.types'; @@ -11,11 +12,11 @@ const UnlockableVideosWrapper: React.FC = ({ setSelectVideo, handlePlayerClick, openVideoplayer, - setOpenVideoPlayer, - primaryColor + setOpenVideoPlayer }) => { + const { isDarkMode } = useAppSelector((store) => store.colors); return ( - + = ({ openVideoplayer={openVideoplayer} setOpenVideoPlayer={setOpenVideoPlayer} handlePlayerClick={handlePlayerClick} - primaryColor={primaryColor} /> ); diff --git a/rair-front/src/components/SplashPage/SplashPageConfig/splashConfig.types.ts b/rair-front/src/components/SplashPage/SplashPageConfig/splashConfig.types.ts index 795152d6e..d2c84f0a5 100644 --- a/rair-front/src/components/SplashPage/SplashPageConfig/splashConfig.types.ts +++ b/rair-front/src/components/SplashPage/SplashPageConfig/splashConfig.types.ts @@ -161,7 +161,7 @@ export type TSplashVideoWrapper = { export type TUnlockableVideosWrapper = TUnlockableVideosSingleTokenPage; export type TStyledUnlockableVideosWrapper = { - primaryColor: string; + isDarkMode: boolean; }; export type TSplashVideoText = { diff --git a/rair-front/src/components/SplashPage/SplashPageTemplate/ModalHelp.tsx b/rair-front/src/components/SplashPage/SplashPageTemplate/ModalHelp.tsx index 580ab5d5f..9ba7e8438 100644 --- a/rair-front/src/components/SplashPage/SplashPageTemplate/ModalHelp.tsx +++ b/rair-front/src/components/SplashPage/SplashPageTemplate/ModalHelp.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import { useSelector } from 'react-redux'; import { faChevronDown, faChevronUp, @@ -7,7 +6,7 @@ import { } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { RootState } from '../../../ducks'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; import { IModalHelp } from '../splashPage.types'; const ModalHelp: React.FC = ({ @@ -18,9 +17,7 @@ const ModalHelp: React.FC = ({ backgroundColor, templateOverride }) => { - const primaryColor = useSelector( - (store) => store.colorStore.primaryColor - ); + const { primaryColor } = useAppSelector((store) => store.colors); const dappUrl = window.location.host; const metamaskAppDeepLink = 'https://metamask.app.link/dapp/' + dappUrl; diff --git a/rair-front/src/components/SplashPage/SplashPageTemplate/VideoPlayer/ShowVideoToLoggedInUsers.tsx b/rair-front/src/components/SplashPage/SplashPageTemplate/VideoPlayer/ShowVideoToLoggedInUsers.tsx index f33c59d36..9616bb588 100644 --- a/rair-front/src/components/SplashPage/SplashPageTemplate/VideoPlayer/ShowVideoToLoggedInUsers.tsx +++ b/rair-front/src/components/SplashPage/SplashPageTemplate/VideoPlayer/ShowVideoToLoggedInUsers.tsx @@ -1,13 +1,12 @@ -import React from 'react'; import { useCallback, useState } from 'react'; import Modal from 'react-modal'; -import { Provider, useSelector, useStore } from 'react-redux'; +import { Provider, useStore } from 'react-redux'; import VideoPlayerBySignature from './VideoPlayerBySignature '; -import { RootState } from '../../../../ducks'; -import { ColorStoreType } from '../../../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../../../hooks/useReduxHooks'; import useSwal from '../../../../hooks/useSwal'; +import { CustomModalStyle } from '../../../../types/commonTypes'; import NftVideoplayer from '../../../MockUpPage/NftList/NftData/NftVideoplayer/NftVideoplayer'; import StandaloneVideoPlayer from '../../../video/videoPlayerGenerall'; import { playImagesColored } from '../../images/greyMan/grayMan'; @@ -15,7 +14,7 @@ import { IShowVideoToLoggedInUsers } from '../../splashPage.types'; import './VideoPlayer.css'; -const customStylesForVideo = { +const customStylesForVideo: CustomModalStyle = { overlay: { zIndex: '5' }, @@ -65,30 +64,13 @@ const ShowVideoToLoggedInUsers: React.FC = ({ const store = useStore(); const reactSwal = useSwal(); - const { primaryColor, textColor } = useSelector( - (store) => store.colorStore - ); + const { primaryColor, textColor } = useAppSelector((store) => store.colors); return ( <> {demo ? ( <>
    reactSwal.fire({ - // title: videoTitle, - // html: - // - // , - // width: '90vw', - // height: '90vh', - // customClass: { - // popup: `bg-${primaryColor}`, - // title: `text-${textColor}`, - // }, - // showConfirmButton: false - // })} className="video-module-background" style={{ backgroundImage: 'url(' + backgroundImage + ')' }}>
    diff --git a/rair-front/src/components/SplashPage/SplashPageTemplate/VideoTiles/VideoTilesItem.tsx b/rair-front/src/components/SplashPage/SplashPageTemplate/VideoTiles/VideoTilesItem.tsx index 66c226ac3..a87a3d1db 100644 --- a/rair-front/src/components/SplashPage/SplashPageTemplate/VideoTiles/VideoTilesItem.tsx +++ b/rair-front/src/components/SplashPage/SplashPageTemplate/VideoTiles/VideoTilesItem.tsx @@ -1,18 +1,18 @@ import { useCallback, useState } from 'react'; import Modal from 'react-modal'; -import { Provider, useSelector, useStore } from 'react-redux'; +import { Provider, useStore } from 'react-redux'; -import { RootState } from '../../../../ducks'; -import { ColorStoreType } from '../../../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../../../hooks/useReduxHooks'; import useSwal from '../../../../hooks/useSwal'; import { metaMaskIcon } from '../../../../images'; +import { CustomModalStyle } from '../../../../types/commonTypes'; import { ImageLazy } from '../../../MockUpPage/ImageLazy/ImageLazy'; import StandaloneVideoPlayer from '../../../video/videoPlayerGenerall'; import VideoPlayerBySignature from '../VideoPlayer/VideoPlayerBySignature '; import '../VideoPlayer/VideoPlayer.css'; -const customStylesForVideo = { +const customStylesForVideo: CustomModalStyle = { overlay: { zIndex: '5' }, @@ -80,9 +80,7 @@ const VideoTilesItem = ({ setVideoIsOpen(false); } - const { primaryColor, textColor } = useSelector( - (store) => store.colorStore - ); + const { primaryColor, textColor } = useAppSelector((store) => store.colors); return ( <> diff --git a/rair-front/src/components/SplashPage/SplashPageTemplate/VideoTiles/VideosTilesTest.tsx b/rair-front/src/components/SplashPage/SplashPageTemplate/VideoTiles/VideosTilesTest.tsx index 7e03a6b7b..7174659be 100644 --- a/rair-front/src/components/SplashPage/SplashPageTemplate/VideoTiles/VideosTilesTest.tsx +++ b/rair-front/src/components/SplashPage/SplashPageTemplate/VideoTiles/VideosTilesTest.tsx @@ -1,12 +1,13 @@ -//@ts-nocheck //test page for video tiles -import { useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { FC, useEffect, useState } from 'react'; import axios from 'axios'; -import { setInfoSEO } from '../../../../ducks/seo/actions'; -import { InitialState } from '../../../../ducks/seo/reducers'; -import { TInfoSeo } from '../../../../ducks/seo/seo.types'; +import { + useAppDispatch, + useAppSelector +} from '../../../../hooks/useReduxHooks'; +import { setSEOInfo } from '../../../../redux/seoSlice'; +import { SplashPageProps } from '../../../../types/commonTypes'; import VideoPlayerView from '../../../MockUpPage/NftList/NftData/UnlockablesPage/VideoPlayerView'; import MetaTags from '../../../SeoTags/MetaTags'; import { NYCVideoBackground } from '../../images/NFTNYC/nftnyc'; @@ -62,10 +63,10 @@ const testContract = { // } // ] -const VideoTilesTest = ({ setIsSplashPage }) => { - const dispatch = useDispatch(); - const seo = useSelector((store) => store.seoStore); - const { primaryColor } = useSelector((store) => store.colorStore); +const VideoTilesTest: FC = ({ setIsSplashPage }) => { + const dispatch = useAppDispatch(); + const seo = useAppSelector((store) => store.seo); + const { primaryColor } = useAppSelector((store) => store.colors); /* UTILITIES FOR VIDEO PLAYERS */ const [productsFromOffer, setProductsFromOffer] = useState([]); @@ -73,7 +74,7 @@ const VideoTilesTest = ({ setIsSplashPage }) => { const [mainVideo, setMainVideo] = useState(productsFromOffer[0]); const getProductsFromOffer = async () => { - const response = await axios.get( + const response = await axios.get( `/api/nft/network/${testContract.requiredBlockchain}/${testContract.contractAddress}/${testContract.offerIndex[0]}/files` ); setProductsFromOffer(response.data.files); @@ -82,7 +83,7 @@ const VideoTilesTest = ({ setIsSplashPage }) => { }; useEffect(() => { - dispatch(setInfoSEO(InitialState)); + dispatch(setSEOInfo()); //eslint-disable-next-line }, []); diff --git a/rair-front/src/components/SplashPage/TeamMeet/TeamComponentCommon.tsx b/rair-front/src/components/SplashPage/TeamMeet/TeamComponentCommon.tsx index cdf6c5de4..08bee225f 100644 --- a/rair-front/src/components/SplashPage/TeamMeet/TeamComponentCommon.tsx +++ b/rair-front/src/components/SplashPage/TeamMeet/TeamComponentCommon.tsx @@ -1,9 +1,8 @@ import React from 'react'; -import { useSelector } from 'react-redux'; import Teammate from './Teammate'; -import { RootState } from '../../../ducks'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; import { ITeamMeetComponentCommon } from '../splashPage.types'; const TeamMeetComponentCommon: React.FC = ({ @@ -11,9 +10,7 @@ const TeamMeetComponentCommon: React.FC = ({ className, arraySplash }) => { - const primaryColor = useSelector( - (state) => state.colorStore.primaryColor - ); + const { primaryColor } = useAppSelector((state) => state.colors); return (
    {teamArray && diff --git a/rair-front/src/components/SplashPage/TokenLeft/TokenLeft.tsx b/rair-front/src/components/SplashPage/TokenLeft/TokenLeft.tsx index 246c40ff0..361e00b4b 100644 --- a/rair-front/src/components/SplashPage/TokenLeft/TokenLeft.tsx +++ b/rair-front/src/components/SplashPage/TokenLeft/TokenLeft.tsx @@ -1,18 +1,16 @@ -import React, { useEffect, useState } from 'react'; +import { FC, useEffect, useState } from 'react'; import Box from '@mui/material/Box'; import CircularProgress from '@mui/material/CircularProgress'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; import MailchimpComponent from '../NipseyRelease/MailchimpComponent'; import { ITokenLeft } from '../splashPage.types'; -const TokenLeft: React.FC = ({ - primaryColor, - DiscordIcon, - copies, - soldCopies -}) => { +const TokenLeft: FC = ({ DiscordIcon, copies, soldCopies }) => { const [percentTokens, setPersentTokens] = useState(0); + const { isDarkMode } = useAppSelector((store) => store.colors); + const leftTokensNumber = Number(copies) - Number(soldCopies); const wholeTokens = Number(copies); @@ -38,11 +36,7 @@ const TokenLeft: React.FC = ({
    NFTs remaining
    @@ -100,7 +94,7 @@ const TokenLeft: React.FC = ({

    October 2013, Los Angeles, CA. Nipsey unveils the Crenshaw EP with a groundbreaking release strategy: Sell 1000 copies for $100 each. @@ -108,14 +102,14 @@ const TokenLeft: React.FC = ({

    Within 24 hours, all 1000 copies are spoken for.

    In collaboration with award-winning producer Mr. Lee, the Asghedom estate, Southwest Digital Distribution, and RAIR Technologies , the diff --git a/rair-front/src/components/SplashPage/TokenLeft/TokenLeftGreyman.tsx b/rair-front/src/components/SplashPage/TokenLeft/TokenLeftGreyman.tsx index 51144f675..ede58d5af 100644 --- a/rair-front/src/components/SplashPage/TokenLeft/TokenLeftGreyman.tsx +++ b/rair-front/src/components/SplashPage/TokenLeft/TokenLeftGreyman.tsx @@ -1,19 +1,18 @@ -import React, { useEffect, useState } from 'react'; +import { FC, useEffect, useState } from 'react'; import Box from '@mui/material/Box'; import CircularProgress from '@mui/material/CircularProgress'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; import { ITokenLeftGreyman } from '../splashPage.types'; -const TokenLeftGreyman: React.FC = ({ - primaryColor, - soldCopies, - copies -}) => { +const TokenLeftGreyman: FC = ({ soldCopies, copies }) => { // in props was Metamask const [percentTokens, setPersentTokens] = useState(0); const [showMore, setShowMore] = useState(false); const [fontSize, setFontSize] = useState(''); + const { primaryColor } = useAppSelector((store) => store.colors); + const wholeTokens = Number(copies); const leftTokensNumber = Number(soldCopies); diff --git a/rair-front/src/components/SplashPage/TokenLeft/TokenLeftTemplate.tsx b/rair-front/src/components/SplashPage/TokenLeft/TokenLeftTemplate.tsx index 49df1d85a..033f0279c 100644 --- a/rair-front/src/components/SplashPage/TokenLeft/TokenLeftTemplate.tsx +++ b/rair-front/src/components/SplashPage/TokenLeft/TokenLeftTemplate.tsx @@ -1,16 +1,13 @@ import React, { useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import Box from '@mui/material/Box'; import CircularProgress from '@mui/material/CircularProgress'; -import { RootState } from '../../../ducks'; -import { TUsersInitialState } from '../../../ducks/users/users.types'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; import { ITokenLeftTemplate } from '../splashPage.types'; import './TokenLeftTemplate.css'; const TokenLeftTemplate: React.FC = ({ - primaryColor, soldCopies, counterData, ipftButton, @@ -29,15 +26,15 @@ const TokenLeftTemplate: React.FC = ({ nftCount } = counterData || {}; + const { isDarkMode } = useAppSelector((store) => store.colors); + const [percentTokens, setPersentTokens] = useState(0); const [fontSize, setFontSize] = useState(''); const wholeTokens = nftCount; const leftTokensNumber = soldCopies; - const { loggedIn } = useSelector( - (store) => store.userStore - ); + const { isLoggedIn } = useAppSelector((store) => store.user); useEffect(() => { if (wholeTokens && leftTokensNumber <= wholeTokens) { @@ -70,7 +67,7 @@ const TokenLeftTemplate: React.FC = ({ return (

    - {(counterOverride || (soldCopies !== undefined && loggedIn)) && ( + {(counterOverride || (soldCopies !== undefined && isLoggedIn)) && (
    = ({ className="progress-tokens" style={{ background: `${ - primaryColor === 'rhyno' + !isDarkMode ? 'rgba(34, 32, 33, 0.4)' : 'rgba(34, 32, 33, 0.6)' }` @@ -147,7 +144,7 @@ const TokenLeftTemplate: React.FC = ({ className="property" style={{ background: `${ - primaryColor === 'rhyno' ? '#cccccc' : 'none' + !isDarkMode ? '#cccccc' : 'none' }` }}> = ({

    {item}

    diff --git a/rair-front/src/components/SplashPage/UkraineGlitchSplashPage/UkraineSplashPage.tsx b/rair-front/src/components/SplashPage/UkraineGlitchSplashPage/UkraineSplashPage.tsx index ef67f5fff..046e10ad9 100644 --- a/rair-front/src/components/SplashPage/UkraineGlitchSplashPage/UkraineSplashPage.tsx +++ b/rair-front/src/components/SplashPage/UkraineGlitchSplashPage/UkraineSplashPage.tsx @@ -1,14 +1,11 @@ -import React, { useCallback, useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { FC, useEffect, useState } from 'react'; import { teamUkraineArray } from './AboutUsTeam'; -import { RootState } from '../../../ducks'; -import { setRealChain } from '../../../ducks/contracts/actions'; -import { ContractsInitialType } from '../../../ducks/contracts/contracts.types'; -import { setInfoSEO } from '../../../ducks/seo/actions'; -import { TInfoSeo } from '../../../ducks/seo/seo.types'; -import { TUsersInitialState } from '../../../ducks/users/users.types'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; +import { setSEOInfo } from '../../../redux/seoSlice'; +import { setRequestedChain } from '../../../redux/web3Slice'; +import { SplashPageProps } from '../../../types/commonTypes'; // import NFTLA_Video from "../images/NFT-LA-RAIR-2021.mp4" import { splashData } from '../../../utils/infoSplashData/ukraineSplashPage'; /* importing images*/ @@ -22,7 +19,6 @@ import { videoBackground } from '../images/UkraineGlitch/urkaineGlitch'; import NotCommercialTemplate from '../NotCommercial/NotCommercialTemplate'; -import { ISplashPageProps } from '../splashPage.types'; import AuthorCard from '../SplashPageTemplate/AuthorCard/AuthorCard'; import ListExlusiveProduct from '../SplashPageTemplate/ListExlusiveProduct/ListExlusiveProduct'; import ModalHelp from '../SplashPageTemplate/ModalHelp'; @@ -47,32 +43,19 @@ import './UkraineSplash.css'; //const TRACKING_ID = 'UA-209450870-5'; // YOUR_OWN_TRACKING_ID //ReactGA.initialize(TRACKING_ID); -const UkraineSplashPage: React.FC = ({ - connectUserData, - setIsSplashPage -}) => { - const dispatch = useDispatch(); - const seo = useSelector((store) => store.seoStore); +const UkraineSplashPage: FC = ({ setIsSplashPage }) => { + const dispatch = useAppDispatch(); + const seo = useAppSelector((store) => store.seo); const [openCheckList, setOpenCheckList] = useState(false); const [soldCopies, setSoldCopies] = useState(0); - const primaryColor = useSelector( - (store) => store.colorStore.primaryColor - ); - const { currentChain, minterInstance } = useSelector< - RootState, - ContractsInitialType - >((store) => store.contractStore); const carousel_match = window.matchMedia('(min-width: 900px)'); const [carousel, setCarousel] = useState(carousel_match.matches); const [purchaseList, setPurshaseList] = useState(true); const ukraineglitchChainId = '0x1'; - const { loggedIn } = useSelector( - (store) => store.userStore - ); useEffect(() => { dispatch( - setInfoSEO({ + setSEOInfo({ title: 'Слава Україні!', ogTitle: 'Слава Україні!', twitterTitle: 'Слава Україні!', @@ -102,31 +85,8 @@ const UkraineSplashPage: React.FC = ({ window.addEventListener('resize', () => setCarousel(carousel_match.matches)); - const getAllProduct = useCallback(async () => { - if (loggedIn && minterInstance && splashData.purchaseButton?.offerIndex) { - if ( - currentChain === splashData.purchaseButton?.requiredBlockchain && - splashData.purchaseButton?.offerIndex - ) { - setSoldCopies( - ( - await minterInstance.getOfferRangeInfo( - ...splashData.purchaseButton.offerIndex - ) - ).tokensAllowed.toString() - ); - } else { - setSoldCopies(0); - } - } - }, [setSoldCopies, loggedIn, currentChain, minterInstance]); - useEffect(() => { - getAllProduct(); - }, [getAllProduct]); - - useEffect(() => { - dispatch(setRealChain(ukraineglitchChainId)); + dispatch(setRequestedChain(ukraineglitchChainId)); //eslint-disable-next-line }, []); @@ -148,7 +108,7 @@ const UkraineSplashPage: React.FC = ({ lightTheme: 'rgb(3, 91, 188)' }} /> - + {/* = ({ = ({ colorHeadSecond={'#035BBC'} teamArray={teamUkraineArray} /> - +
    ); diff --git a/rair-front/src/components/SplashPage/UnlockVideos/UnlockVideoItem.tsx b/rair-front/src/components/SplashPage/UnlockVideos/UnlockVideoItem.tsx index d8bc5ab74..e84e87a17 100644 --- a/rair-front/src/components/SplashPage/UnlockVideos/UnlockVideoItem.tsx +++ b/rair-front/src/components/SplashPage/UnlockVideos/UnlockVideoItem.tsx @@ -1,21 +1,22 @@ -import React from 'react'; +import { FC } from 'react'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; import { metaMaskIcon } from '../../../images'; import { ImageLazy } from '../../MockUpPage/ImageLazy/ImageLazy'; import { IUnlockVideoItem } from '../splashPage.types'; -const UnlockVideoItem: React.FC = ({ +const UnlockVideoItem: FC = ({ nameVideo, timeVideo, - unlockableVideo, - primaryColor + unlockableVideo }) => { + const { isDarkMode } = useAppSelector((store) => store.colors); return (
    @@ -31,7 +32,7 @@ const UnlockVideoItem: React.FC = ({

    {nameVideo}

    @@ -39,7 +40,7 @@ const UnlockVideoItem: React.FC = ({

    {timeVideo}

    diff --git a/rair-front/src/components/SplashPage/UnlockVideos/UnlockVideos.tsx b/rair-front/src/components/SplashPage/UnlockVideos/UnlockVideos.tsx index 848fc5604..eb67f2c29 100644 --- a/rair-front/src/components/SplashPage/UnlockVideos/UnlockVideos.tsx +++ b/rair-front/src/components/SplashPage/UnlockVideos/UnlockVideos.tsx @@ -55,10 +55,7 @@ const videoArr: TVideoArrType[] = [ } ]; -const UnlockVideos: React.FC = ({ - unlockableVideo, - primaryColor -}) => { +const UnlockVideos: React.FC = ({ unlockableVideo }) => { return (
    @@ -74,7 +71,6 @@ const UnlockVideos: React.FC = ({ unlockableVideo={unlockableVideo} nameVideo={video.unlockVideoName} timeVideo={video.timeVideo} - primaryColor={primaryColor} /> ); })} diff --git a/rair-front/src/components/SplashPage/VaporverseSplash/VaporverseSplashPage.tsx b/rair-front/src/components/SplashPage/VaporverseSplash/VaporverseSplashPage.tsx index fe9093060..3730af255 100644 --- a/rair-front/src/components/SplashPage/VaporverseSplash/VaporverseSplashPage.tsx +++ b/rair-front/src/components/SplashPage/VaporverseSplash/VaporverseSplashPage.tsx @@ -1,13 +1,13 @@ -import { useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { FC, useEffect, useState } from 'react'; import { v1 } from 'uuid'; import { teamVaporVerseArray } from './AboutUsTeam'; -import { RootState } from '../../../ducks'; -import { setRealChain } from '../../../ducks/contracts/actions'; -import { setInfoSEO } from '../../../ducks/seo/actions'; -import { TInfoSeo } from '../../../ducks/seo/seo.types'; +import useConnectUser from '../../../hooks/useConnectUser'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; +import { setSEOInfo } from '../../../redux/seoSlice'; +import { setRequestedChain } from '../../../redux/web3Slice'; +import { SplashPageProps } from '../../../types/commonTypes'; import { splashData } from '../../../utils/infoSplashData/vapoverseSplashPage'; import { ImageLazy } from '../../MockUpPage/ImageLazy/ImageLazy'; import MetaTags from '../../SeoTags/MetaTags'; @@ -26,7 +26,7 @@ import { } from '../images/vaporverse/vaporverse'; import NotCommercialTemplate from '../NotCommercial/NotCommercialTemplate'; import PurchaseChecklist from '../PurchaseChecklist/PurchaseChecklist'; -import { IInfoBlock, IVaporverseSplashPage } from '../splashPage.types'; +import { IInfoBlock } from '../splashPage.types'; import AuthorCard from '../SplashPageTemplate/AuthorCard/AuthorCard'; import ModalHelp from '../SplashPageTemplate/ModalHelp'; import NFTImages from '../SplashPageTemplate/NFTImages/NFTImages'; @@ -56,16 +56,11 @@ const InfoBlock: React.FC = ({ ); }; -const VaporverseSplashPage: React.FC = ({ - connectUserData, - setIsSplashPage -}) => { - const dispatch = useDispatch(); - const seo = useSelector((store) => store.seoStore); +const VaporverseSplashPage: FC = ({ setIsSplashPage }) => { + const dispatch = useAppDispatch(); + const seo = useAppSelector((store) => store.seo); const [openCheckList, setOpenCheckList] = useState(false); - const primaryColor = useSelector( - (store) => store.colorStore.primaryColor - ); + const { connectUserData } = useConnectUser(); const carousel_match = window.matchMedia('(min-width: 630px)'); const [carousel, setCarousel] = useState(carousel_match.matches); const [purchaseList, setPurchaseList] = useState(true); @@ -77,7 +72,7 @@ const VaporverseSplashPage: React.FC = ({ useEffect(() => { dispatch( - setInfoSEO({ + setSEOInfo({ title: 'Vaporverse', ogTitle: 'Vaporverse', twitterTitle: 'Vaporverse', @@ -111,21 +106,21 @@ const VaporverseSplashPage: React.FC = ({ // const getAllProduct = useCallback(async () => { // if (loggedIn) { - // if (currentChain === splashData.purchaseButton.requiredBlockchain) { + // if (connectedChain === splashData.purchaseButton.requiredBlockchain) { // setSoldCopies((await minterInstance.getOfferRangeInfo(...splashData.purchaseButton.offerIndex)).tokensAllowed.toString()); // } else { // setSoldCopies(); // } // } - // }, [setSoldCopies, loggedIn, currentChain, minterInstance]); + // }, [setSoldCopies, loggedIn, connectedChain, minterInstance]); // useEffect(() => { // getAllProduct() // }, [getAllProduct]) useEffect(() => { - dispatch(setRealChain(chainId)); + dispatch(setRequestedChain(chainId)); }, [dispatch]); useEffect(() => { @@ -281,10 +276,7 @@ const VaporverseSplashPage: React.FC = ({ titleHeadFirst={'mak0r'} teamArray={teamVaporVerseArray} /> - +
    ); diff --git a/rair-front/src/components/SplashPage/splashPage.types.ts b/rair-front/src/components/SplashPage/splashPage.types.ts index 0b6ef7d77..2a0051511 100644 --- a/rair-front/src/components/SplashPage/splashPage.types.ts +++ b/rair-front/src/components/SplashPage/splashPage.types.ts @@ -1,16 +1,11 @@ import React from 'react'; import { IconDefinition } from '@fortawesome/free-solid-svg-icons'; +import { Hex } from 'viem'; -import { TFileType } from '../../axios.responseTypes'; +import { CatalogVideoItem } from '../../types/commonTypes'; export interface INumberedCircle { index: number; - primaryColor: string; -} - -export interface ISplashPageProps { - connectUserData: () => Promise; - setIsSplashPage?: (isSplashPage: boolean) => void; } export type TSplashPageIsActive = { @@ -69,7 +64,7 @@ export type TCarouselDataType = { }; export type TSplashPageVideoData = { - video: string | null; + video?: string; videoTitle?: string; videoModuleDescription?: string | null; videoModuleTitle?: string; @@ -94,15 +89,15 @@ export type TExclusiveNFtType = { }; export type TParamsMarketplaceDemo = { - blockchain: BlockchainType | undefined; + blockchain: Hex | undefined; contract: string; product: string; }; export type TPurchaseButtonType = { - contractAddress?: string; + contractAddress?: Hex; buttonLabel?: string; - requiredBlockchain: BlockchainType | undefined; + requiredBlockchain?: Hex; buttonComponent?: React.ElementType; presaleMessage?: string; customWrapperClassName?: string; @@ -175,7 +170,6 @@ export type TSplashDataType = { export interface IAuthorCard { splashData: TSplashDataType; - connectUserData?: () => Promise; toggleCheckList?: () => void; whatSplashPage?: TWhatSplashPageType; customButtonBlock?: JSX.Element; @@ -235,7 +229,7 @@ export interface ICountdown { } export interface IVideoPlayerModule { - backgroundImage: string; + backgroundImage?: string; videoData?: TSplashPageVideoData; selectVideo?: any /*type of video is unclear yet*/; } @@ -259,7 +253,7 @@ export interface ICarouselListItem { } export interface IShowVideoToLoggedInUsers { - backgroundImage: string; + backgroundImage?: string; video?: string | null; videoTitle?: string; baseURL?: string; @@ -268,12 +262,7 @@ export interface IShowVideoToLoggedInUsers { selectVideo: any /*type of video is unclear yet*/; } -export interface INotCommercial { - primaryColor: string; -} - export interface ITokenLeftGreyman { - primaryColor: string; soldCopies?: string; copies?: string; } @@ -339,12 +328,7 @@ export interface ITeammateDesc { arraySplash?: TArraySplashType; } -export interface INotCommercialGeneric { - primaryColor: string; -} - export interface ITokenLeft { - primaryColor: string; DiscordIcon: string; copies?: number; soldCopies?: number; @@ -352,7 +336,6 @@ export interface ITokenLeft { export interface IUnlockVideos { unlockableVideo: string; - primaryColor: string; } export type TVideoArrType = { @@ -366,7 +349,6 @@ export interface IUnlockVideoItem { nameVideo: string; timeVideo: string; unlockableVideo: string; - primaryColor: string; } export interface IExclusiveNft { @@ -386,7 +368,6 @@ export interface INipseyRelease { } export interface INotCommercialTemplate { - primaryColor: string; NFTName: string | undefined; } @@ -410,11 +391,6 @@ export interface IInfoBlock { children?: JSX.Element; } -export interface IVaporverseSplashPage { - connectUserData: () => Promise; - setIsSplashPage: (isSplashPage: boolean) => void; -} - export interface INFTImages { Nft_1: string; Nft_2: string; @@ -429,7 +405,6 @@ export interface INFTImages { } export interface ITokenLeftTemplate { - primaryColor: string; soldCopies: number; counterData?: TCounterData; ipftButton?: any; //type is unclear @@ -438,8 +413,8 @@ export interface ITokenLeftTemplate { } export type TMainContractType = { - contractAddress: string; - requiredBlockchain: BlockchainType | undefined; + contractAddress: Hex; + requiredBlockchain: Hex; offerIndex: string[]; }; @@ -480,13 +455,12 @@ export interface IDonationGrid { } export type TUseGetProductsReturn = [ - TFileType[], - TFileType | undefined, + CatalogVideoItem[], + CatalogVideoItem | undefined, (selectVideo: any) => void ]; export interface INotCommercialTemplate2 { - primaryColor: string; NFTName: string; } diff --git a/rair-front/src/components/SplashPage/splashPageProductsHook.tsx b/rair-front/src/components/SplashPage/splashPageProductsHook.tsx index 1013248b9..3cf4c0c44 100644 --- a/rair-front/src/components/SplashPage/splashPageProductsHook.tsx +++ b/rair-front/src/components/SplashPage/splashPageProductsHook.tsx @@ -1,22 +1,21 @@ import { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import axios from 'axios'; import { TSplashDataType, TUseGetProductsReturn } from './splashPage.types'; -import { TFileType, TNftFilesResponse } from '../../axios.responseTypes'; -import { RootState } from '../../ducks'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; +import { TNftFilesResponse } from '../../axios.responseTypes'; +import { useAppSelector } from '../../hooks/useReduxHooks'; +import { CatalogVideoItem } from '../../types/commonTypes'; export const useGetProducts = ( splashData: TSplashDataType ): TUseGetProductsReturn => { - const [productsFromOffer, setProductsFromOffer] = useState([]); - const [selectVideo, setSelectVideo] = useState(); + const [productsFromOffer, setProductsFromOffer] = useState< + CatalogVideoItem[] + >([]); + const [selectVideo, setSelectVideo] = useState(); - const { currentUserAddress } = useSelector( - (store) => store.contractStore - ); + const { currentUserAddress } = useAppSelector((store) => store.web3); const getProductsFromOffer = useCallback(async () => { if (currentUserAddress) { diff --git a/rair-front/src/components/SplashPage/wallstreet80sclub/wallstreet80sclub.tsx b/rair-front/src/components/SplashPage/wallstreet80sclub/wallstreet80sclub.tsx index b9df6b59c..993299e59 100644 --- a/rair-front/src/components/SplashPage/wallstreet80sclub/wallstreet80sclub.tsx +++ b/rair-front/src/components/SplashPage/wallstreet80sclub/wallstreet80sclub.tsx @@ -1,15 +1,12 @@ -import { useCallback, useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { FC, useEffect, useState } from 'react'; import { teamWallstreetArray } from './AboutUsTeam'; import RairFavicon from '../../../components/MockUpPage/assets/rair_favicon.ico'; -import { RootState } from '../../../ducks'; -import { setRealChain } from '../../../ducks/contracts/actions'; -import { ContractsInitialType } from '../../../ducks/contracts/contracts.types'; -import { setInfoSEO } from '../../../ducks/seo/actions'; -import { TInfoSeo } from '../../../ducks/seo/seo.types'; -import { TUsersInitialState } from '../../../ducks/users/users.types'; +import { useAppDispatch, useAppSelector } from '../../../hooks/useReduxHooks'; +import { setSEOInfo } from '../../../redux/seoSlice'; +import { setRequestedChain } from '../../../redux/web3Slice'; +import { SplashPageProps } from '../../../types/commonTypes'; import { blockchain, splashData @@ -18,7 +15,6 @@ import VideoPlayerView from '../../MockUpPage/NftList/NftData/UnlockablesPage/Vi import MetaTags from '../../SeoTags/MetaTags'; import NotCommercialTemplate from '../NotCommercial/NotCommercialTemplate'; import ButtonHelp from '../PurchaseChecklist/ButtonHelp'; -import { ISplashPageProps } from '../splashPage.types'; import { useGetProducts } from '../splashPageProductsHook'; import AuthorCard from '../SplashPageTemplate/AuthorCard/AuthorCard'; import ListExlusiveProduct from '../SplashPageTemplate/ListExlusiveProduct/ListExlusiveProduct'; @@ -40,12 +36,11 @@ import './wallstreet80sclub.css'; //const TRACKING_ID = 'UA-209450870-5'; // YOUR_OWN_TRACKING_ID //ReactGA.initialize(TRACKING_ID); -const Wallstreet80sClubSplashPage: React.FC = ({ - connectUserData, +const Wallstreet80sClubSplashPage: FC = ({ setIsSplashPage }) => { - const dispatch = useDispatch(); - const seo = useSelector((store) => store.seoStore); + const dispatch = useAppDispatch(); + const seo = useAppSelector((store) => store.seo); /* UTILITIES FOR VIDEO PLAYER VIEW (placed this functionality into custom hook for reusability)*/ const [productsFromOffer, selectVideo, setSelectVideo] = useGetProducts(splashData); @@ -54,26 +49,16 @@ const Wallstreet80sClubSplashPage: React.FC = ({ const carousel_match = window.matchMedia('(min-width: 900px)'); const [carousel, setCarousel] = useState(carousel_match.matches); - const { loggedIn } = useSelector( - (store) => store.userStore - ); - /* UTILITIES FOR NFT PURCHASE */ - const [soldCopies, setSoldCopies] = useState(0); - const { currentChain, minterInstance } = useSelector< - RootState, - ContractsInitialType - >((store) => store.contractStore); + const [soldCopies] = useState(0); const [openCheckList, setOpenCheckList] = useState(false); const [purchaseList, setPurchaseList] = useState(true); - const primaryColor = useSelector( - (store) => store.colorStore.primaryColor - ); + const { primaryColor } = useAppSelector((store) => store.colors); useEffect(() => { dispatch( - setInfoSEO({ + setSEOInfo({ title: '#wallstreet80sclub', ogTitle: '#wallstreet80sclub', twitterTitle: '#wallstreet80sclub', @@ -108,7 +93,7 @@ const Wallstreet80sClubSplashPage: React.FC = ({ }, [carousel_match.matches]); useEffect(() => { - dispatch(setRealChain(blockchain)); + dispatch(setRequestedChain(blockchain)); //eslint-disable-next-line }, []); @@ -118,25 +103,6 @@ const Wallstreet80sClubSplashPage: React.FC = ({ const toggleCheckList = () => { setOpenCheckList((prev) => !prev); }; - const getAllProduct = useCallback(async () => { - if (loggedIn && minterInstance && splashData.purchaseButton?.offerIndex) { - if (currentChain === splashData.purchaseButton?.requiredBlockchain) { - setSoldCopies( - ( - await minterInstance.getOfferRangeInfo( - ...(splashData.purchaseButton.offerIndex || []) - ) - ).tokensAllowed.toString() - ); - } else { - setSoldCopies(0); - } - } - }, [setSoldCopies, loggedIn, currentChain, minterInstance]); - - useEffect(() => { - getAllProduct(); - }, [getAllProduct]); return (
    @@ -153,11 +119,10 @@ const Wallstreet80sClubSplashPage: React.FC = ({ lightTheme: 'rgb(3, 91, 188)' }} /> - + @@ -191,10 +156,7 @@ const Wallstreet80sClubSplashPage: React.FC = ({ titleHeadFirst="Founding Members" teamArray={teamWallstreetArray} /> - +
    ); diff --git a/rair-front/src/components/UserProfilePage/UserProfileCreated/UserProfileCreated.tsx b/rair-front/src/components/UserProfilePage/UserProfileCreated/UserProfileCreated.tsx index 77e1132e3..7af184d27 100644 --- a/rair-front/src/components/UserProfilePage/UserProfileCreated/UserProfileCreated.tsx +++ b/rair-front/src/components/UserProfilePage/UserProfileCreated/UserProfileCreated.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import { useState } from 'react'; import { NftItem } from './../../MockUpPage/NftList/NftItem'; @@ -7,43 +7,27 @@ const UserProfileCreated = ({ contractData, titleSearch }) => { const filteredContracts = contractData && - contractData.filter((el) => - el.name.toLowerCase().includes(titleSearch.toLowerCase()) + contractData.filter( + (el) => + el.product.name.toLowerCase().includes(titleSearch.toLowerCase()) && + el.product.cover !== 'none' ); return (
    {filteredContracts.length > 0 ? ( - filteredContracts.map((contractData, index) => { - if (contractData.cover !== 'none') { - return ( - String(p.price))} - blockchain={contractData.blockchain} - collectionName={contractData.name} - ownerCollectionUser={contractData.user} - index={index} - playing={playing} - setPlaying={setPlaying} - collectionIndexInContract={ - contractData.collectionIndexInContract - } - /> - ); - } else { - return null; - } + filteredContracts.map((item, index) => { + return ( + + ); }) ) : (
    diff --git a/rair-front/src/components/UserProfilePage/UserProfilePage.tsx b/rair-front/src/components/UserProfilePage/UserProfilePage.tsx index 6e70b1bc9..1dab91a8b 100644 --- a/rair-front/src/components/UserProfilePage/UserProfilePage.tsx +++ b/rair-front/src/components/UserProfilePage/UserProfilePage.tsx @@ -1,5 +1,4 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'; -import { useSelector } from 'react-redux'; import { NavLink, useParams } from 'react-router-dom'; import { Tab, TabList, TabPanel, Tabs } from 'react-tabs'; import { @@ -13,16 +12,16 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { Stack } from '@mui/material'; import { Breadcrumbs, Typography } from '@mui/material'; import axios from 'axios'; -import { constants, utils } from 'ethers'; -import Swal from 'sweetalert2'; +import { isAddress, ZeroAddress } from 'ethers'; +import { Hex } from 'viem'; -import { TContract, TUserResponse } from '../../axios.responseTypes'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; -import { UserType } from '../../ducks/users/users.types'; +import { TUserResponse } from '../../axios.responseTypes'; +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useSwal from '../../hooks/useSwal'; import useWindowDimensions from '../../hooks/useWindowDimensions'; import { VideoIcon } from '../../images'; +import { NftItemToken } from '../../types/commonTypes'; +import { User } from '../../types/databaseTypes'; import { rFetch } from '../../utils/rFetch'; import InputField from '../common/InputField'; import LoadingComponent from '../common/LoadingComponent'; @@ -31,7 +30,6 @@ import FilteringBlock from '../MockUpPage/FilteringBlock/FilteringBlock'; import { ImageLazy } from '../MockUpPage/ImageLazy/ImageLazy'; import CustomShareButton from '../MockUpPage/NftList/NftData/CustomShareButton'; import SharePopUp from '../MockUpPage/NftList/NftData/TitleCollection/SharePopUp/SharePopUp'; -import { TDiamondTokensType } from '../nft/nft.types'; import { PersonalProfileMyNftTab } from '../nft/PersonalProfile/PersonalProfileMyNftTab/PersonalProfileMyNftTab'; import { PersonalProfileMyVideoTab } from '../nft/PersonalProfile/PersonalProfileMyVideoTab/PersonalProfileMyVideoTab'; import { TSortChoice } from '../ResalePage/listOffers.types'; @@ -45,19 +43,14 @@ import './UserProfilePage.css'; const UserProfilePage: React.FC = () => { const { primaryColor, textColor, headerLogo, iconColor, primaryButtonColor } = - useSelector((store) => store.colorStore); + useAppSelector((store) => store.colors); const { userAddress } = useParams(); - const { currentUserAddress } = useSelector( - (store) => store.contractStore - ); + const { currentUserAddress } = useAppSelector((store) => store.web3); const [copyState, setCopyState] = useState(false); - const [userData, setUserData] = useState( - undefined - ); - const [, /*tokens*/ setTokens] = useState([]); + const [userData, setUserData] = useState(undefined); const [collectedTokens, setCollectedTokens] = useState< - TDiamondTokensType[] | null - >(null); + NftItemToken[] | undefined + >(undefined); const [createdContracts, setCreatedContracts] = useState([]); const [fileUpload, setFileUpload] = useState(null); const [loadingBg, setLoadingBg] = useState(false); @@ -76,6 +69,7 @@ const UserProfilePage: React.FC = () => { ); const [metadataFilter, setMetadataFilter] = useState(false); + const rSwal = useSwal(); const { width } = useWindowDimensions(); const handleClose = (value: number) => { @@ -89,34 +83,15 @@ const UserProfilePage: React.FC = () => { const getMyNft = useCallback( async (number, page) => { - if (userAddress && utils.isAddress(userAddress)) { + if (userAddress && isAddress(userAddress)) { setIsLoading(true); const response = await rFetch( `/api/nft/${userAddress}?itemsPerPage=${number}&pageNum=${page}&onResale=${onResale}` ); if (response.success) { - const tokenData: TDiamondTokensType[] = []; setTotalCount(response.totalCount); - for await (const token of response.result) { - if (!token.contract._id) { - return; - } - const contractData = await rFetch( - `/api/contracts/${token.contract._id}` - ); - tokenData.push({ - ...token, - ...contractData.contract._id - }); - } - - const newCollectedTokens = tokenData.filter( - (el) => el.isMinted === true - ); - - setTokens(tokenData); - setCollectedTokens(newCollectedTokens); + setCollectedTokens(response.result.filter((token) => token.isMinted)); setIsLoading(false); setIsResaleLoding(false); } @@ -143,35 +118,12 @@ const UserProfilePage: React.FC = () => { (el) => el.user === userAddress ); - const covers = contractsFiltered.map((item: TContract) => ({ - id: item._id, - productId: item.products?._id, - blockchain: item.blockchain, - collectionIndexInContract: item.products.collectionIndexInContract, - contract: item.contractAddress, - cover: item.products.cover, - title: item.title, - name: item.products.name, - user: item.user, - copiesProduct: item.products.copies, - offerData: item.products.offers?.map((elem) => ({ - price: elem.price, - offerName: elem.offerName, - offerIndex: elem.offerIndex, - productNumber: elem.product - })) - })); - - setCreatedContracts(covers); + setCreatedContracts(contractsFiltered); } }, [userAddress]); const getUserData = useCallback(async () => { - if ( - userAddress && - utils.isAddress(userAddress) && - userAddress !== constants.AddressZero - ) { + if (userAddress && isAddress(userAddress) && userAddress !== ZeroAddress) { const userAddressChanged = userAddress.toLowerCase(); setTabIndexItems(0); setUserData(undefined); @@ -181,22 +133,23 @@ const UserProfilePage: React.FC = () => { if (response.user) { setUserData(response.user); } else { - const defaultUser = { - avatar: null, - background: null, + const defaultUser: User = { + avatar: '', + background: '', creationDate: '2023-04-25T14:54:58.190Z', email: '', - firstName: null, - lastName: null, + firstName: '', + lastName: '', nickName: `@${userAddress}`, ageVerified: false, - publicAddress: `${userAddress}`, - _id: 'none' + publicAddress: userAddress as Hex, + _id: 'none', + blocked: false }; setUserData(defaultUser); } } else { - setUserData(null); + setUserData(undefined); } } }, [userAddress]); @@ -253,21 +206,28 @@ const UserProfilePage: React.FC = () => { ]; - const photoUpload = useCallback((e) => { - e.preventDefault(); - const reader = new FileReader(); - const fileF = e.target.files[0]; - reader.onloadend = () => { - if (fileF.type !== 'video/mp4') { - setFileUpload(fileF); - } else { - Swal.fire('Info', `You cannot upload video to background!`, 'warning'); + const photoUpload = useCallback( + (e) => { + e.preventDefault(); + const reader = new FileReader(); + const fileF = e.target.files[0]; + reader.onloadend = () => { + if (fileF.type !== 'video/mp4') { + setFileUpload(fileF); + } else { + rSwal.fire( + 'Info', + `You cannot upload video to background!`, + 'warning' + ); + } + }; + if (fileF) { + reader.readAsDataURL(fileF); } - }; - if (fileF) { - reader.readAsDataURL(fileF); - } - }, []); + }, + [rSwal] + ); useEffect(() => { editBackground(); @@ -299,7 +259,6 @@ const UserProfilePage: React.FC = () => {
    1025 ? 'container' : 'wrapper-user-page'}`}>
    { }`}> {currentUserAddress === userAddress ? ( <> - + ) : (
    @@ -424,11 +380,7 @@ const UserProfilePage: React.FC = () => {
    )} {!editMode && ( - + )}
    @@ -559,7 +511,7 @@ const UserProfilePage: React.FC = () => {
    { - const dispatch = useDispatch(); + const dispatch = useAppDispatch(); const store = useStore(); const reactSwal = useSwal(); const hotdropsVar = import.meta.env.VITE_TESTNET; - const { primaryColor, textColor } = useSelector( - (store) => store.colorStore - ); - const { currentUserAddress } = useSelector( - (store) => store.contractStore - ); + const { primaryColor, textColor } = useAppSelector((store) => store.colors); + const { currentUserAddress } = useAppSelector((store) => store.web3); const [userName, setUserName] = useState(mainName.replace(/@/g, '')); const [emailUser, setEmailUser] = useState(userEmail); const [userAvatar, setUserAvatar] = useState( @@ -73,12 +66,6 @@ const EditMode = ({ emailUser={emailUser} filePhoto={filePhoto} currentUserAddress={currentUserAddress} - setUserName={setUserName} - setMainEmail={setMainEmail} - setMainName={setMainName} - setUserAvatar={setUserAvatar} - setImagePreviewUrl={setImagePreviewUrl} - onChangeEditMode={onChangeEditMode} /> ), @@ -111,13 +98,12 @@ const EditMode = ({ const { user, success } = profileUpdateResponse.data; if (success) { + dispatch(loadCurrentUser()); if (user?.nickName) { setUserName(user.nickName.replace(/@/g, '')); - dispatch(getUserStart(currentUserAddress)); setMainName(user.nickName); } setMainEmail(user?.email); - dispatch(getUserStart(currentUserAddress)); if (user?.avatar) { setUserAvatar(user.avatar); setImagePreviewUrl(user.avatar); diff --git a/rair-front/src/components/UserProfileSettings/NotificationPage/NotificationPage.tsx b/rair-front/src/components/UserProfileSettings/NotificationPage/NotificationPage.tsx index 6b8bab440..064ef3787 100644 --- a/rair-front/src/components/UserProfileSettings/NotificationPage/NotificationPage.tsx +++ b/rair-front/src/components/UserProfileSettings/NotificationPage/NotificationPage.tsx @@ -1,26 +1,31 @@ -//@ts-nocheck -import { useEffect } from 'react'; -import { useSelector } from 'react-redux'; +import { FC, useEffect } from 'react'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; -// import IconRemove from './images/icon-remove.png'; - -// import { useSelector } from 'react-redux'; import './NotificationPage.css'; -const NotificationPage = ({ el, readNotification, removeItem }) => { - const { headerLogoMobile, primaryColor } = useSelector( - (store) => store.colorStore +interface NotificationPageProps { + el?: any; + readNotification?: () => void; +} + +const NotificationPage: FC = ({ + el, + readNotification +}) => { + const { headerLogoMobile, primaryColor } = useAppSelector( + (store) => store.colors ); useEffect(() => { - readNotification(); - }, []) + if (readNotification) { + readNotification(); + } + }, []); return ( -
    +
    {
    Rair Tech
    -
    -
    - {el.message} + {el && ( +
    +
    {el.message}
    +
    {el.title}
    -
    {el.title}
    -
    + )}
    {/*
    { - const { headerLogoMobile } = useSelector( - (store) => store.colorStore + const { headerLogoMobile, primaryColor } = useAppSelector( + (store) => store.colors ); + const { currentUserAddress } = useAppSelector((store) => store.web3); const reactSwal = useSwal(); const store = useStore(); @@ -43,7 +41,7 @@ const NotificationBox = ({ getNotificationsCount(); } } - }, [currentUserAddress]); + }, [currentUserAddress, el._id, getNotifications, getNotificationsCount]); const readNotification = useCallback(async () => { if (currentUserAddress) { @@ -62,17 +60,13 @@ const NotificationBox = ({ getNotificationsCount(); } } - }, [currentUserAddress]); + }, [currentUserAddress, el._id, getNotifications, getNotificationsCount]); const showMoreDetails = () => { reactSwal.fire({ html: ( - + ), width: '90vw', diff --git a/rair-front/src/components/UserProfileSettings/PopUpNotification/PopUpNotification.tsx b/rair-front/src/components/UserProfileSettings/PopUpNotification/PopUpNotification.tsx index fb20f4d3c..cf5e4ab81 100644 --- a/rair-front/src/components/UserProfileSettings/PopUpNotification/PopUpNotification.tsx +++ b/rair-front/src/components/UserProfileSettings/PopUpNotification/PopUpNotification.tsx @@ -1,12 +1,7 @@ -//@ts-nocheck import { useCallback, useEffect, useState } from 'react'; -import { useSelector, useStore } from 'react-redux'; import { Popup } from 'reactjs-popup'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../../ducks/contracts/contracts.types'; -import { TUsersInitialState } from '../../../ducks/users/users.types'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; import useSwal from '../../../hooks/useSwal'; import { BellIcon } from '../../../images'; import { SocialBox } from '../../../styled-components/SocialLinkIcons/SocialLinkIcons'; @@ -15,78 +10,80 @@ import PaginationBox from '../../MockUpPage/PaginationBox/PaginationBox'; import NotificationBox from './NotificationBox/NotificationBox'; -const PopUpNotification = ({getNotifications, realDataNotification, notificationCount, getNotificationsCount, setRealDataNotification}) => +const PopUpNotification = ({ + getNotifications, + realDataNotification, + notificationCount, + getNotificationsCount +}) => // props was - isNotification { - const currentName = - import.meta.env.VITE_TESTNET === 'true' ? 'HotDrops' : 'Rair.tech'; const [openModal, setOpenModal] = useState(false); - const store = useStore(); const reactSwal = useSwal(); - const { currentUserAddress } = useSelector< - RootState, - ContractsInitialType - >((state) => state.contractStore); - const [totalPageForPagination, setTotalPageForPagination] = useState(0); - const [currentPageForNotification, setCurrentPageNotification] = useState(1); - const { primaryColor, primaryButtonColor, textColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); - const { uploadVideo } = useSelector( - (store) => store.videoDemoStore - ); - const { userRd } = useSelector( - (store) => store.userStore + 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 changePageForVideo = (currentPage: number) => { setCurrentPageNotification(currentPage); - const currentPageNumber = currentPage === 0 ? currentPage : currentPage - 1; + const currentPageNumber = + currentPage === 0 ? currentPage : currentPage - 1; getNotifications(Number(currentPageNumber)); }; - const getNotificationsCountPagitation = useCallback( async () => { - if(currentUserAddress) { + 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]); + }, [currentUserAddress, isLoggedIn]); - const deleteAllNotificaiton = useCallback( async() => { - if(currentUserAddress) { + const deleteAllNotificaiton = useCallback(async () => { + if (currentUserAddress) { const result = await rFetch(`/api/notifications`, { - method: "DELETE", + method: 'DELETE', body: JSON.stringify([]) }); - if(result.success) { + if (result.success) { getNotifications(); getNotificationsCount(); reactSwal.fire({ - title : "Success", + title: 'Success', icon: 'success' }); } } - }, [currentUserAddress]) + }, [ + currentUserAddress, + getNotifications, + getNotificationsCount, + reactSwal + ]); useEffect(() => { - if(openModal) { + if (openModal) { getNotifications(0); getNotificationsCount(); } - }, [openModal]); + }, [getNotifications, getNotificationsCount, openModal]); useEffect(() => { getNotificationsCount(); - }, [getNotificationsCount]) + }, [getNotificationsCount]); useEffect(() => { getNotificationsCountPagitation(); - }, [getNotificationsCountPagitation]) + }, [getNotificationsCountPagitation]); const onCloseNext = useCallback(() => { if (!openModal) { @@ -98,15 +95,6 @@ const PopUpNotification = ({getNotifications, realDataNotification, notification onCloseNext(); }, [onCloseNext]); - useEffect(() => { - if (uploadVideo) { - setOpenModal(true); - } else { - setOpenModal(false); - } - }, [uploadVideo]); - - return ( <> - {uploadVideo && userRd?.email && } + {email && } {notificationCount > 0 && ( -
    {notificationCount > 9 ? "9+" : notificationCount}
    +
    + {notificationCount > 9 ? '9+' : notificationCount} +
    )}
    { setOpenModal(false); @@ -145,66 +137,68 @@ const PopUpNotification = ({getNotifications, realDataNotification, notification }`, border: '1px solid #fff', color: `${primaryColor === 'rhyno' && '#000'}`, - maxHeight: '500px', + maxHeight: '500px' }}> -
    -
    Notifications
    - -
    -
    - {realDataNotification && realDataNotification.length > 0 ? ( - realDataNotification.map((el) => { - return ( - - ) - }) - ) : ( -
    +
    Notifications
    +
    - )} -
    - { - - notificationCount > 0 && totalPageForPagination && - } + Clear all +
    +
    + {realDataNotification && realDataNotification.length > 0 ? ( + realDataNotification.map((el) => { + return ( + + ); + }) + ) : ( +
    + {"You don't have any notifications now"} +
    + )} +
    + {notificationCount > 0 && totalPageForPagination && ( + + )} +
    )} diff --git a/rair-front/src/components/UserProfileSettings/PopUpSetting.tsx b/rair-front/src/components/UserProfileSettings/PopUpSetting.tsx index e9325a1e7..d139348bf 100644 --- a/rair-front/src/components/UserProfileSettings/PopUpSetting.tsx +++ b/rair-front/src/components/UserProfileSettings/PopUpSetting.tsx @@ -1,82 +1,83 @@ -//@ts-nocheck import { useCallback, useEffect, useRef, useState } from 'react'; -import { useSelector } from 'react-redux'; import { useNavigate } from 'react-router-dom'; import { Popup } from 'reactjs-popup'; -import { faBars, faSignOutAlt } from '@fortawesome/free-solid-svg-icons'; +import { + faBars, + faSignOutAlt, + faUpload, + faUser +} from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { BigNumber, utils } from 'ethers'; -import { formatEther } from 'ethers/lib/utils'; +import { formatEther } from 'ethers'; -import { RootState } from '../../ducks'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; -// import { TUsersInitialState } from '../../ducks/users/users.types'; -// React Redux types import useConnectUser from '../../hooks/useConnectUser'; +import useContracts from '../../hooks/useContracts'; +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; import { RairFavicon, RairTokenLogo, VerifiedIcon } from '../../images'; -import useServerSettings from '../adminViews/useServerSettings'; import LoadingComponent from '../common/LoadingComponent'; import { TooltipBox } from '../common/Tooltip/TooltipBox'; import useWeb3Tx from './../../hooks/useWeb3Tx'; import EditMode from './EditMode/EditMode'; import defaultPictures from './images/defaultUserPictures.png'; -import { - SvgFactoryIcon, - SvgUpload, - SvgUserIcon -} from './SettingsIcons/SettingsIcons'; +import { SvgFactoryIcon } from './SettingsIcons/SettingsIcons'; -const PopUpSettings = ({ showAlert, selectedChain, setTabIndexItems }) => { - const settingBlockRef = useRef(); +const PopUpSettings = ({ showAlert, setTabIndexItems }) => { + const settingBlockRef = useRef(null); const navigate = useNavigate(); const [next, setNext] = useState(false); - const [, /*openModal*/ setOpenModal] = useState(false); - const [userName, setUserName] = useState(); - const [userEmail, setUserEmail] = useState(); - const [triggerState, setTriggerState] = useState(); + const [userName, setUserName] = useState(); + const [userEmail, setUserEmail] = useState(); + const [triggerState, setTriggerState] = useState(false); const [editMode, setEditMode] = useState(false); const [userBalance, setUserBalance] = useState(''); const [isLoadingBalance, setIsLoadingBalance] = useState(false); const [userBalanceTrigger, setUserBalanceTrigger] = useState(false); - const [userRairBalance, setUserRairBalance] = useState< - BigNumber | undefined - >(); + const [userRairBalance, setUserRairBalance] = useState(); const hotdropsVar = import.meta.env.VITE_TESTNET; const { getBlockchainData } = useServerSettings(); - const { primaryColor, textColor, iconColor } = useSelector( - (store) => store.colorStore + const { primaryColor, textColor, iconColor, isDarkMode } = useAppSelector( + (store) => store.colors ); - const [imagePreviewUrl, setImagePreviewUrl] = useState(null); - const { adminRights, loggedIn } = useSelector( - (store) => store.userStore - ); + const [imagePreviewUrl, setImagePreviewUrl] = useState(); + const { adminRights, isLoggedIn, nickName, avatar, email, ageVerified } = + useAppSelector((store) => store.user); const { logoutUser } = useConnectUser(); - const { userData } = useSelector((store) => store.userStore); - - const { currentUserAddress, mainTokenInstance, currentChain } = useSelector< - RootState, - ContractsInitialType - >((store) => store.contractStore); + const { mainTokenInstance } = useContracts(); + const { currentUserAddress, connectedChain } = useAppSelector( + (store) => store.web3 + ); const { web3TxHandler } = useWeb3Tx(); const getUserRairBalance = useCallback(async () => { - if (!mainTokenInstance || userRairBalance) { + if ( + !userBalanceTrigger || + !currentUserAddress || + !mainTokenInstance || + userRairBalance + ) { return; } const result = await web3TxHandler(mainTokenInstance, 'balanceOf', [ currentUserAddress ]); - if (result?._isBigNumber) { + if (result) { setUserRairBalance(result); } - }, [mainTokenInstance, currentUserAddress, userRairBalance, web3TxHandler]); + }, [ + userBalanceTrigger, + currentUserAddress, + mainTokenInstance, + userRairBalance, + web3TxHandler + ]); useEffect(() => { getUserRairBalance(); @@ -87,31 +88,32 @@ const PopUpSettings = ({ showAlert, selectedChain, setTabIndexItems }) => { }, [setEditMode]); useEffect(() => { - if (userData) { - setUserName(userData.nickName); - setUserEmail(userData.email); - if (userData.avatar) { - setImagePreviewUrl(userData.avatar); + if (isLoggedIn) { + setUserName(nickName); + setUserEmail(email); + if (avatar) { + setImagePreviewUrl(avatar); } } - }, [userData]); + }, [avatar, email, isLoggedIn, nickName]); const getBalance = useCallback(async () => { - if (currentUserAddress && mainTokenInstance?.provider) { + if (currentUserAddress && mainTokenInstance?.runner?.provider) { setIsLoadingBalance(true); const balance = - await mainTokenInstance.provider.getBalance(currentUserAddress); + await mainTokenInstance?.runner?.provider?.getBalance( + currentUserAddress + ); - if (balance) { - const result = utils.formatEther(balance); + if (balance !== undefined) { + const result = formatEther(balance.toString()); const final = Number(result.toString())?.toFixed(2)?.toString(); setUserBalance(final); setIsLoadingBalance(false); } } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [currentUserAddress, mainTokenInstance, userData]); + }, [currentUserAddress, mainTokenInstance]); useEffect(() => { getBalance(); @@ -131,10 +133,6 @@ const PopUpSettings = ({ showAlert, selectedChain, setTabIndexItems }) => { } }; - useEffect(() => { - setOpenModal(); - }, [setOpenModal]); - const pushToUploadVideo = (tab: number) => { setTabIndexItems(tab); navigate('/demo/upload'); @@ -151,7 +149,6 @@ const PopUpSettings = ({ showAlert, selectedChain, setTabIndexItems }) => { const handlePopUp = () => { setNext((prev) => !prev); - setOpenModal((prev) => !prev); }; const onCloseNext = useCallback(() => { @@ -171,32 +168,26 @@ const PopUpSettings = ({ showAlert, selectedChain, setTabIndexItems }) => { return ( <>
    setUserBalanceTrigger((prev) => !prev)} - className={`profile-user-balance ${ - primaryColor === '#dedede' ? 'rhyno' : '' - }`}> + className={`profile-user-balance ${!isDarkMode ? 'rhyno' : ''}`}> logo - {getBlockchainData(currentChain) && ( - logo + {getBlockchainData(connectedChain) && ( + logo )}
    { alt="User Avatar" /> ) : ( - + )}
    - {userData && userData.ageVerified && ( + {ageVerified && ( { border: `${ primaryColor === '#dedede' ? '1px solid #DEDEDE' : 'none' }`, - marginTop: `${selectedChain && showAlert ? '65px' : '12px'}` + marginTop: `${showAlert ? '65px' : '12px'}` }}>
    { )}
    - {getBlockchainData(currentChain) && ( + {getBlockchainData(connectedChain) && ( logo )} @@ -431,7 +422,7 @@ const PopUpSettings = ({ showAlert, selectedChain, setTabIndexItems }) => { border: `${ primaryColor === '#dedede' ? '1px solid #DEDEDE' : 'none' }`, - marginTop: `${selectedChain && showAlert ? '65px' : '12px'}` + marginTop: `${showAlert ? '65px' : '12px'}` }}> {!next ? (
    @@ -443,47 +434,25 @@ const PopUpSettings = ({ showAlert, selectedChain, setTabIndexItems }) => { color: primaryColor === '#dedede' ? 'rgb(41, 41, 41)' : 'white' }}> - {' '} + {' '} Profile settings
  • {/* {hotdropsVar !== 'true' && ( */} - {hotdropsVar === 'true' - ? loggedIn && - adminRights && ( -
  • pushToUploadVideo(2)} - style={{ - color: - primaryColor === '#dedede' - ? 'rgb(41, 41, 41)' - : 'white' - }}> - {' '} - Upload video -
  • - ) - : loggedIn && ( -
  • pushToUploadVideo(2)} - style={{ - color: - primaryColor === '#dedede' - ? 'rgb(41, 41, 41)' - : 'white' - }}> - {' '} - Upload video -
  • - )} + {(hotdropsVar === 'true' + ? isLoggedIn && adminRights + : isLoggedIn) && ( +
  • pushToUploadVideo(2)} + style={{ + color: textColor + }}> + {' '} + Upload video +
  • + )} {/* )} */} {/*
  • pushToMyItems(2)} @@ -543,8 +512,6 @@ const PopUpSettings = ({ showAlert, selectedChain, setTabIndexItems }) => { = ({ xmlns="http://www.w3.org/2000/svg"> ); }; -export const SvgUpload = ({ width, height, primaryColor, customSecondaryButtonColor }) => { +export const SvgUpload = ({ + width, + height, + primaryColor, + customSecondaryButtonColor +}) => { return ( ); }; -export const SvgMyFavorites = ({ primaryColor , customSecondaryButtonColor}) => { +export const SvgMyFavorites = ({ + primaryColor, + customSecondaryButtonColor +}) => { return ( xmlns="http://www.w3.org/2000/svg"> { xmlns="http://www.w3.org/2000/svg"> { ); }; -export const SvgFactoryIcon = ({ primaryColor, customSecondaryButtonColor }) => { +export const SvgFactoryIcon = ({ + primaryColor, + customSecondaryButtonColor +}) => { return ( xmlns="http://www.w3.org/2000/svg"> { xmlns="http://www.w3.org/2000/svg"> { @@ -20,22 +17,16 @@ export const AgreementsPopUp = ({ userName, emailUser, filePhoto, - currentUserAddress, - setUserName, - setMainEmail, - setMainName, - setUserAvatar, - setImagePreviewUrl, - onChangeEditMode + currentUserAddress }) => { const [privacyPolicy, setPrivacyPolicy] = useState(false); const [termsOfUse, setTermsOfUse] = useState(false); - const dispatch = useDispatch(); + const dispatch = useAppDispatch(); - const { textColor, primaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { textColor, primaryButtonColor } = useAppSelector( + (store) => store.colors + ); + const rSwal = useSwal(); const onChangeUserInfo = async () => { const formData = new FormData(); @@ -56,34 +47,19 @@ export const AgreementsPopUp = ({ } } ); - const { user, success } = profileUpdateResponse.data; - - if (user) { - if (user.nickName) { - setUserName(user.nickName.replace(/@/g, '')); - dispatch(getUserStart(currentUserAddress)); - } - if (success) { - setMainName(user.nickName); - setMainEmail(user.email); + const { success } = profileUpdateResponse.data; - dispatch(getUserStart(currentUserAddress)); - } - if (user?.avatar) { - setUserAvatar(user.avatar); - setImagePreviewUrl(user.avatar); - } - onChangeEditMode(); - Swal.fire( + if (success) { + rSwal.fire( 'Success', `You have just changed your email address successfully!`, 'success' ); } + + dispatch(loadCurrentUser()); } catch (err) { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const error = err as AxiosError; - Swal.fire('Info', `The name ${userName} already exists`, 'question'); + rSwal.fire('Info', `The name ${userName} already exists`, 'question'); } }; @@ -164,9 +140,7 @@ export const AgreementsPopUp = ({ }; const ConfirmAgreements = () => { - const { primaryColor, textColor } = useSelector( - (store) => store.colorStore - ); + const { primaryColor, textColor } = useAppSelector((store) => store.colors); const reactSwal = useSwal(); const openModal = () => { diff --git a/rair-front/src/components/UserProfileSettings/UserProfileSettings.tsx b/rair-front/src/components/UserProfileSettings/UserProfileSettings.tsx index dd98d7824..2ba17a1ac 100644 --- a/rair-front/src/components/UserProfileSettings/UserProfileSettings.tsx +++ b/rair-front/src/components/UserProfileSettings/UserProfileSettings.tsx @@ -1,35 +1,17 @@ -//@ts-nocheck -import React, { useEffect } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; - import PopUpSettings from './PopUpSetting'; -// React Redux types -import { setColorScheme } from '../../ducks/colors/actions'; -import { getUserStart } from '../../ducks/users/actions'; +import { useAppDispatch, useAppSelector } from '../../hooks/useReduxHooks'; import { SunIcon } from '../../images'; +import { setColorScheme } from '../../redux/colorSlice'; import { SocialBox } from '../../styled-components/SocialLinkIcons/SocialLinkIcons'; import { TooltipBox } from '../common/Tooltip/TooltipBox'; import './UserProfileSettings.css'; -const UserProfileSettings = ({ - adminAccess, - showAlert, - selectedChain, - setTabIndexItems, - isSplashPage -}) => { - const dispatch = useDispatch(); - const { loggedIn } = useSelector((store) => store.userStore); - const { primaryColor } = useSelector((store) => store.colorStore); - const { currentUserAddress } = useSelector((store) => store.contractStore); - - useEffect(() => { - if (currentUserAddress) { - dispatch(getUserStart(currentUserAddress)); - } - }, [currentUserAddress, dispatch]); +const UserProfileSettings = ({ showAlert, setTabIndexItems }) => { + const dispatch = useAppDispatch(); + const { isLoggedIn } = useAppSelector((store) => store.user); + const { primaryColor, isDarkMode } = useAppSelector((store) => store.colors); return (
    { - dispatch( - setColorScheme( - primaryColor === '#dedede' ? 'charcoal' : 'rhyno' - ) - ); + dispatch(setColorScheme(isDarkMode ? 'light' : 'dark')); }}> - + - {loggedIn && ( + {isLoggedIn && (
    )} diff --git a/rair-front/src/components/YotiPage/YotiPage.tsx b/rair-front/src/components/YotiPage/YotiPage.tsx index 0ce1a8b62..06319ce8b 100644 --- a/rair-front/src/components/YotiPage/YotiPage.tsx +++ b/rair-front/src/components/YotiPage/YotiPage.tsx @@ -1,18 +1,20 @@ -import { useState } from 'react'; -import { useDispatch } from 'react-redux'; +import { FC, useState } from 'react'; import FaceCapture from '@getyoti/react-face-capture'; -import { setUserData } from '../../ducks/users/actions'; import useSwal from '../../hooks/useSwal'; import { YotiLogo } from '../../images'; +import { loadCurrentUser } from '../../redux/userSlice'; import { rFetch } from '../../utils/rFetch'; import './YotiPage.css'; -const YotiPage = ({ setOpenVideoplayer }) => { +interface YotiPage { + setOpenVideoPlayer?: React.Dispatch>; +} + +const YotiPage: FC = ({ setOpenVideoPlayer }) => { const [yotiVerify, setYotiVerify] = useState(false); const reactSwal = useSwal(); - const dispatch = useDispatch(); const onSuccess = async ({ img }) => { const data = await rFetch('/api/users/verify-age', { @@ -25,36 +27,26 @@ const YotiPage = ({ setOpenVideoplayer }) => { } }); - if (data.success) { - if (data.data.age.age_check === 'pass') { - const { success, user: userInfoData } = await rFetch( - '/api/auth/me/', - undefined, - undefined, - false - ); + loadCurrentUser(); - if (success) { - dispatch(setUserData(userInfoData)); - } - reactSwal - .fire({ - title: 'Age verified!', - html: 'Thanks you for verification', - icon: 'success' - }) - .then((result) => { - if (result.isConfirmed) { - setOpenVideoplayer(true); - } - }); - } else { - reactSwal.fire({ - title: 'Your age is not verified', - html: 'Please try again later', - icon: 'error' + if (data.success && data.data.age.age_check === 'pass') { + reactSwal + .fire({ + title: 'Age verified!', + html: 'Thanks you for verification', + icon: 'success' + }) + .then((result) => { + if (result.isConfirmed && setOpenVideoPlayer) { + setOpenVideoPlayer(true); + } }); - } + } else { + reactSwal.fire({ + title: 'Your age is not verified', + html: 'Please try again later', + icon: 'error' + }); } }; const onError = (error) => console.error(`Error =, ${error}`); @@ -69,6 +61,7 @@ const YotiPage = ({ setOpenVideoplayer }) => { secure={false} returnPreviewImage={true} faceCaptureAssetsRootUrl={'/yoti-assets/'} + numStableFrames={4} /> ) : (
    diff --git a/rair-front/src/components/adminViews/BatchERC20Transfer.tsx b/rair-front/src/components/adminViews/BatchERC20Transfer.tsx index 2b06ebc89..8d9d2dbce 100644 --- a/rair-front/src/components/adminViews/BatchERC20Transfer.tsx +++ b/rair-front/src/components/adminViews/BatchERC20Transfer.tsx @@ -1,13 +1,11 @@ import { useCallback, useState } from 'react'; import Dropzone from 'react-dropzone'; -import { useSelector } from 'react-redux'; import { faPlus, faTrash } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { parseUnits } from 'ethers/lib/utils'; +import { parseUnits } from 'ethers'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; +import useContracts from '../../hooks/useContracts'; +import { useAppSelector } from '../../hooks/useReduxHooks'; import useSwal from '../../hooks/useSwal'; import useWeb3Tx from '../../hooks/useWeb3Tx'; import csvParser from '../../utils/csvParser'; @@ -53,10 +51,8 @@ type RowData = { const BatchERC20Transfer = () => { const [data, setData] = useState([]); const { textColor, primaryColor, primaryButtonColor, secondaryButtonColor } = - useSelector((store) => store.colorStore); - const { mainTokenInstance } = useSelector( - (store) => store.contractStore - ); + useAppSelector((store) => store.colors); + const { mainTokenInstance } = useContracts(); const { web3TxHandler } = useWeb3Tx(); const reactSwal = useSwal(); const updateRowData = useCallback( diff --git a/rair-front/src/components/adminViews/BlockchainSwitcher.tsx b/rair-front/src/components/adminViews/BlockchainSwitcher.tsx index 1779e2797..9e2f154dd 100644 --- a/rair-front/src/components/adminViews/BlockchainSwitcher.tsx +++ b/rair-front/src/components/adminViews/BlockchainSwitcher.tsx @@ -1,33 +1,24 @@ import { useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import * as ethers from 'ethers'; +import { JsonRpcProvider, Wallet } from 'ethers'; -import useServerSettings from './useServerSettings'; - -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { - setChainId, - setProgrammaticProvider -} from '../../ducks/contracts/actions'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; +import { useAppDispatch, useAppSelector } from '../../hooks/useReduxHooks'; import useSwal from '../../hooks/useSwal'; import useWeb3Tx from '../../hooks/useWeb3Tx'; +import { + setConnectedChain, + setProgrammaticProvider +} from '../../redux/web3Slice'; import InputField from '../common/InputField'; const BlockChainSwitcher = () => { const [UNSAFE_PrivateKey, setUNSAFE_PrivateKey] = useState(''); - const { textColor, primaryButtonColor, secondaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); - const { blockchainSettings } = useServerSettings(); + const { textColor, primaryButtonColor, secondaryButtonColor } = + useAppSelector((store) => store.colors); + const { blockchainSettings } = useAppSelector((store) => store.settings); const { web3Switch } = useWeb3Tx(); - const { currentChain } = useSelector( - (state) => state.contractStore - ); - const dispatch = useDispatch(); + const { connectedChain } = useAppSelector((state) => state.web3); + const dispatch = useAppDispatch(); const reactSwal = useSwal(); const connectProgrammatically = async ({ @@ -43,16 +34,10 @@ const BlockChainSwitcher = () => { name: chainName, timeout: 1000000 }; - const provider = new ethers.providers.JsonRpcProvider( - rpcEndpoint, - networkData - ); - const currentWallet = await new ethers.Wallet( - UNSAFE_PrivateKey, - provider - ); - await dispatch(setProgrammaticProvider(currentWallet)); - dispatch(setChainId(chainId, blockchainSettings)); + const provider = new JsonRpcProvider(rpcEndpoint, networkData); + const currentWallet = new Wallet(UNSAFE_PrivateKey, provider); + dispatch(setProgrammaticProvider(currentWallet)); + dispatch(setConnectedChain(chainId)); } catch (err) { const error = err as Error; console.error(error); @@ -92,7 +77,7 @@ const BlockChainSwitcher = () => { color: textColor }} disabled={ - currentChain === item.hash?.toLowerCase() || + connectedChain === item.hash?.toLowerCase() || UNSAFE_PrivateKey.length !== 64 } onClick={async () => { @@ -122,7 +107,7 @@ const BlockChainSwitcher = () => { index % 2 === 0 ? secondaryButtonColor : primaryButtonColor, color: textColor }} - disabled={currentChain === item.hash?.toLowerCase()} + disabled={connectedChain === item.hash?.toLowerCase()} onClick={() => { if (item.hash) { web3Switch(item.hash); diff --git a/rair-front/src/components/adminViews/ImportExternalContracts.tsx b/rair-front/src/components/adminViews/ImportExternalContracts.tsx index f976268d8..d9ee24dee 100644 --- a/rair-front/src/components/adminViews/ImportExternalContracts.tsx +++ b/rair-front/src/components/adminViews/ImportExternalContracts.tsx @@ -1,14 +1,10 @@ import { useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; -import { utils } from 'ethers'; -import { isAddress } from 'ethers/lib/utils'; - -import useServerSettings from './useServerSettings'; +import { isAddress } from 'ethers'; +import { Hex } from 'viem'; import { diamondFactoryAbi } from '../../contracts'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; +import useContracts from '../../hooks/useContracts'; +import { useAppSelector } from '../../hooks/useReduxHooks'; import useSwal from '../../hooks/useSwal'; import useWeb3Tx from '../../hooks/useWeb3Tx'; import { validateInteger } from '../../utils/metamaskUtils'; @@ -20,9 +16,9 @@ import InputSelect from '../common/InputSelect'; const ImportExternalContract = () => { const [selectedContract, setSelectedContract] = useState(''); const [resultData, setResultData] = useState(''); - const [selectedBlockchain, setSelectedBlockchain] = useState< - BlockchainType | 'null' - >('null'); + const [selectedBlockchain, setSelectedBlockchain] = useState( + 'null' + ); const [owner, setOwner] = useState(''); const [sendingData, setSendingData] = useState(false); const [limit, setLimit] = useState(0); @@ -31,7 +27,7 @@ const ImportExternalContract = () => { const reactSwal = useSwal(); const { web3TxHandler, correctBlockchain, web3Switch } = useWeb3Tx(); - const { blockchainSettings } = useServerSettings(); + const { blockchainSettings } = useAppSelector((store) => store.settings); useEffect(() => { const report = (socketData) => { @@ -64,13 +60,9 @@ const ImportExternalContract = () => { }; }); - const { contractCreator } = useSelector( - (store) => store.contractStore - ); - const { primaryButtonColor, secondaryButtonColor, textColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { contractCreator } = useContracts(); + const { primaryButtonColor, secondaryButtonColor, textColor } = + useAppSelector((store) => store.colors); const callImport = async () => { if (!validateInteger(limit)) { @@ -104,13 +96,19 @@ const ImportExternalContract = () => { return; } if (!correctBlockchain(selectedBlockchain)) { - web3Switch(selectedBlockchain as BlockchainType); + web3Switch(selectedBlockchain); return; } if (!contractCreator) { return; } - const instance = await contractCreator(selectedContract, diamondFactoryAbi); + if (!isAddress(selectedContract)) { + return; + } + const instance = await contractCreator( + selectedContract as Hex, + diamondFactoryAbi + ); if (instance) { const owner = await web3TxHandler(instance, 'owner', [], { intendedBlockchain: selectedBlockchain, @@ -183,7 +181,7 @@ const ImportExternalContract = () => { sendingData || !validateInteger(limit) || selectedBlockchain === 'null' || - !utils.isAddress(selectedContract) + !isAddress(selectedContract) } className="btn rair-button col-12" style={{ diff --git a/rair-front/src/components/adminViews/LicenseExchange.tsx b/rair-front/src/components/adminViews/LicenseExchange.tsx index 142ed865e..b4ea5b83c 100644 --- a/rair-front/src/components/adminViews/LicenseExchange.tsx +++ b/rair-front/src/components/adminViews/LicenseExchange.tsx @@ -1,11 +1,8 @@ import { useCallback, useState } from 'react'; -import { useSelector } from 'react-redux'; -import { formatEther, parseUnits } from 'ethers/lib/utils'; +import { formatEther, parseUnits } from 'ethers'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; -import { TUsersInitialState } from '../../ducks/users/users.types'; +import useContracts from '../../hooks/useContracts'; +import { useAppSelector } from '../../hooks/useReduxHooks'; import useSwal from '../../hooks/useSwal'; import useWeb3Tx from '../../hooks/useWeb3Tx'; import InputField from '../common/InputField'; @@ -16,19 +13,13 @@ const LicenseExchange = () => { const [userAddress, setUserAddress] = useState(''); const [signedHash, setSignedhash] = useState(''); - const { licenseExchangeInstance, mainTokenInstance, currentUserAddress } = - useSelector( - (store) => store.contractStore - ); + const { licenseExchangeInstance, mainTokenInstance } = useContracts(); + const { currentUserAddress } = useAppSelector((store) => store.web3); - const { adminRights } = useSelector( - (store) => store.userStore - ); + const { adminRights } = useAppSelector((store) => store.user); - const { primaryButtonColor, secondaryButtonColor, textColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { primaryButtonColor, secondaryButtonColor, textColor } = + useAppSelector((store) => store.colors); const { web3TxHandler, web3TxSignMessage } = useWeb3Tx(); const rSwal = useSwal(); @@ -74,7 +65,7 @@ const LicenseExchange = () => { }); const allowance = await web3TxHandler(mainTokenInstance, 'allowance', [ currentUserAddress, - licenseExchangeInstance.address + await licenseExchangeInstance.getAddress() ]); if (allowance.lt(tokenPriceBigNumber)) { rSwal.fire({ @@ -85,7 +76,7 @@ const LicenseExchange = () => { showConfirmButton: false }); await web3TxHandler(mainTokenInstance, 'approve', [ - licenseExchangeInstance.address, + await licenseExchangeInstance.getAddress(), tokenPriceBigNumber ]); } @@ -122,7 +113,7 @@ const LicenseExchange = () => { } await web3TxHandler(licenseExchangeInstance, 'setPurchasePeriod', [180]); await web3TxHandler(licenseExchangeInstance, 'updateERC20Address', [ - mainTokenInstance.address + await mainTokenInstance.getAddress() ]); }, [licenseExchangeInstance, web3TxHandler, mainTokenInstance]); diff --git a/rair-front/src/components/adminViews/ServerSettings.tsx b/rair-front/src/components/adminViews/ServerSettings.tsx deleted file mode 100644 index 1a6a96a7d..000000000 --- a/rair-front/src/components/adminViews/ServerSettings.tsx +++ /dev/null @@ -1,1109 +0,0 @@ -import { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; -import { AlchemyChainMap } from '@alchemy/aa-core'; -import { faArrowUp, faTrash } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { isAddress } from 'ethers/lib/utils'; - -import useServerSettings from './useServerSettings'; - -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import useSwal from '../../hooks/useSwal'; -import { rFetch } from '../../utils/rFetch'; -import { OptionsType } from '../common/commonTypes/InputSelectTypes.types'; -import InputField from '../common/InputField'; -import InputSelect from '../common/InputSelect'; - -type Category = { - name: string; - _id?: string; - files?: number; -}; - -const ServerSettings = ({ fullContractData }) => { - const serverSettings = useServerSettings(); - const [productOptions, setProductOptions] = useState(); - const [categoryList, setCategoryList] = useState([]); - - const [customLightModeLogo, setCustomLightModeLogo] = useState({ name: '' }); - const [customDarkModeLogo, setCustomDarkModeLogo] = useState({ name: '' }); - const [customLightModeMobileLogo, setCustomLightModeMobileLogo] = useState({ - name: '' - }); - const [favicon, setFavicon] = useState({ - name: '' - }); - const [customDarkModeMobileLogo, setCustomDarkModeMobileLogo] = useState({ - name: '' - }); - - const { primaryButtonColor, textColor, secondaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); - - const reactSwal = useSwal(); - - const modifySuperAdminAddress = (index) => (value) => { - const aux = [...serverSettings.superAdmins]; - aux[index] = value; - serverSettings.setSuperAdmins(aux); - }; - - const deleteSuperAdminAddress = (index) => { - const aux = [...serverSettings.superAdmins]; - aux.splice(index, 1); - serverSettings.setSuperAdmins(aux); - }; - - const modifyFooterLinks = (index, field) => (value) => { - const aux = [...serverSettings.footerLinks]; - aux[index][field] = value; - serverSettings.setFooterLinks(aux); - }; - - const deleteFooterLinks = (index) => { - const aux = [...serverSettings.footerLinks]; - aux.splice(index, 1); - serverSettings.setFooterLinks(aux); - }; - - const modifyCustomValues = (index, field) => (value) => { - const aux = [...serverSettings.customValues]; - aux[index][field] = value; - serverSettings.setCustomValues(aux); - }; - - const deleteCustomValues = (index) => { - const aux = [...serverSettings.customValues]; - aux.splice(index, 1); - serverSettings.setCustomValues(aux); - }; - - const getCategories = useCallback(async () => { - const { success, result } = await rFetch('/api/categories'); - if (success) { - setCategoryList(result); - } - }, []); - - useEffect(() => { - getCategories(); - }, [getCategories]); - - const setServerSetting = useCallback( - async (setting) => { - const { success } = await rFetch(`/api/settings/`, { - method: 'POST', - body: JSON.stringify(setting), - headers: { - 'Content-Type': 'application/json' - } - }); - if (success) { - serverSettings.getServerSettings(); - reactSwal.fire('Success', 'Setting updated', 'success'); - } - }, - [ - reactSwal, - serverSettings.getServerSettings, - serverSettings.customPrimaryColor, - serverSettings.customTextColor, - serverSettings.customPrimaryButtonColor, - serverSettings.customSecondaryButtonColor - ] - ); - - const setBlockchainSetting = useCallback( - async (chain: BlockchainType | undefined, method = 'PUT') => { - if (!chain) { - return; - } - const settings = serverSettings.blockchainSettings.find( - (chainData) => chainData.hash === chain - ); - - if (!settings) { - return; - } - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { _id, isNew, ...cleanChainData } = settings; - Object.keys(cleanChainData).forEach((field) => { - if (cleanChainData[field] === '') { - cleanChainData[field] = undefined; - } - }); - const { success } = await rFetch(`/api/settings/${chain}`, { - method, - body: JSON.stringify(cleanChainData), - headers: { - 'Content-Type': 'application/json' - } - }); - if (success) { - reactSwal.fire('Success', 'Blockchain settings updated', 'success'); - serverSettings.refreshBlockchainData(); - } - }, - [ - reactSwal, - serverSettings.blockchainSettings, - serverSettings.refreshBlockchainData - ] - ); - - const loadImage = useCallback( - (setterTarget) => (file) => { - const reader = new FileReader(); - reader.onloadend = () => { - if (file.type !== 'video/mp4') { - setterTarget(file); - } else { - reactSwal.fire( - 'Info', - `You cannot upload video as a logo`, - 'warning' - ); - } - }; - if (file) { - reader.readAsDataURL(file); - } - }, - [reactSwal] - ); - - const setAppLogos = useCallback( - async (target: string, image: any) => { - const formData = new FormData(); - if (image) { - formData.append('logoImage', image); - } - formData.append('target', target); - const { success } = await rFetch(`/api/settings/appLogo`, { - method: 'POST', - body: formData - }); - if (success) { - reactSwal.fire( - 'Success', - `App Logo ${image ? 'Set' : 'Removed'}`, - 'success' - ); - serverSettings.getServerSettings(); - } - }, - [reactSwal, serverSettings.getServerSettings] - ); - - useEffect(() => { - serverSettings.getServerSettings(); - }, [serverSettings.getServerSettings]); - - const deleteCategory = useCallback( - (index) => { - const aux = [...categoryList]; - aux.splice(index, 1); - setCategoryList(aux); - }, - [categoryList] - ); - - const updateCategory = useCallback( - (index) => (value) => { - const aux = [...categoryList]; - aux[index] = { - ...aux[index], - name: value - }; - setCategoryList(aux); - }, - [categoryList] - ); - - useEffect(() => { - serverSettings.setFeaturedProduct('null'); - if (serverSettings.featuredContract === 'null') { - return; - } - if (!fullContractData[serverSettings.featuredContract]?.products) { - return; - } - const options = Object.keys( - fullContractData[serverSettings.featuredContract].products - ).map((productIndex) => { - const data = - fullContractData[serverSettings.featuredContract].products[ - productIndex - ]; - return { label: `${data.name} (${data.copies} NFTs)`, value: data._id }; - }); - - setProductOptions(options); - }, [serverSettings.featuredContract, fullContractData]); - - const updateBlockchainSetting = useCallback( - ( - chain: BlockchainType | undefined, - setting: string, - value: string | number | boolean - ) => { - if (!chain) { - return; - } - const aux = serverSettings.blockchainSettings.map((chainData) => { - if (chainData.hash === chain) { - chainData[setting] = value; - } - return chainData; - }); - serverSettings.setBlockchainSettings(aux); - }, - [serverSettings.blockchainSettings] - ); - - return ( -
    -
    Server Settings
    - {[ - { - title: 'Only return minted tokens on collection page', - value: 'onlyMintedTokensResult' - }, - { - title: 'Allow demo page uploads', - value: 'demoUploadsEnabled' - }, - { - title: 'Use Vault for super admin verification', - value: 'superAdminsOnVault' - }, - { - title: 'Use gasless resales', - value: 'databaseResales' - } - ].map((item, index) => { - return ( -
    -
    {item.title}
    - - -
    - ); - })} -
    -

    Featured banner

    -
    -
    - { - return { - label: `${fullContractData[contract].title} (${serverSettings - .getBlockchainData[fullContractData[contract].blockchain] - ?.symbol})`, - value: contract - }; - })} - /> -
    -
    - -
    -
    - -
    -
    -

    Node address

    - - -
    -
    -

    Blockchain settings:

    - {serverSettings.blockchainSettings?.map((chain, index) => { - return ( -
    - - {chain.testnet ? ( - - - - ) : ( - '' - )}{' '} - {chain.name} ({chain.hash}) - - {[ - { - label: 'Sync contracts', - setting: 'sync' - }, - { - label: 'Display contracts', - setting: 'display' - }, - { - label: 'Test network', - setting: 'testnet' - }, - { - label: 'Supported by Alchemy SDK', - setting: 'alchemySupport' - } - ].map((booleanSetting, boolSettingIndex) => { - return ( -
    -
    - {booleanSetting.label} -
    -
    - - -
    -
    - ); - })} - {[ - { - label: 'Chain Id (Hexadecimal)', - type: 'text', - setting: 'hash', - effect: (chain) => { - const alchemyData = AlchemyChainMap.get(Number(chain)); - updateBlockchainSetting( - chain, - 'alchemySupport', - !!alchemyData - ); - if (alchemyData) { - updateBlockchainSetting( - chain, - 'testnet', - !!alchemyData?.testnet - ); - updateBlockchainSetting( - chain, - 'blockExplorerGateway', - alchemyData.blockExplorers?.default?.url || '' - ); - updateBlockchainSetting( - chain, - 'rpcEndpoint', - alchemyData.rpcUrls.default.http.at(0) || '' - ); - updateBlockchainSetting( - chain, - 'numericalId', - alchemyData.id - ); - updateBlockchainSetting(chain, 'name', alchemyData.name); - updateBlockchainSetting( - chain, - 'symbol', - alchemyData.nativeCurrency.symbol - ); - } - } - }, - { - label: 'Name', - type: 'text', - setting: 'name' - }, - { - label: 'Symbol', - type: 'text', - setting: 'symbol' - }, - { - label: 'Block Explorere URL', - type: 'text', - setting: 'blockExplorerGateway' - }, - { - label: 'RPC endpoint', - type: 'text', - setting: 'rpcEndpoint' - }, - { - label: 'Chain ID (Decimal)', - type: 'number', - setting: 'numericalId' - }, - { - label: 'Main ERC20 address', - type: 'text', - setting: 'mainTokenAddress' - }, - { - label: 'Classic Factory Address', - type: 'text', - setting: 'classicFactoryAddress' - }, - { - label: 'Diamond Factory Address', - type: 'text', - setting: 'diamondFactoryAddress' - }, - { - label: 'Marketplace Address', - type: 'text', - setting: 'diamondMarketplaceAddress' - }, - { - label: 'License exchange address', - type: 'text', - setting: 'licenseExchangeAddress' - } - ].map((inputSetting, inputSettingIndex) => { - return ( -
    - { - if (inputSetting.effect) { - inputSetting.effect(chain[inputSetting.setting]); - } - }} - getter={chain[inputSetting.setting]} - setter={(value) => - updateBlockchainSetting( - chain.hash, - inputSetting.setting, - value - ) - } - type={inputSetting.type} - /> -
    - ); - })} - - -
    -
    - ); - })} - -
    -
    -

    Super admins:

    - {serverSettings.settings.superAdminsOnVault - ? 'Currently using Vault' - : ''} - {serverSettings.superAdmins && - serverSettings.superAdmins.map((user, index) => { - return ( -
    - - -
    - ); - })} - - -
    -
    -
    -

    Custom Dark Mode Colors

    - {[ - { - getter: serverSettings.customPrimaryColor, - setter: serverSettings.setCustomPrimaryColor, - label: 'Primary Color' - }, - { - getter: serverSettings.customSecondaryColor, - setter: serverSettings.setCustomSecondaryColor, - label: 'Secondary Color' - }, - { - getter: serverSettings.customTextColor, - setter: serverSettings.setCustomTextColor, - label: 'Text Color' - }, - { - getter: serverSettings.customPrimaryButtonColor, - setter: serverSettings.setCustomPrimaryButtonColor, - label: 'Primary Button Color' - }, - { - getter: serverSettings.customSecondaryButtonColor, - setter: serverSettings.setCustomSecondaryButtonColor, - label: 'Secondary Button Color' - }, - { - getter: serverSettings.customFadeButtonColor, - setter: serverSettings.setCustomFadeButtonColor, - label: 'Fade Button Color' - } - ].map((item, index) => { - return ( -
    -
    - -
    -
    - -
    -
    - ); - })} -
    - - -
    -
    -
    -

    Custom Logos

    - {[ - { - label: 'Dark Mode Desktop Logo', - getter: customDarkModeLogo, - setter: setCustomDarkModeLogo, - target: 'darkModeBannerLogo' - }, - { - label: 'Dark Mode Mobile logo', - getter: customDarkModeMobileLogo, - setter: setCustomDarkModeMobileLogo, - target: 'darkModeMobileLogo' - }, - { - label: 'Light Mode Desktop Logo', - getter: customLightModeLogo, - setter: setCustomLightModeLogo, - target: 'lightModeBannerLogo' - }, - { - label: 'Light Mode Mobile Logo', - getter: customLightModeMobileLogo, - setter: setCustomLightModeMobileLogo, - target: 'lightModeMobileLogo' - }, - { - label: 'Favicon', - getter: favicon, - setter: setFavicon, - target: 'favicon' - } - ].map((item, index) => { - return ( -
    -
    - -
    - - -
    - ); - })} -
    -
    -

    Categories

    - {categoryList.map((categoryData, index) => { - return ( -
    -
    - -
    - -
    - ); - })} - - -
    -
    -

    Footer items

    - {serverSettings.footerLinks && - serverSettings.footerLinks.map((footerLink, index) => { - return ( -
    -
    - -
    -
    - -
    - -
    - ); - })} - - -
    -
    -

    Legal info

    - - -
    -
    -

    Server values

    - {serverSettings.customValues && - serverSettings.customValues.map((customValue, index) => { - return ( -
    -
    - -
    -
    - -
    - -
    - ); - })} - - -
    -
    -

    Default Signup Message

    - - -
    -
    -
    - ); -}; - -export default ServerSettings; diff --git a/rair-front/src/components/adminViews/adminView.types.ts b/rair-front/src/components/adminViews/adminView.types.ts index 3696b9bb4..ad0d89c52 100644 --- a/rair-front/src/components/adminViews/adminView.types.ts +++ b/rair-front/src/components/adminViews/adminView.types.ts @@ -1,3 +1,5 @@ +import { Hex } from 'viem'; + import { TTokenData } from '../../axios.responseTypes'; export type NativeCurrencyType = { @@ -7,7 +9,7 @@ export type NativeCurrencyType = { }; export type ChainDataType = { - chainId?: BlockchainType; + chainId?: Hex; chainName: string; nativeCurrency?: NativeCurrencyType; rpcUrls?: string[]; @@ -38,8 +40,8 @@ export type ContractType = { diamond: boolean; _id: string; title: string; - blockchain: BlockchainType; - contractAddress: string; + blockchain: Hex; + contractAddress: Hex; external?: boolean; }; @@ -54,7 +56,7 @@ export type NFTSelectedNumberResponseType = { }; export type TContractSchema = { - blockchain: BlockchainType; + blockchain: Hex; contractAddress: string; diamond: boolean; title: string; @@ -79,26 +81,3 @@ export type Settings = { favicon?: string; databaseResales?: Boolean; }; - -export type BlockchainSetting = { - hash?: BlockchainType; - display?: Boolean; - sync?: Boolean; - name?: string; - - diamondFactoryAddress?: string; - classicFactoryAddress?: string; - diamondMarketplaceAddress?: string; - licenseExchangeAddress?: string; - mainTokenAddress?: string; - rpcEndpoint?: string; - blockExplorerGateway?: string; - numericalId?: number; - testnet?: Boolean; - symbol?: string; - - _id?: string; - isNew?: boolean; - - image?: string; -}; diff --git a/rair-front/src/components/adminViews/transferTokens.tsx b/rair-front/src/components/adminViews/transferTokens.tsx index dc0568b04..33cdbfa6c 100644 --- a/rair-front/src/components/adminViews/transferTokens.tsx +++ b/rair-front/src/components/adminViews/transferTokens.tsx @@ -1,36 +1,28 @@ import { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; -import { constants, Contract, utils } from 'ethers'; +import { Contract, isAddress, ZeroAddress } from 'ethers'; +import { Hex } from 'viem'; -import { - BlockchainSetting, - ContractDataType, - ContractsResponseType -} from './adminView.types'; -import useServerSettings from './useServerSettings'; +import { ContractDataType, ContractsResponseType } from './adminView.types'; import { TTokenData } from '../../axios.responseTypes'; import { diamondFactoryAbi, erc721Abi } from '../../contracts'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; +import useContracts from '../../hooks/useContracts'; +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; import useSwal from '../../hooks/useSwal'; import useWeb3Tx from '../../hooks/useWeb3Tx'; import { rFetch } from '../../utils/rFetch'; -import { TChainData } from '../../utils/utils.types'; import { OptionsType } from '../common/commonTypes/InputSelectTypes.types'; import InputField from '../common/InputField'; import InputSelect from '../common/InputSelect'; const TransferTokens = () => { - const { currentChain, currentUserAddress, contractCreator } = useSelector< - RootState, - ContractsInitialType - >((store) => store.contractStore); - const { primaryButtonColor, textColor, secondaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { connectedChain, currentUserAddress } = useAppSelector( + (store) => store.web3 + ); + const { primaryButtonColor, textColor, secondaryButtonColor } = + useAppSelector((store) => store.colors); + const { getBlockchainData } = useServerSettings(); const [traderRole, setTraderRole] = useState(); const [manualAddress, setManualAddress] = useState(false); @@ -50,14 +42,12 @@ const TransferTokens = () => { const [targetAddress, setTargetAddress] = useState(''); const [allTokensFilter, setAllTokensFilter] = useState(true); - const [contractBlockchain, setContractBlockchain] = useState< - BlockchainSetting & TChainData - >(); + const [contractBlockchain, setContractBlockchain] = useState(); const [contractInstance, setContractInstance] = useState< Contract | undefined >(); - const { getBlockchainData } = useServerSettings(); + const { contractCreator } = useContracts(); const reactSwal = useSwal(); const { web3TxHandler, web3Switch, correctBlockchain } = useWeb3Tx(); @@ -93,12 +83,13 @@ const TransferTokens = () => { }, [getUserContracts]); const connectAddressManual = async () => { - if (currentChain === undefined) return; + if (connectedChain === undefined) return; if (selectedContract === '') return; + if (!isAddress(selectedContract)) return; let instance; try { instance = contractCreator?.( - selectedContract, + selectedContract as Hex, manualDiamond ? diamondFactoryAbi : erc721Abi ); } catch (err) { @@ -109,7 +100,7 @@ const TransferTokens = () => { 'name', [], { - intendedBlockchain: currentChain, + intendedBlockchain: connectedChain, failureMessage: 'Unable to connect to the contract, please verify the address, blockchain and type of the contract' } @@ -119,9 +110,9 @@ const TransferTokens = () => { if (name !== false && typeof name === 'string') { setContractData({ title: name, - contractAddress: instance.address + contractAddress: await instance.getAddress() }); - setContractBlockchain(getBlockchainData(currentChain)); + setContractBlockchain(getBlockchainData(connectedChain)); setContractInstance(instance); } else { return; @@ -161,9 +152,12 @@ const TransferTokens = () => { setContractBlockchain( getBlockchainData(selectedBlockchain as `0x${string}`) ); - if (correctBlockchain(selectedBlockchain as BlockchainType)) { + if ( + correctBlockchain(selectedBlockchain as Hex) && + isAddress(contractAddress) + ) { const instance = contractCreator?.( - contractAddress, + contractAddress as Hex, response1.contract.diamond ? diamondFactoryAbi : erc721Abi ); setContractInstance(instance); @@ -300,7 +294,7 @@ const TransferTokens = () => {
    - - {collectionsData && ( -
    -
    -
    Minter Marketplace
    - - {offerCount} Offers found -
    - with {salesCount} price ranges! -
    -
    -
    - {collectionsData.map((item, index) => { - return ( - - ); - })} -
    - )} -
    - ); -}; - -export default ConsumerMode; diff --git a/rair-front/src/components/creatorAndConsumerModes.types.ts b/rair-front/src/components/creatorAndConsumerModes.types.ts index 485a59425..186399276 100644 --- a/rair-front/src/components/creatorAndConsumerModes.types.ts +++ b/rair-front/src/components/creatorAndConsumerModes.types.ts @@ -1,11 +1,5 @@ import { ethers } from 'ethers'; -import { ContractContents } from '../ducks/contracts/contracts.types'; - -export interface IConsumerMode { - addresses: ContractContents | undefined; -} - export type TSingleOfferDataObject = { contractAddress: string; productIndex: string; diff --git a/rair-front/src/components/creatorStudio/BannerCollection.tsx b/rair-front/src/components/creatorStudio/BannerCollection.tsx index c18f58002..3e9a79013 100644 --- a/rair-front/src/components/creatorStudio/BannerCollection.tsx +++ b/rair-front/src/components/creatorStudio/BannerCollection.tsx @@ -1,18 +1,15 @@ import { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import { faPlus } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import Swal from 'sweetalert2'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useSwal from '../../hooks/useSwal'; import { rFetch } from '../../utils/rFetch'; import { changeIPFSLink } from '../MockUpPage/NftList/utils/changeIPFSLink'; export const BannerCollection = ({ item, getContractData }) => { - const { primaryColor } = useSelector( - (store) => store.colorStore - ); + const { primaryColor } = useAppSelector((store) => store.colors); + const rSwal = useSwal(); const [fileUpload, setFileUpload] = useState(); const [loadingBg, setLoadingBg] = useState(false); @@ -26,7 +23,7 @@ export const BannerCollection = ({ item, getContractData }) => { if (fileF.type !== 'video/mp4') { setFileUpload(fileF); } else { - Swal.fire( + rSwal.fire( 'Info', `You cannot upload video to background!`, 'warning' @@ -37,7 +34,7 @@ export const BannerCollection = ({ item, getContractData }) => { reader.readAsDataURL(fileF); } }, - [setFileUpload] + [setFileUpload, rSwal] ); const editBackground = useCallback(async () => { diff --git a/rair-front/src/components/creatorStudio/ContractDetails.tsx b/rair-front/src/components/creatorStudio/ContractDetails.tsx index ef0fdf146..692fc6dc4 100644 --- a/rair-front/src/components/creatorStudio/ContractDetails.tsx +++ b/rair-front/src/components/creatorStudio/ContractDetails.tsx @@ -1,6 +1,7 @@ import { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import { useParams } from 'react-router-dom'; +import { isAddress } from 'ethers'; +import { Hex } from 'viem'; import { TContractsNetworkContract, @@ -13,13 +14,12 @@ import FixedBottomNavigation from './FixedBottomNavigation'; import NavigatorContract from './NavigatorContract'; import { diamond721Abi, erc721Abi } from '../../contracts'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; +import useContracts from '../../hooks/useContracts'; +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; import useSwal from '../../hooks/useSwal'; import useWeb3Tx from '../../hooks/useWeb3Tx'; import { rFetch } from '../../utils/rFetch'; -import useServerSettings from '../adminViews/useServerSettings'; import InputField from '../common/InputField'; const ContractDetails = () => { @@ -31,14 +31,11 @@ const ContractDetails = () => { const { getBlockchainData } = useServerSettings(); - const { primaryColor, secondaryColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); - const { contractCreator, currentChain } = useSelector< - RootState, - ContractsInitialType - >((store) => store.contractStore); + const { primaryColor, secondaryColor } = useAppSelector( + (store) => store.colors + ); + const { connectedChain } = useAppSelector((store) => store.web3); + const { contractCreator } = useContracts(); const { address, blockchain } = useParams(); const [data, setData] = useState(); @@ -62,9 +59,9 @@ const ContractDetails = () => { } setData(dataRequest.contract); setIsDiamond(dataRequest.contract.diamond); - } else if (contractCreator) { + } else if (contractCreator && isAddress(address)) { // Try diamonds - const instance = contractCreator(address, diamond721Abi); + const instance = contractCreator(address as Hex, diamond721Abi); if (instance) { const productCount = Number( (await instance.getProductCount()).toString() @@ -73,12 +70,12 @@ const ContractDetails = () => { setData({ title: await instance?.name(), contractAddress: address, - blockchain: currentChain, + blockchain: connectedChain, products: Array(productCount) }); } } - }, [address, blockchain, contractCreator, currentChain]); + }, [address, blockchain, contractCreator, connectedChain]); useEffect(() => { getContractData(); @@ -161,9 +158,9 @@ const ContractDetails = () => { } if (!correctBlockchain(data.blockchain)) { web3Switch(data.blockchain); - } else { + } else if (isAddress(data?.contractAddress)) { const instance = await contractCreator?.( - data?.contractAddress, + data.contractAddress as Hex, isDiamond ? diamond721Abi : erc721Abi ); if (!instance) { diff --git a/rair-front/src/components/creatorStudio/Contracts.tsx b/rair-front/src/components/creatorStudio/Contracts.tsx index b16b33f98..7b588a8c5 100644 --- a/rair-front/src/components/creatorStudio/Contracts.tsx +++ b/rair-front/src/components/creatorStudio/Contracts.tsx @@ -1,59 +1,49 @@ import { useCallback, useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; import { NavLink } from 'react-router-dom'; -import { faArrowRight, faGem, faVial } from '@fortawesome/free-solid-svg-icons'; +import { + faArrowRight, + faEyeSlash, + faGem, + faLinkSlash, + faVial +} from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Hex } from 'viem'; -import { TContractsArray } from './creatorStudio.types'; import NavigatorFactory from './NavigatorFactory'; -import { RootState } from '../../ducks'; -import { getTokenError } from '../../ducks/auth/actions'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; +import { Contract } from '../../types/databaseTypes'; import { rFetch } from '../../utils/rFetch'; import setDocumentTitle from '../../utils/setTitle'; -import { ContractType } from '../adminViews/adminView.types'; -import useServerSettings from '../adminViews/useServerSettings'; import InputField from '../common/InputField'; const Contracts = () => { - const dispatch = useDispatch(); const [titleSearch, setTitleSearch] = useState(''); - const [contractArray, setContractArray] = useState(); + const [contractArray, setContractArray] = useState>([]); const [diamondFilter, setDiamondFilter] = useState(false); - const [chainFilter, setChainFilter] = useState([]); - const { programmaticProvider } = useSelector( - (store) => store.contractStore - ); + const [chainFilter, setChainFilter] = useState([]); + const { programmaticProvider } = useAppSelector((store) => store.web3); const { primaryColor, secondaryColor, textColor, primaryButtonColor, iconColor - } = useSelector((store) => store.colorStore); + } = useAppSelector((store) => store.colors); - const { blockchainSettings, getBlockchainData } = useServerSettings(); + const { blockchainSettings } = useAppSelector((store) => store.settings); + const { getBlockchainData } = useServerSettings(); const fetchContracts = useCallback(async () => { const response = await rFetch('/api/contracts/factoryList', undefined, { provider: programmaticProvider }); if (response.success) { - setContractArray( - response.contracts.map((item: ContractType) => ({ - address: item.contractAddress, - name: item.title, - blockchain: item.blockchain, - diamond: item.diamond - })) - ); - } - if (response.error && response.message) { - dispatch(getTokenError(response.error)); + setContractArray(response.contracts); } - }, [programmaticProvider, dispatch]); + }, [programmaticProvider]); useEffect(() => { fetchContracts(); @@ -89,8 +79,9 @@ const Contracts = () => { Only Diamonds {blockchainSettings - .filter((chain) => chain.display !== true && chain.hash) + .filter((chain) => chain.display === true && chain.hash) .map((chain, index) => { + const chainData = getBlockchainData(chain.hash); return ( )} - {factoryInstance && diamondFactoryInstance && false && ( + {classicFactoryInstance && diamondFactoryInstance && false && (
    or
    )} {diamondFactoryInstance && (
    @@ -312,15 +204,14 @@ const ListOffers: React.FC = ({ forwardFunctions={[ !onMyChain ? { - action: () => - web3Switch(contractData?.blockchain as BlockchainType), - label: `Switch to ${getBlockchainData( - contractData?.blockchain - )?.name}` + action: () => web3Switch(contractData?.blockchain as Hex), + label: `Switch to ${ + getBlockchainData(contractData?.blockchain)?.name + }` } : mintingRole === true ? { - action: offerList[0]?.fixed ? appendOffers : createOffers, + action: undefined, label: offerList[0]?.fixed ? 'Append to offer' : 'Create new offers', @@ -333,7 +224,7 @@ const ListOffers: React.FC = ({ emptyNames } : { - action: giveMinterRole, + action: undefined, label: 'Connect to Minter Marketplace' }, { diff --git a/rair-front/src/components/creatorStudio/creatorSteps/MediaUpload.tsx b/rair-front/src/components/creatorStudio/creatorSteps/MediaUpload.tsx index 8bd511129..2f138011c 100644 --- a/rair-front/src/components/creatorStudio/creatorSteps/MediaUpload.tsx +++ b/rair-front/src/components/creatorStudio/creatorSteps/MediaUpload.tsx @@ -1,36 +1,30 @@ import React, { useCallback, useEffect, useState } from 'react'; import Dropzone from 'react-dropzone'; -import { useSelector } from 'react-redux'; import { useParams } from 'react-router-dom'; import WorkflowContext from '../../../contexts/CreatorWorkflowContext'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../../ducks/contracts/contracts.types'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; import videoIcon from '../../../images/videoIcon.svg'; +import { UploadMediaFile } from '../../../types/commonTypes'; import { rFetch } from '../../../utils/rFetch'; import LoadingComponent from '../../common/LoadingComponent'; import MediaListBox from '../../DemoMediaUpload/MediaListBox/MediaListBox'; import UploadedListBox from '../../DemoMediaUpload/UploadedListBox/UploadedListBox'; -import { IMediaUpload, TMediaType } from '../creatorStudio.types'; +import { IMediaUpload } from '../creatorStudio.types'; const MediaUpload: React.FC = ({ setStepNumber, contractData, stepNumber }) => { - const { primaryColor, textColor } = useSelector( - (store) => store.colorStore - ); + const { primaryColor, textColor } = useAppSelector((store) => store.colors); const { address, collectionIndex } = useParams(); - const { currentUserAddress } = useSelector( - (store) => store.contractStore - ); + const { currentUserAddress } = useAppSelector((store) => store.web3); const [loading, setLoading] = useState(false); const [mediaUploadedList, setMediaUploadedList] = useState([]); - const [mediaList, setMediaList] = useState([]); + const [mediaList, setMediaList] = useState([]); const [uploadSuccess, setUploadSuccess] = useState(null); const selectCommonInfo = { @@ -45,7 +39,7 @@ const MediaUpload: React.FC = ({ }; const onMediaDrop = (media) => { - let aux: TMediaType[] = [...mediaList]; + let aux = [...mediaList]; aux = aux.concat( media.map((item: File) => { return { @@ -74,15 +68,12 @@ const MediaUpload: React.FC = ({ [mediaList] ); - const getMediaList = async () => { - if ( - currentUserAddress !== undefined && - contractData?.nfts?.tokens?.at(0)?._id - ) { + const getMediaList = useCallback(async () => { + if (currentUserAddress !== undefined && contractData?.nfts?.at(0)?._id) { setLoading(true); try { const { success, data } = await rFetch( - `/api/files/forToken/${contractData?.nfts?.tokens[0]._id}` + `/api/files/forToken/${contractData.nfts.at(0)?._id}` ); if (success && contractData) { setMediaUploadedList(data.map((unlock) => unlock.file)); @@ -92,17 +83,15 @@ const MediaUpload: React.FC = ({ } setLoading(false); } - }; + }, [contractData, currentUserAddress]); useEffect(() => { - setStepNumber(stepNumber); + setStepNumber?.(stepNumber); }, [setStepNumber, stepNumber]); useEffect(() => { - if (!currentUserAddress) return; getMediaList(); - // eslint-disable-next-line - }, [currentUserAddress]); + }, [getMediaList]); return (
    diff --git a/rair-front/src/components/creatorStudio/creatorSteps/OfferRow.tsx b/rair-front/src/components/creatorStudio/creatorSteps/OfferRow.tsx index 0c177cc9a..2991ae764 100644 --- a/rair-front/src/components/creatorStudio/creatorSteps/OfferRow.tsx +++ b/rair-front/src/components/creatorStudio/creatorSteps/OfferRow.tsx @@ -1,11 +1,9 @@ import { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import { faKey, faTrash } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { utils } from 'ethers'; +import { formatEther } from 'ethers'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; import { validateInteger } from '../../../utils/metamaskUtils'; import colors from '../../../utils/offerLockColors'; import InputField from '../../common/InputField'; @@ -24,10 +22,9 @@ const OfferRow: React.FC = ({ maxCopies, blockchainSymbol }) => { - const { primaryColor, secondaryColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { primaryColor, secondaryColor } = useAppSelector( + (store) => store.colors + ); const [itemName, setItemName] = useState(name); const [startingToken, setStartingToken] = useState(starts); @@ -184,14 +181,12 @@ const OfferRow: React.FC = ({ - {utils - .formatEther( - individualPrice === '' || - !validateInteger(Number(individualPrice)) - ? 0 - : individualPrice - ) - .toString()}{' '} + {formatEther( + individualPrice === '' || + !validateInteger(Number(individualPrice)) + ? 0 + : individualPrice + ).toString()}{' '} {blockchainSymbol} diff --git a/rair-front/src/components/creatorStudio/creatorSteps/ResaleMarketplace.tsx b/rair-front/src/components/creatorStudio/creatorSteps/ResaleMarketplace.tsx index 790304bf5..ba60a0b39 100644 --- a/rair-front/src/components/creatorStudio/creatorSteps/ResaleMarketplace.tsx +++ b/rair-front/src/components/creatorStudio/creatorSteps/ResaleMarketplace.tsx @@ -1,16 +1,15 @@ import { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import { faPlus } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { BigNumber, utils } from 'ethers'; +import { isAddress } from 'ethers'; +import { Hex } from 'viem'; import WorkflowContext from '../../../contexts/CreatorWorkflowContext'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../../ducks/contracts/contracts.types'; +import useContracts from '../../../hooks/useContracts'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; +import useServerSettings from '../../../hooks/useServerSettings'; import useSwal from '../../../hooks/useSwal'; import useWeb3Tx from '../../../hooks/useWeb3Tx'; -import useServerSettings from '../../adminViews/useServerSettings'; import InputField from '../../common/InputField'; import CustomFeeRow from '../common/customFeeRow'; import { TCustomPayments, TResaleMarketplace } from '../creatorStudio.types'; @@ -22,14 +21,10 @@ const CustomizeFees: React.FC = ({ stepNumber, gotoNextStep }) => { - const { textColor, primaryColor, primaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); - const { diamondMarketplaceInstance } = useSelector< - RootState, - ContractsInitialType - >((store) => store.contractStore); + const { textColor, primaryColor, primaryButtonColor } = useAppSelector( + (store) => store.colors + ); + const { diamondMarketplaceInstance } = useContracts(); const { getBlockchainData } = useServerSettings(); @@ -39,18 +34,23 @@ const CustomizeFees: React.FC = ({ const [customPayments, setCustomPayments] = useState([]); const [approving, setApproving] = useState(false); const [rerender, setRerender] = useState(false); - const [resaleAddress, setResaleAddress] = useState( - diamondMarketplaceInstance?.address || '' - ); - const [nodeFee, setNodeFee] = useState(BigNumber.from(0)); - const [treasuryFee, setTreasuryFee] = useState(BigNumber.from(0)); - const [minterDecimals, setMinterDecimals] = useState( - BigNumber.from(0) - ); - const [precisionFactor, setPrecisionFactor] = useState( - BigNumber.from(10) - ); + const [nodeFee, setNodeFee] = useState(BigInt(0)); + const [treasuryFee, setTreasuryFee] = useState(BigInt(0)); + const [minterDecimals, setMinterDecimals] = useState(BigInt(0)); + const [precisionFactor, setPrecisionFactor] = useState(BigInt(10)); const [sendingData, setSendingData] = useState(false); + const [resaleAddress, setResaleAddress] = useState(''); + + const updateMarketAddress = useCallback(async () => { + if (!diamondMarketplaceInstance) { + return; + } + setResaleAddress(await diamondMarketplaceInstance.getAddress()); + }, [diamondMarketplaceInstance]); + + useEffect(() => { + updateMarketAddress(); + }, [updateMarketAddress]); const getContractData = useCallback(async () => { if (!diamondMarketplaceInstance) { @@ -60,7 +60,7 @@ const CustomizeFees: React.FC = ({ if (nodeFeeData) { setNodeFee(nodeFeeData.nodeFee); setMinterDecimals(nodeFeeData.decimals); - setPrecisionFactor(BigNumber.from(10).pow(nodeFeeData.decimals)); + setPrecisionFactor(BigInt(10) ** BigInt(nodeFeeData.decimals)); } const treasuryFeeData = await diamondMarketplaceInstance.getTreasuryFee(); if (treasuryFeeData) { @@ -132,16 +132,12 @@ const CustomizeFees: React.FC = ({ const validatePaymentData = () => { if (customPayments.length) { let valid = true; - let total = BigNumber.from(0); + let total = BigInt(0); for (const payment of customPayments) { - valid = valid && utils.isAddress(payment.recipient || ''); - total = total.add(payment.percentage); + valid = valid && isAddress(payment.recipient || ''); + total = total + BigInt(payment.percentage); } - if ( - BigNumber.from(90) - .mul(precisionFactor) - .gte(total.add(nodeFee).add(treasuryFee)) - ) { + if (BigInt(90) * precisionFactor >= total + nodeFee + treasuryFee) { return valid; } } @@ -149,8 +145,8 @@ const CustomizeFees: React.FC = ({ }; const total = customPayments.reduce((prev, current) => { - return prev.add(current.percentage); - }, BigNumber.from(0)); + return prev + current.percentage; + }, BigInt(0)); return (
    {contractData && customPayments?.length !== 0 && ( @@ -180,29 +176,27 @@ const CustomizeFees: React.FC = ({ )} - {nodeFee && treasuryFee && minterDecimals && ( + {!!nodeFee && !!treasuryFee && !!minterDecimals && (
    - Node Fee: {BigNumber.from(nodeFee).div(precisionFactor).toString()} + Node Fee: {(BigInt(nodeFee) / precisionFactor).toString()} %
    Treasury Fee: - {BigNumber.from(treasuryFee).div(precisionFactor).toString()} + {(BigInt(treasuryFee) / precisionFactor).toString()} %
    Total:{' '} - {total - .add(nodeFee) - .add(treasuryFee) - .div(BigNumber.from(10).pow(minterDecimals)) - .toString()} + {( + (total + nodeFee + treasuryFee) / + BigInt(10) ** minterDecimals + ).toString()} %
    Percentage left for the seller:{' '} - {BigNumber.from(100) - .mul(precisionFactor) - .sub(total.add(nodeFee).add(treasuryFee)) - .div(BigNumber.from(10).pow(minterDecimals)) - .toString()} + {( + (BigInt(100) * precisionFactor - (total + nodeFee + treasuryFee)) / + BigInt(10) ** minterDecimals + ).toString()} %
    @@ -237,7 +231,7 @@ const CustomizeFees: React.FC = ({ />
    -
    - -
    -
    - +
    +
    + +
    +
    + +

    Image @@ -313,6 +318,10 @@ const SingleMetadataEditor: React.FC = ({ value={nftDescription} onChange={(e) => setNFTDescription(e.target.value)} className={`rounded-rair w-100 form-control`} + style={{ + background: primaryColor, + color: textColor + }} rows={3} />
    @@ -394,12 +403,13 @@ const SingleMetadataEditor: React.FC = ({ forwardFunctions={[ { action: !onMyChain - ? () => web3Switch(contractData?.blockchain as BlockchainType) + ? () => web3Switch(contractData?.blockchain as Hex) : pinMetadata, label: !onMyChain ? contractData?.blockchain - ? `Switch to ${getBlockchainData(contractData?.blockchain) - ?.name}` + ? `Switch to ${ + getBlockchainData(contractData?.blockchain)?.name + }` : '' : 'Pin to IPFS', disabled: false diff --git a/rair-front/src/components/creatorStudio/creatorStudio.types.ts b/rair-front/src/components/creatorStudio/creatorStudio.types.ts index 9f2c628c6..aa238de5e 100644 --- a/rair-front/src/components/creatorStudio/creatorStudio.types.ts +++ b/rair-front/src/components/creatorStudio/creatorStudio.types.ts @@ -1,23 +1,24 @@ import { MouseEvent } from 'react'; import { ReactNode } from 'react'; -import { BigNumber, ethers } from 'ethers'; +import { ethers } from 'ethers'; +import { Hex } from 'viem'; import { TAttributes, - TContract, - TNftItemResult, TOfferPool, TProducts, TTokenData } from '../../axios.responseTypes'; +import { CatalogItem } from '../../redux/tokenSlice'; +import { MediaFile } from '../../types/databaseTypes'; import { ContractType } from '../adminViews/adminView.types'; import { OptionsType } from '../common/commonTypes/InputSelectTypes.types'; export interface IMarketplaceOfferConfig { array: TMarketplaceOfferConfigArrayItem[]; index: number; - nodeFee: BigNumber; + nodeFee: bigint; minterDecimals: number; - treasuryFee: BigNumber; + treasuryFee: bigint; treasuryAddress: string; simpleMode: boolean; rerender: () => void; @@ -55,11 +56,11 @@ export interface ICustomFeeRow { recipient: string | undefined; canBeContract: boolean; deleter: (index: number) => void; - percentage: BigNumber; + percentage: bigint; rerender: () => void; editable: boolean; message?: string; - minterDecimals: BigNumber; + minterDecimals: bigint; disabled?: boolean; marketValuesChanged?: boolean; setMarketValuesChanged?: (value: boolean) => void; @@ -79,7 +80,7 @@ export interface ITokenURIRow { export interface IIBlockchainURIManager { contractData: TContractData; collectionIndex: string; - refreshNFTMetadata: () => Promise; + refreshNFTMetadata: () => Promise; changeFile: boolean; } export type TParamsBatchMetadata = { @@ -89,7 +90,7 @@ export type TParamsBatchMetadata = { export type TCustomPayments = { recipient: string | undefined; - percentage: BigNumber; + percentage: bigint; editable: boolean; message?: string; canBeContract: boolean; @@ -161,9 +162,9 @@ export type TWorkflowProduct = TProducts & { tokenLock: TTokenLock | undefined; }; -export type TContractData = Omit & { +export type TContractData = Omit & { instance: ethers.Contract; - nfts: TNftItemResult; + nfts: TTokenData[]; product: TWorkflowProduct; }; @@ -189,11 +190,10 @@ export type TWorkflowContextType = { mintingRole: boolean | undefined; traderRole: boolean | undefined; onMyChain: boolean | undefined; - correctMinterInstance: ethers.Contract | undefined; tokenInstance: ethers.Contract | TContractData | undefined; simpleMode: boolean; forceRefetch: () => void; - refreshNFTMetadata: () => Promise; + refreshNFTMetadata: () => Promise; fetchingData: boolean; }; @@ -206,20 +206,20 @@ export type TListOffersProductType = Omit & { offers: TMarketplaceOfferConfigArrayItem[]; }; -export type TDiamondContractData = Omit & +export type TDiamondContractData = Omit & TMetadataExtra & { instance: ethers.Contract; - nfts: TNftItemResult; + nfts: TTokenData[]; product: TListOffersProductType; }; export type TParamsListLocks = { - address: string; + address: Hex; }; export interface IMediaUpload { - setStepNumber: Function; - contractData: TContractData | undefined; - stepNumber: number; + setStepNumber?: Function; + contractData?: TContractData | TDiamondContractData | undefined; + stepNumber?: number; } export type TSteps = { @@ -235,20 +235,6 @@ export type TSteps = { description: string; }; -export type TMediaType = { - id(contractAddress: string, id: any): void; - category: string; - contractAddress: string; - description: string; - file: File; - offer: string; - preview: string; - productIndex: string; - storage: string; - title: string; - demo: boolean; -}; - export type TChoiceAllOptions = { contract: string; product: string; @@ -261,12 +247,12 @@ export type TCategories = { }; export interface IMediaUploadRow { - item: TMediaType; + item: MediaFile; offerList: OptionsType[]; deleter: () => void; rerender: () => void; index: number; - array: TMediaType[]; + array: MediaFile[]; categoriesArray: OptionsType[]; } @@ -328,12 +314,7 @@ export type TNextToken = Pick< >; export type TResaleMarketplace = Pick< TWorkflowContextType, - | 'contractData' - | 'correctMinterInstance' - | 'setStepNumber' - | 'gotoNextStep' - | 'goBack' - | 'simpleMode' + 'contractData' | 'setStepNumber' | 'gotoNextStep' | 'goBack' | 'simpleMode' > & { stepNumber: number; }; @@ -345,7 +326,7 @@ export interface IBatchMetadataParser { gotoNextStep: () => void; goBack: () => void; simpleMode: boolean; - refreshNFTMetadata: () => Promise; + refreshNFTMetadata: () => Promise; } export interface ICustomizeFees { @@ -425,8 +406,8 @@ export type TNftMapping = { }; export type TParamsContractDetails = { - address: string; - blockchain: BlockchainType; + address: Hex; + blockchain: Hex; }; export type TWorkflowParams = TParamsContractDetails & { @@ -436,7 +417,7 @@ export type TWorkflowParams = TParamsContractDetails & { export type TSetData = { title: string; contractAddress: string; - blockchain: BlockchainType | undefined; + blockchain: Hex | undefined; products: TProducts[]; }; @@ -452,8 +433,8 @@ export type IForwardFunctions = { }; export type TContractsNetworkContract = { - blockchain: BlockchainType | undefined; - contractAddress: string; + blockchain: Hex | undefined; + contractAddress: Hex; creationDate: string; diamond: boolean; external: boolean; @@ -496,7 +477,7 @@ export type TProductDataLocal = { export type TSetDataUseState = { title: string; contractAddress: string; - blockchain: BlockchainType | undefined; + blockchain: Hex | undefined; products: TProductDataLocal[]; }; @@ -508,7 +489,7 @@ export interface INavigatorContract { children: ReactNode; contractAddress: string; contractName: string; - contractBlockchain: BlockchainType | undefined; + contractBlockchain: Hex | undefined; contractProducts?: any; } @@ -536,6 +517,6 @@ export type TApiContractsResponseType = { export type TContractsArray = { address: string; name: string; - blockchain: BlockchainType | undefined; + blockchain: Hex | undefined; diamond: boolean; }; diff --git a/rair-front/src/components/creatorStudio/diamondCreatorSteps/DiamondMinterMarketplace.tsx b/rair-front/src/components/creatorStudio/diamondCreatorSteps/DiamondMinterMarketplace.tsx index 76fa62c00..79bb0a0dd 100644 --- a/rair-front/src/components/creatorStudio/diamondCreatorSteps/DiamondMinterMarketplace.tsx +++ b/rair-front/src/components/creatorStudio/diamondCreatorSteps/DiamondMinterMarketplace.tsx @@ -1,12 +1,9 @@ import React, { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; -import { BigNumber } from 'ethers'; import MarketplaceOfferConfig from './MarketplaceOfferConfig'; import WorkflowContext from '../../../contexts/CreatorWorkflowContext'; -import { RootState } from '../../../ducks'; -import { ContractsInitialType } from '../../../ducks/contracts/contracts.types'; +import useContracts from '../../../hooks/useContracts'; import useSwal from '../../../hooks/useSwal'; import useWeb3Tx from '../../../hooks/useWeb3Tx'; import { @@ -26,18 +23,15 @@ const DiamondMinterMarketplace: React.FC = ({ //handleMinterRole, forceRefetch }) => { - const { diamondMarketplaceInstance } = useSelector< - RootState, - ContractsInitialType - >((store) => store.contractStore); + const { diamondMarketplaceInstance } = useContracts(); const reactSwal = useSwal(); const { web3TxHandler } = useWeb3Tx(); const [offerData, setOfferData] = useState< TMarketplaceOfferConfigArrayItem[] >([]); - const [nodeFee, setNodeFee] = useState(BigNumber.from(0)); - const [treasuryFee, setTreasuryFee] = useState(BigNumber.from(0)); + const [nodeFee, setNodeFee] = useState(BigInt(0)); + const [treasuryFee, setTreasuryFee] = useState(BigInt(0)); const [treasuryAddress, setTreasuryAddress] = useState( undefined ); @@ -67,7 +61,7 @@ const DiamondMinterMarketplace: React.FC = ({ if (!diamondMarketplaceInstance) { return; } - if (nodeFee.eq(0) && minterDecimals === 0) { + if (nodeFee === BigInt(0) && minterDecimals === 0) { const nodeFeeData = await web3TxHandler( diamondMarketplaceInstance, 'getNodeFee' @@ -77,7 +71,7 @@ const DiamondMinterMarketplace: React.FC = ({ setMinterDecimals(nodeFeeData.decimals); } } - if (treasuryFee.eq(0)) { + if (treasuryFee === BigInt(0)) { const treasuryFeeData = await web3TxHandler( diamondMarketplaceInstance, 'getTreasuryFee' @@ -125,8 +119,8 @@ const DiamondMinterMarketplace: React.FC = ({ await web3TxHandler(diamondMarketplaceInstance, 'addMintingOfferBatch', [ contractData?.contractAddress, filteredOffers?.map((item) => item.diamondRangeIndex), - filteredOffers?.map( - (item) => item.customSplits?.filter((split) => split.editable) + filteredOffers?.map((item) => + item.customSplits?.filter((split) => split.editable) ), filteredOffers?.map((item) => item.marketData.visible), import.meta.env.VITE_NODE_ADDRESS @@ -158,7 +152,7 @@ const DiamondMinterMarketplace: React.FC = ({ MINTERHash && (await web3TxHandler(contractData.instance, 'grantRole', [ MINTERHash, - diamondMarketplaceInstance?.address + await diamondMarketplaceInstance?.getAddress() ])) ) { reactSwal.fire({ diff --git a/rair-front/src/components/creatorStudio/diamondCreatorSteps/ListOffersDiamond.tsx b/rair-front/src/components/creatorStudio/diamondCreatorSteps/ListOffersDiamond.tsx index 05dd95dd6..28fd1dca2 100644 --- a/rair-front/src/components/creatorStudio/diamondCreatorSteps/ListOffersDiamond.tsx +++ b/rair-front/src/components/creatorStudio/diamondCreatorSteps/ListOffersDiamond.tsx @@ -1,17 +1,15 @@ import React, { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import { useParams } from 'react-router-dom'; -import { faPlus } from '@fortawesome/free-solid-svg-icons'; +import { faPlusCircle } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import DiamondOfferRow from './diamondOfferRow'; import WorkflowContext from '../../../contexts/CreatorWorkflowContext'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; +import useServerSettings from '../../../hooks/useServerSettings'; import useSwal from '../../../hooks/useSwal'; import useWeb3Tx from '../../../hooks/useWeb3Tx'; -import useServerSettings from '../../adminViews/useServerSettings'; import { TAddDiamondOffer, TListOffers, @@ -41,7 +39,7 @@ const ListOffers: React.FC = ({ const { getBlockchainData } = useServerSettings(); const { primaryColor, textColor, primaryButtonColor, secondaryColor } = - useSelector((store) => store.colorStore); + useAppSelector((store) => store.colors); const { collectionIndex } = useParams(); useEffect(() => { @@ -172,12 +170,7 @@ const ListOffers: React.FC = ({ className={`btn rair-button rounded-rair px-4`}> Add new{' '}
@@ -208,8 +201,9 @@ const ListOffers: React.FC = ({ : createOffers : createOffers, label: !correctBlockchain(contractData.blockchain) - ? `Switch to ${getBlockchainData(contractData?.blockchain) - ?.name}` + ? `Switch to ${ + getBlockchainData(contractData?.blockchain)?.name + }` : offerList[0]?._id ? offerList.filter((item) => !item._id).length === 0 ? 'Continue' diff --git a/rair-front/src/components/creatorStudio/diamondCreatorSteps/MarketplaceOfferConfig.tsx b/rair-front/src/components/creatorStudio/diamondCreatorSteps/MarketplaceOfferConfig.tsx index 4172065f9..d3f134d28 100644 --- a/rair-front/src/components/creatorStudio/diamondCreatorSteps/MarketplaceOfferConfig.tsx +++ b/rair-front/src/components/creatorStudio/diamondCreatorSteps/MarketplaceOfferConfig.tsx @@ -1,5 +1,4 @@ import React, { useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import { faCheck, faEye, @@ -8,14 +7,13 @@ import { faTimes } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { BigNumber, utils } from 'ethers'; +import { formatEther } from 'ethers'; -import { RootState } from '../../../ducks'; -import { ColorStoreType } from '../../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../../ducks/contracts/contracts.types'; +import useContracts from '../../../hooks/useContracts'; +import { useAppSelector } from '../../../hooks/useReduxHooks'; +import useServerSettings from '../../../hooks/useServerSettings'; import useSwal from '../../../hooks/useSwal'; import useWeb3Tx from '../../../hooks/useWeb3Tx'; -import useServerSettings from '../../adminViews/useServerSettings'; import CustomFeeRow from '../common/customFeeRow'; import { IMarketplaceOfferConfig, @@ -34,14 +32,12 @@ const MarketplaceOfferConfig: React.FC = ({ enabled }) => { const item = array[index]; - const { currentUserAddress, diamondMarketplaceInstance, currentChain } = - useSelector( - (store) => store.contractStore - ); - const { textColor, primaryButtonColor, secondaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { diamondMarketplaceInstance } = useContracts(); + const { currentUserAddress, connectedChain } = useAppSelector( + (store) => store.web3 + ); + const { textColor, primaryButtonColor, secondaryButtonColor } = + useAppSelector((store) => store.colors); const [marketValuesChanged, setMarketValuesChanged] = useState(false); const reactSwal = useSwal(); @@ -66,9 +62,7 @@ const MarketplaceOfferConfig: React.FC = ({ { message: 'Creator address (You)', recipient: currentUserAddress, - percentage: BigNumber.from(10) - .pow(minterDecimals | 3) - .mul(95), + percentage: BigInt(10) ** BigInt(minterDecimals || 3) * BigInt(95), canBeContract: false, editable: true } @@ -96,7 +90,7 @@ const MarketplaceOfferConfig: React.FC = ({ ].concat( array[index].marketData.fees.map((fee: TCustomPayments) => ({ recipient: fee.recipient, - percentage: BigNumber.from(fee.percentage), + percentage: BigInt(fee.percentage), editable: true, canBeContract: false, message: 'Data from the marketplace' @@ -115,7 +109,7 @@ const MarketplaceOfferConfig: React.FC = ({ const aux = [...customPayments]; aux.push({ recipient: '', - percentage: BigNumber.from(0), + percentage: BigInt(0), canBeContract: false, editable: true }); @@ -142,8 +136,8 @@ const MarketplaceOfferConfig: React.FC = ({
{item.copies}
tokens available for{' '}
- {utils.formatEther(item.price)}{' '} - {currentChain && getBlockchainData(currentChain)?.symbol} + {formatEther(item.price)}{' '} + {connectedChain && getBlockchainData(connectedChain)?.symbol}
@@ -265,13 +259,13 @@ const MarketplaceOfferConfig: React.FC = ({ deleter={removePayment} {...{ rerender, - minterDecimals: BigNumber.from(minterDecimals | 3), + minterDecimals: BigInt(minterDecimals || 3), marketValuesChanged, setMarketValuesChanged, price: item.price, symbol: - currentChain && - getBlockchainData(currentChain)?.symbol + connectedChain && + getBlockchainData(connectedChain)?.symbol }} {...customPaymentItem} /> @@ -284,15 +278,17 @@ const MarketplaceOfferConfig: React.FC = ({
Total:{' '} - {BigNumber.from(total) - .div(Math.pow(10, minterDecimals | 3)) - ?.toString()} + {( + BigInt(total) / + BigInt(BigInt(10) ** BigInt(minterDecimals || 3)) + )?.toString()} %
)}
- {loggedIn && } + {isLoggedIn && }
); }; diff --git a/rair-front/src/components/layout/Layout.tsx b/rair-front/src/components/layout/Layout.tsx index 106bce66e..b7b2a8dec 100644 --- a/rair-front/src/components/layout/Layout.tsx +++ b/rair-front/src/components/layout/Layout.tsx @@ -1,14 +1,12 @@ import React from 'react'; -import { useSelector } from 'react-redux'; import { Link } from 'react-router-dom'; import { faSearch, faUser } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { ILayout } from './layout.types'; -import { RootState } from '../../ducks'; -import { TUsersInitialState } from '../../ducks/users/users.types'; import useConnectUser from '../../hooks/useConnectUser'; +import { useAppSelector } from '../../hooks/useReduxHooks'; import { metaMaskIcon } from '../../images'; import { headerLogoBlackMobile } from '../../images'; @@ -21,9 +19,7 @@ const Layout: React.FC = ({ children }) => { const { connectUserData } = useConnectUser(); - const { userData } = useSelector( - (store) => store.userStore - ); + const { isLoggedIn } = useAppSelector((store) => store.user); const items = [ { name: , route: '/search' }, { name: , route: '/user' }, @@ -64,7 +60,7 @@ const Layout: React.FC = ({ alt="Rair Tech Logo" />
- {!userData && account ? ( + {!isLoggedIn && account ? ( diff --git a/rair-front/src/components/layout/layout.types.ts b/rair-front/src/components/layout/layout.types.ts index 38c62807c..120f0da98 100644 --- a/rair-front/src/components/layout/layout.types.ts +++ b/rair-front/src/components/layout/layout.types.ts @@ -1,6 +1,8 @@ +import { Hex } from "viem"; + export interface ILayout { account: any; contractAddresses: any; - chainId: BlockchainType; + chainId: Hex; children: any[]; } diff --git a/rair-front/src/components/marketplace/BuyTokenModalContent.tsx b/rair-front/src/components/marketplace/BuyTokenModalContent.tsx index c9b0b64d7..2d1bf8cde 100644 --- a/rair-front/src/components/marketplace/BuyTokenModalContent.tsx +++ b/rair-front/src/components/marketplace/BuyTokenModalContent.tsx @@ -1,8 +1,7 @@ -import { useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; +import { useState } from 'react'; import { faMinus, faPlus } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { BigNumber, ethers, utils } from 'ethers'; +import { formatEther } from 'ethers'; import BatchRow from './BatchRow'; import { @@ -10,10 +9,8 @@ import { TBuyTokenModalContentType } from './marketplace.types'; -import { minterAbi } from '../../contracts'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; +import useContracts from '../../hooks/useContracts'; +import { useAppSelector } from '../../hooks/useReduxHooks'; import useSwal from '../../hooks/useSwal'; import useWeb3Tx from '../../hooks/useWeb3Tx'; import csvParser from '../../utils/csvParser'; @@ -27,7 +24,6 @@ const BuyTokenModalContent: React.FC = ({ offerIndex, rangeIndex, offerName, - minterAddress, diamonds, buyTokenFunction, buyTokenBatchFunction @@ -36,44 +32,31 @@ const BuyTokenModalContent: React.FC = ({ const [rows, setRows] = useState([]); const [batchMode, setBatchMode] = useState(false); - const [minterInstance, setMinterInstance] = useState< - ethers.Contract | undefined - >(); const [batchPage, setBatchPage] = useState(0); - const { contractCreator } = useSelector( - (state) => state.contractStore - ); - const { textColor, primaryButtonColor, secondaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { textColor, primaryButtonColor, secondaryButtonColor } = + useAppSelector((store) => store.colors); + const { diamondMarketplaceInstance } = useContracts(); const reactSwal = useSwal(); const { web3TxHandler } = useWeb3Tx(); const rowsLimit = 100; - useEffect(() => { - if (minterAddress) { - setMinterInstance(contractCreator?.(minterAddress, minterAbi)); - } - }, [minterAddress, contractCreator]); - const batchMint = async (data: TBatchMintDataType) => { - if (!minterInstance) { + if (!diamondMarketplaceInstance) { return; } const addresses = data.map((i) => i['Public Address']); const tokens = data.map((i) => i['NFTID']); if ( - await web3TxHandler(minterInstance, 'buyTokenBatch', [ + await web3TxHandler(diamondMarketplaceInstance, 'buyTokenBatch', [ offerIndex, rangeIndex, tokens, addresses, { - value: BigNumber.from(price).mul(tokens.length).toString() + value: (BigInt(price) * BigInt(tokens.length)).toString() } ]) ) { @@ -155,25 +138,24 @@ const BuyTokenModalContent: React.FC = ({ />
@@ -204,10 +186,7 @@ const BuyTokenModalContent: React.FC = ({ Add
- Total:{' '} - {utils.formatEther( - diamonds ? price.mul(rows.length) : price.mul(rows.length) - )} + Total: {formatEther(BigInt(price) * BigInt(rows.length))}
= ({ offerIndex, paginatedRows.map((item) => item['NFTID']), paginatedRows.map((item) => item['Public Address']), - price + BigInt(price) ); } else { batchMint(paginatedRows); } }} - disabled={!minterInstance || !paginatedRows.length} + disabled={!diamondMarketplaceInstance || !paginatedRows.length} style={{ background: primaryButtonColor, color: textColor diff --git a/rair-front/src/components/marketplace/MinterMarketplace.tsx b/rair-front/src/components/marketplace/MinterMarketplace.tsx index e56ac91bd..4aaa3a042 100644 --- a/rair-front/src/components/marketplace/MinterMarketplace.tsx +++ b/rair-front/src/components/marketplace/MinterMarketplace.tsx @@ -1,11 +1,11 @@ -import React, { useCallback, useEffect, useState } from 'react'; -import { BigNumber } from 'ethers'; +import { useCallback, useEffect, useState } from 'react'; import { TOfferData } from './marketplace.types'; import MinterMarketplaceItem from './MinterMarketplaceItem'; import { rFetch } from '../../utils/rFetch'; import setDocumentTitle from '../../utils/setTitle'; +import LoadingComponent from '../common/LoadingComponent'; const MinterMarketplace = () => { const [offerData, setOfferData] = useState([]); @@ -15,21 +15,19 @@ const MinterMarketplace = () => { if (aux.success) { const offerArray: TOfferData[] = []; aux.contracts.forEach((contract) => { - contract.products.offers.forEach((offer) => { + contract.product.offers.forEach((offer) => { for (const field of Object.keys(offer)) { if (offer && offer[field] && offer[field]['$numberDecimal']) { - offer[field] = BigNumber.from( - offer[field]['$numberDecimal'] - ).toString(); + offer[field] = BigInt(offer[field]['$numberDecimal']).toString(); } } if (!offer.sold) { offerArray.push({ blockchain: contract.blockchain, contractAddress: contract.contractAddress, - productIndex: contract.products.collectionIndexInContract, - productName: contract.products.name, - totalCopies: contract.products.copies, + productIndex: contract.product.collectionIndexInContract, + productName: contract.product.name, + totalCopies: contract.product.copies, minterAddress: contract?.offerPool?.minterAddress, ...offer }); @@ -48,6 +46,10 @@ const MinterMarketplace = () => { setDocumentTitle('Minter Marketplace'); }, []); + if (offerData.length === 0) { + return ; + } + return (
{offerData.map((item, index) => { diff --git a/rair-front/src/components/marketplace/MinterMarketplaceItem.tsx b/rair-front/src/components/marketplace/MinterMarketplaceItem.tsx index 956925abb..e72f0dba2 100644 --- a/rair-front/src/components/marketplace/MinterMarketplaceItem.tsx +++ b/rair-front/src/components/marketplace/MinterMarketplaceItem.tsx @@ -1,23 +1,21 @@ -import React from 'react'; -import { Provider, useSelector, useStore } from 'react-redux'; -import { BigNumber } from 'ethers'; +import { FC } from 'react'; +import { Provider, useStore } from 'react-redux'; import BuyTokenModalContent from './BuyTokenModalContent'; import { TMinterMarketplaceItemType } from './marketplace.types'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; import useSwal from '../../hooks/useSwal'; import useWeb3Tx from '../../hooks/useWeb3Tx'; -import useServerSettings from '../adminViews/useServerSettings'; -const MinterMarketplaceItem: React.FC = ({ +const MinterMarketplaceItem: FC = ({ item, index, colWidth }) => { const { primaryColor, secondaryColor, textColor, secondaryButtonColor } = - useSelector((state) => state.colorStore); + useAppSelector((state) => state.colors); const store = useStore(); const reactSwal = useSwal(); const { correctBlockchain } = useWeb3Tx(); @@ -67,9 +65,8 @@ const MinterMarketplaceItem: React.FC = ({ html: ( void; buyTokenBatchFunction?: ( offerIndex: string, tokens: number[], addresses: string[], - price: BigNumber + price: bigint ) => void; }; diff --git a/rair-front/src/components/nft/PersonalProfile/PersonalProfileBackground/PersonalProfileBackground.tsx b/rair-front/src/components/nft/PersonalProfile/PersonalProfileBackground/PersonalProfileBackground.tsx index c7b20f7fc..245ab7693 100644 --- a/rair-front/src/components/nft/PersonalProfile/PersonalProfileBackground/PersonalProfileBackground.tsx +++ b/rair-front/src/components/nft/PersonalProfile/PersonalProfileBackground/PersonalProfileBackground.tsx @@ -1,13 +1,10 @@ import { memo, useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import AddIcon from '@mui/icons-material/Add'; import axios from 'axios'; import Swal from 'sweetalert2'; import { TUserResponse } from '../../../../axios.responseTypes'; -import { RootState } from '../../../../ducks'; -import { ColorStoreType } from '../../../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../../../ducks/contracts/contracts.types'; +import { useAppSelector } from '../../../../hooks/useReduxHooks'; import cl from './PersonalProfileBackground.module.css'; @@ -15,13 +12,8 @@ const PersonalProfileBackgroundComponent = () => { const [backgroundUser, setBackgroundUser] = useState(); const [fileUpload, setFileUpload] = useState(null); const [loadingBg, setLoadingBg] = useState(false); - const { primaryColor } = useSelector( - (state) => state.colorStore - ); - const { currentUserAddress } = useSelector( - (store) => store.contractStore - ); + const { currentUserAddress } = useAppSelector((store) => store.web3); const editBackground = useCallback(async () => { if (currentUserAddress) { @@ -98,8 +90,7 @@ const PersonalProfileBackgroundComponent = () => { style={{ backgroundImage: backgroundUser && !loadingBg ? `url(${backgroundUser})` : '' - }} - className={cl[primaryColor]}> + }}> {loadingBg && (
@@ -107,7 +98,7 @@ const PersonalProfileBackgroundComponent = () => {
)} -
+
diff --git a/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyCreated/PersonalProfileMyCreated.tsx b/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyCreated/PersonalProfileMyCreated.tsx index f36a367bf..1c85184dc 100644 --- a/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyCreated/PersonalProfileMyCreated.tsx +++ b/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyCreated/PersonalProfileMyCreated.tsx @@ -3,8 +3,8 @@ import { memo, useCallback, useEffect, useState } from 'react'; import axios from 'axios'; import { useStateIfMounted } from 'use-state-if-mounted'; +import useServerSettings from '../../../../hooks/useServerSettings'; import useWindowDimensions from '../../../../hooks/useWindowDimensions'; -import useServerSettings from '../../../adminViews/useServerSettings'; const PersonalProfileMyCreatedComponent = ({ openModal, @@ -30,7 +30,7 @@ const PersonalProfileMyCreatedComponent = ({ setLoad(false); setMyContracts(response.data.contracts); } else { - console.info(response?.message); + console.error(response?.message); } }, []); diff --git a/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyNftTab/Collecteditem.tsx b/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyNftTab/Collecteditem.tsx deleted file mode 100644 index d273307cd..000000000 --- a/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyNftTab/Collecteditem.tsx +++ /dev/null @@ -1,122 +0,0 @@ -import React, { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; -import { useNavigate, useParams } from 'react-router'; - -import { RootState } from '../../../../ducks'; -import { ColorStoreType } from '../../../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../../../ducks/contracts/contracts.types'; -import useSwal from '../../../../hooks/useSwal'; -import { BillTransferIcon } from '../../../../images'; -import { rFetch } from '../../../../utils/rFetch'; -import { ImageLazy } from '../../../MockUpPage/ImageLazy/ImageLazy'; - -import ResaleModal from './ResaleModal/ResaleModal'; - -const Collecteditem = ({ item, profile, defaultImg, index, chainData }) => { - const [tokenInfo, setTokenInfo] = useState(null); - const navigate = useNavigate(); - const reactSwal = useSwal(); - - const { currentUserAddress } = useSelector( - (state) => state.contractStore - ); - const { primaryColor, textColor } = useSelector( - (store) => store.colorStore - ); - const { userAddress } = useParams(); - - const getTokenData = useCallback(async () => { - const response = await rFetch( - `/api/tokens/id/${item._id}`, - undefined, - undefined, - undefined - ); - - if (response.success) { - setTokenInfo(response.tokenData); - } - }, [item]); - - const redirection = useCallback(() => { - if (tokenInfo?.contract && tokenInfo?.product?.collectionIndexInContract) { - navigate( - `/tokens/${tokenInfo.contract.blockchain}/${tokenInfo.contract.contractAddress}/${tokenInfo.product.collectionIndexInContract}/${tokenInfo.token}` - ); - } - }, [navigate, tokenInfo]); - - useEffect(() => { - getTokenData(); - }, [getTokenData]); - - return ( -
- {currentUserAddress === userAddress && ( - - )} - -
-
-
- - {item.metadata ? ( - <> - {item.title} - - ) : ( - No metadata available - )} -
-
-
- - {item.metadata && item.metadata.name.length > 16 - ? item.metadata.name.slice(0, 5) + - '...' + - item.metadata.name.slice(item.metadata.name.length - 4) - : item.metadata.name} - -
- Blockchain network -
-
-
-
-
-
- ); -}; - -export default Collecteditem; diff --git a/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyNftTab/PersonalProfileMyNftTab.tsx b/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyNftTab/PersonalProfileMyNftTab.tsx index ccdec8247..8f77f1fc3 100644 --- a/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyNftTab/PersonalProfileMyNftTab.tsx +++ b/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyNftTab/PersonalProfileMyNftTab.tsx @@ -2,6 +2,7 @@ import { memo, useCallback, useEffect, useRef, useState } from 'react'; import CircularProgress from '@mui/material/CircularProgress'; import useWindowDimensions from '../../../../hooks/useWindowDimensions'; +import { NftItemToken } from '../../../../types/commonTypes'; import LoadingComponent from '../../../common/LoadingComponent'; import { MobileCloseBtn } from '../../../GlobalModal/FilterModal/FilterModalIcons'; import { HomePageModalFilter } from '../../../GlobalModal/FilterModal/HomePAgeModal'; @@ -11,7 +12,7 @@ import { NftItemForCollectionView } from '../../../MockUpPage/NftList/NftItemFor import './PersonalProfileMyNftTab.css'; interface IPersonalProfileMyNftTabComponent { - filteredData: any; + filteredData?: NftItemToken[]; openModal?: any; setSelectedData?: any; defaultImg: string; @@ -120,9 +121,7 @@ const PersonalProfileMyNftTabComponent: React.FC< return ( - There is no such item with that name -

+

No items found

)}
)} @@ -209,7 +206,7 @@ const PersonalProfileMyNftTabComponent: React.FC< />
)} - {!onResale && totalCount && showTokensRef.current <= totalCount && ( + {!onResale && !!totalCount && showTokensRef.current <= totalCount && (
)} 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 96d12b227..570bdd3e6 100644 --- a/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyNftTab/ResaleModal/ResaleModal.tsx +++ b/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyNftTab/ResaleModal/ResaleModal.tsx @@ -1,17 +1,24 @@ import React, { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import { faTrash } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import CloseIcon from '@mui/icons-material/Close'; -import { formatEther, formatUnits, parseEther } from 'ethers/lib/utils'; +import { formatUnits, parseEther } from 'ethers'; +import { Hex } from 'viem'; -import { RootState } from '../../../../../ducks'; -import { ColorStoreType } from '../../../../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../../../../ducks/contracts/contracts.types'; +import useContracts from '../../../../../hooks/useContracts'; +import { + useAppDispatch, + useAppSelector +} from '../../../../../hooks/useReduxHooks'; +import useServerSettings from '../../../../../hooks/useServerSettings'; import useSwal from '../../../../../hooks/useSwal'; import useWeb3Tx from '../../../../../hooks/useWeb3Tx'; +import { + CollectionTokens, + reloadTokenData +} from '../../../../../redux/tokenSlice'; +import { NftItemToken } from '../../../../../types/commonTypes'; import { rFetch } from '../../../../../utils/rFetch'; -import useServerSettings from '../../../../adminViews/useServerSettings'; import InputField from '../../../../common/InputField'; import { TooltipBox } from '../../../../common/Tooltip/TooltipBox'; import { ImageLazy } from '../../../../MockUpPage/ImageLazy/ImageLazy'; @@ -21,35 +28,42 @@ import SellButton from '../../../../MockUpPage/NftList/NftData/SellButton'; import './ResaleModal.css'; interface IResaleModal { - item: any; - textColor: any; + item: NftItemToken | CollectionTokens; singleTokenPage?: boolean; - reloadFunction?: () => void; getMyNft?: (num: number, page: number) => void; totalNft?: any; } const ResaleModal: React.FC = ({ item, - textColor, singleTokenPage, - reloadFunction, getMyNft, totalNft }) => { - const { diamondMarketplaceInstance, currentUserAddress, coingeckoRates } = - useSelector( - (state) => state.contractStore - ); + const { currentCollectionMetadata } = useAppSelector((store) => store.tokens); + const { currentUserAddress, exchangeRates } = useAppSelector( + (state) => state.web3 + ); + + const [contractAddress] = useState( + typeof item?.contract === 'string' + ? currentCollectionMetadata?.contract?.contractAddress + : item?.contract?.contractAddress + ); + const [blockchain] = useState( + typeof item?.contract === 'string' + ? currentCollectionMetadata?.contract?.blockchain + : item?.contract?.blockchain + ); + + const { diamondMarketplaceInstance } = useContracts(); - const { primaryColor, primaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { primaryColor, primaryButtonColor, textColor, isDarkMode } = + useAppSelector((store) => store.colors); const { getBlockchainData } = useServerSettings(); + const dispatch = useAppDispatch(); - const [resaleData, setResaleData] = useState(); const [resaleOffer, setResaleOffer] = useState(undefined); const [isInputPriceExist, setIsInputPriceExist] = useState(false); const [inputSellValue, setInputSellValue] = useState(''); @@ -57,7 +71,7 @@ const ResaleModal: React.FC = ({ const reactSwal = useSwal(); const xMIN = Number(0.0001); - const yMAX = item?.contract?.blockchain === '0x1' ? 10 : 10000.0; + const yMAX = blockchain === '0x1' ? 10 : 10000.0; const { web3Switch, correctBlockchain, web3TxHandler } = useWeb3Tx(); @@ -70,11 +84,7 @@ const ResaleModal: React.FC = ({ }, [inputSellValue]); const fetchRoyalties = useCallback(async () => { - if ( - diamondMarketplaceInstance && - item && - correctBlockchain(item.contract.blockchain) - ) { + if (diamondMarketplaceInstance && item && correctBlockchain(blockchain)) { const nodeFee = await web3TxHandler( diamondMarketplaceInstance, 'getNodeFee' @@ -87,7 +97,7 @@ const ResaleModal: React.FC = ({ const result = await web3TxHandler( diamondMarketplaceInstance, 'getRoyalties', - [item.contract.contractAddress] + [contractAddress] ); const calculationNodeFee = formatUnits(nodeFee.nodeFee, nodeFee.decimals); @@ -113,41 +123,23 @@ const ResaleModal: React.FC = ({ }, [diamondMarketplaceInstance]); const getResaleData = useCallback(async () => { - if (item) { - if (!diamondMarketplaceInstance) { - return; - } - const contractResponse = await rFetch( - `/api/contracts?contractAddress=${item.contract.contractAddress}&blockchain=${item.contract.blockchain}` - ); - if (!contractResponse.success) { - return; - } - const contractData = contractResponse?.result?.at(0); - if (!contractData) { - return; - } - setResaleData(undefined); - const resaleResponse = await rFetch( - `/api/resales/open?contract=${item.contract.contractAddress}&blockchain=${item.contract.blockchain}&index=${item.uniqueIndexInContract}` - ); - if (!resaleResponse.success) { - return; - } - const [resaleData] = resaleResponse.data; - if (!resaleData) { - return; - } - const userResponse = await rFetch( - `/api/users/${resaleData.seller.toLowerCase()}` - ); - if (userResponse.success) { - resaleData.seller = userResponse.user.nickName; - } + setResaleOffer(undefined); + const token = item.uniqueIndexInContract; + if (!contractAddress || !blockchain || !token) { + return; } - setResaleData(resaleData); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [diamondMarketplaceInstance]); + const { success, data } = await rFetch( + `/api/resales/open?contract=${contractAddress}&blockchain=${blockchain}&index=${token}` + ); + if (!success) { + return; + } + const [resaleData] = data; + if (!resaleData) { + return; + } + setResaleOffer(resaleData); + }, [item, contractAddress, blockchain]); const removeResaleOffer = async (tokenId) => { const response = await rFetch(`/api/resales/delete/${tokenId}`, { @@ -162,7 +154,77 @@ const ResaleModal: React.FC = ({ } }; - const updateResaleOffer = async (price, id) => { + const removeResaleOfferBlockchain = useCallback( + async (id) => { + if (!id || !diamondMarketplaceInstance) { + return; + } + if ( + await web3TxHandler(diamondMarketplaceInstance, 'deleteGasTokenOffer', [ + id + ]) + ) { + reactSwal.fire({ + title: 'Deleted', + html: 'Your resale offer has been deleted.', + icon: 'success' + }); + if (!singleTokenPage && totalNft) { + getMyNft && getMyNft(Number(totalNft), 1); + if (!singleTokenPage && totalNft) { + getMyNft && getMyNft(Number(totalNft), 1); + } + } + } + }, + [ + diamondMarketplaceInstance, + getMyNft, + reactSwal, + singleTokenPage, + totalNft, + web3TxHandler + ] + ); + + const updateResaleOfferBlockchain = useCallback( + async (price: string, id: string) => { + if (!diamondMarketplaceInstance || !price || !id) { + return; + } + if ( + await web3TxHandler(diamondMarketplaceInstance, 'updateGasTokenOffer', [ + id, + parseEther(price) + ]) + ) { + reactSwal.fire({ + title: 'Updated!', + html: "The offer's price has been updated.", + icon: 'success' + }); + getResaleData(); + dispatch(reloadTokenData({ tokenId: item._id })); + + if (!singleTokenPage && totalNft) { + getMyNft && getMyNft(Number(totalNft), 1); + } + } + }, + [ + diamondMarketplaceInstance, + dispatch, + getMyNft, + getResaleData, + item._id, + reactSwal, + singleTokenPage, + totalNft, + web3TxHandler + ] + ); + + const updateResaleOfferDatabase = async (price, id) => { const response = await rFetch(`/api/resales/update`, { method: 'PUT', body: JSON.stringify({ @@ -182,7 +244,7 @@ const ResaleModal: React.FC = ({ icon: 'success' }); getResaleData(); - reloadFunction && reloadFunction(); + dispatch(reloadTokenData({ tokenId: item._id })); if (!singleTokenPage && totalNft) { getMyNft && getMyNft(Number(totalNft), 1); @@ -190,7 +252,7 @@ const ResaleModal: React.FC = ({ } }; - const removeVideoAlert = (tokenId) => { + const confirmDatabaseResaleDeletion = (tokenId) => { reactSwal .fire({ title: 'Are you sure?', @@ -208,7 +270,7 @@ const ResaleModal: React.FC = ({ 'Your resale offer has been deleted.', 'success' ); - reloadFunction && reloadFunction(); + dispatch(reloadTokenData({ tokenId: item._id })); removeResaleOffer(tokenId); if (!singleTokenPage && totalNft) { getMyNft && getMyNft(Number(totalNft), 1); @@ -220,37 +282,21 @@ const ResaleModal: React.FC = ({ }); }; - const getResalesInfo = useCallback(async () => { - if (item) { - const resaleResponse = await rFetch( - `/api/resales/open?contract=${item.contract.contractAddress}&blockchain=${item.contract.blockchain}&index=${item.uniqueIndexInContract}` - ); - if (resaleResponse.success) { - setResaleOffer(resaleResponse.data); - if (resaleResponse.data.length > 0) { - setInputSellValue(formatEther(resaleResponse.data[0].price)); - } - } - } - }, [item]); - useEffect(() => { - getResalesInfo(); - }, [getResalesInfo]); + getResaleData(); + }, [getResaleData]); useEffect(() => { fetchRoyalties(); }, [fetchRoyalties]); - const chainData = getBlockchainData(item.contract.blockchain); + const chainData = getBlockchainData(blockchain); return (
{item && item.metadata && ( @@ -268,10 +314,10 @@ const ResaleModal: React.FC = ({ )}
- {!correctBlockchain(item.contract.blockchain) ? ( + {!correctBlockchain(blockchain) ? (
web3Switch(item.contract.blockchain)} + handleClick={() => web3Switch(blockchain)} isColorPurple={true} title={`Switch network`} /> @@ -297,7 +343,7 @@ const ResaleModal: React.FC = ({ />
- {resaleOffer && resaleOffer.length > 0 ? ( + {resaleOffer ? ( <> {' '} @@ -345,15 +408,17 @@ const ResaleModal: React.FC = ({ ) : ( { getResaleData(); - reloadFunction && reloadFunction(); + //dispatch(); }} singleTokenPage={true} /> @@ -378,64 +443,66 @@ const ResaleModal: React.FC = ({
Total:
-
-
-
- {' '} - $ - {commissionFee && - coingeckoRates && - commissionFee.creatorFee && - commissionFee.creatorFee.length > 0 - ? ( - ((Number(inputSellValue) * - Number(commissionFee.creatorFee)) / - 100) * - coingeckoRates[item.contract.blockchain] - ).toFixed(2) - : '0'} -
-
-
-
- {inputSellValue.length <= 10 && - commissionFee && - coingeckoRates && ( -
- $ - {( + {blockchain && ( +
+
+
+ {' '} + $ + {commissionFee && + exchangeRates && + commissionFee.creatorFee && + commissionFee.creatorFee.length > 0 + ? ( ((Number(inputSellValue) * - (Number(commissionFee.nodeFee) + - Number(commissionFee.treasuryFee))) / + Number(commissionFee.creatorFee)) / 100) * - coingeckoRates[item.contract.blockchain] - ).toFixed(2)} -
- )} + exchangeRates[blockchain] + ).toFixed(2) + : '0'} +
-
-
-
- $ - {inputSellValue.length <= 10 && - commissionFee && - coingeckoRates && - correctBlockchain(item.contract.blockchain) - ? ( - (Number(inputSellValue) - - (Number(inputSellValue) * - (Number(commissionFee.creatorFee) + +
+
+ {inputSellValue.length <= 10 && + commissionFee && + exchangeRates && ( +
+ $ + {( + ((Number(inputSellValue) * (Number(commissionFee.nodeFee) + - (commissionFee.treasuryFee - ? Number(commissionFee.treasuryFee) - : 0)))) / - 100) * - coingeckoRates[item.contract.blockchain] - ).toFixed(2) - : '0'} + Number(commissionFee.treasuryFee))) / + 100) * + exchangeRates[blockchain] + ).toFixed(2)} +
+ )} +
+
+
+
+ $ + {inputSellValue.length <= 10 && + commissionFee && + exchangeRates && + correctBlockchain(blockchain) + ? ( + (Number(inputSellValue) - + (Number(inputSellValue) * + (Number(commissionFee.creatorFee) + + (Number(commissionFee.nodeFee) + + (commissionFee.treasuryFee + ? Number(commissionFee.treasuryFee) + : 0)))) / + 100) * + exchangeRates[blockchain] + ).toFixed(2) + : '0'} +
-
+ )}
@@ -467,7 +534,7 @@ const ResaleModal: React.FC = ({
{inputSellValue.length <= 10 && commissionFee && - correctBlockchain(item.contract.blockchain) + correctBlockchain(blockchain) ? ( Number(inputSellValue) - (Number(inputSellValue) * diff --git a/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyVideoTab/PersonalProfileMyVideoTab.tsx b/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyVideoTab/PersonalProfileMyVideoTab.tsx index 0bafd6543..f75e78039 100644 --- a/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyVideoTab/PersonalProfileMyVideoTab.tsx +++ b/rair-front/src/components/nft/PersonalProfile/PersonalProfileMyVideoTab/PersonalProfileMyVideoTab.tsx @@ -1,62 +1,46 @@ -import { memo, useCallback, useEffect } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; +import { FC, memo, useEffect, useState } from 'react'; +import { Hex } from 'viem'; -import { RootState } from '../../../../ducks'; -import { TVideosInitialState } from '../../../../ducks/videos/videosDucks.types'; +import { + useAppDispatch, + useAppSelector +} from '../../../../hooks/useReduxHooks'; +import { dataStatuses } from '../../../../redux/commonTypes'; +import { loadVideoList } from '../../../../redux/videoSlice'; +import { CatalogVideoItem } from '../../../../types/commonTypes'; import LoadingComponent from '../../../common/LoadingComponent'; import VideoItem from '../../../video/videoItem'; // import cl from './PersonalProfileMyVideoTab.module.css'; interface IPersonalProfileMyVideoTabComponent { titleSearch: string; - publicAddress?: string; + publicAddress?: Hex; } -const PersonalProfileMyVideoTabComponent: React.FC< +const PersonalProfileMyVideoTabComponent: FC< IPersonalProfileMyVideoTabComponent > = ({ titleSearch, publicAddress }) => { - const dispatch = useDispatch(); + const dispatch = useAppDispatch(); - const { videos, loading } = useSelector( - (store) => store.videosStore - ); - const myVideo = {}; - - const updateVideo = useCallback( - (params) => { - dispatch({ type: 'GET_LIST_VIDEOS_START', params: params }); - }, - [dispatch] - ); + const { videos, videoListStatus } = useAppSelector((store) => store.videos); + const [unlockedVideos, setUnlockedVideos] = useState([]); useEffect(() => { - const params = { - itemsPerPage: '10000000', - publicAddress: publicAddress ? publicAddress : undefined - // pageNum: '1', - }; - updateVideo(params); - }, [updateVideo, publicAddress]); + dispatch( + loadVideoList({ + userAddress: publicAddress ? publicAddress : undefined + }) + ); + }, [dispatch, publicAddress]); - const findMyVideo = (obj: object, subField: string, value: boolean) => { - if (obj !== null) { - for (const i in obj) { - const video = obj[i]; - if (publicAddress) { - myVideo[i] = video; - } else { - if (video[subField] === value) { - myVideo[i] = video; - } - } - } + useEffect(() => { + if (publicAddress) { + setUnlockedVideos(videos); } - }; - if (videos !== null) { - findMyVideo(videos, 'isUnlocked', true); - } + setUnlockedVideos(videos.filter((video) => video.isUnlocked)); + }, [videos, publicAddress]); - if (loading) { + if (videoListStatus !== dataStatuses.Complete) { return ; } return ( @@ -64,24 +48,16 @@ const PersonalProfileMyVideoTabComponent: React.FC<
- {myVideo ? ( - Object.keys(myVideo).length > 0 ? ( - Object.keys(myVideo) - .filter((item) => - myVideo[item].title - .toLowerCase() - .includes(titleSearch.toLowerCase()) - ) - .map((item, index) => { - return ( - - ); - }) - ) : ( -
No files found
- ) + {unlockedVideos.length ? ( + unlockedVideos + ?.filter((video) => + video.title.toLowerCase().includes(titleSearch.toLowerCase()) + ) + .map((item, index) => { + return ; + }) ) : ( - 'Searching...' +
No files found
)}
diff --git a/rair-front/src/components/nft/myDiamondItems.tsx b/rair-front/src/components/nft/myDiamondItems.tsx index 41055e761..4e44293c9 100644 --- a/rair-front/src/components/nft/myDiamondItems.tsx +++ b/rair-front/src/components/nft/myDiamondItems.tsx @@ -1,8 +1,8 @@ import React, { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import { faGem } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import axios from 'axios'; +import { Hex } from 'viem'; import { IItemsForContract, @@ -14,10 +14,9 @@ import { import { TMetadataType } from '../../axios.responseTypes'; import { diamondFactoryAbi } from '../../contracts'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; -import useServerSettings from '../adminViews/useServerSettings'; +import useContracts from '../../hooks/useContracts'; +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; const TokenLayout: React.FC = ({ item, @@ -28,9 +27,7 @@ const TokenLayout: React.FC = ({ import.meta.env.VITE_IPFS_GATEWAY }/QmNtfjBAPYEFxXiHmY5kcPh9huzkwquHBcn9ZJHGe7hfaW`; - const { primaryColor } = useSelector( - (store) => store.colorStore - ); + const { primaryColor } = useAppSelector((store) => store.colors); const { getBlockchainData } = useServerSettings(); @@ -113,10 +110,10 @@ const ItemsForContract: React.FC = ({ }) => { const [tokens, setTokens] = useState([]); const [contractName, setContractName] = useState(''); - const { contractCreator, currentUserAddress, currentChain } = useSelector< - RootState, - ContractsInitialType - >((store) => store.contractStore); + const { contractCreator } = useContracts(); + const { currentUserAddress, connectedChain } = useAppSelector( + (store) => store.web3 + ); const getTokens = useCallback(async () => { const instance = contractCreator?.(item, diamondFactoryAbi); setContractName(await instance?.name()); @@ -142,11 +139,11 @@ const ItemsForContract: React.FC = ({ metadata, contract: item, title: metadata ? metadata.name : contractName, - blockchain: currentChain + blockchain: connectedChain }); } setTokens(tokenData); - }, [item, contractCreator, contractName, currentUserAddress, currentChain]); + }, [item, contractCreator, contractName, currentUserAddress, connectedChain]); useEffect(() => { getTokens(); @@ -168,12 +165,9 @@ const ItemsForContract: React.FC = ({ }; const MyDiamondItems: React.FC = (props) => { - const [deploymentAddresses, setDeploymentAddresses] = useState([]); + const [deploymentAddresses, setDeploymentAddresses] = useState([]); const [status, setStatus] = useState('Fetching data...'); - const { diamondMarketplaceInstance } = useSelector< - RootState, - ContractsInitialType - >((store) => store.contractStore); + const { diamondMarketplaceInstance } = useContracts(); const fetchDiamondData = useCallback(async () => { if (!diamondMarketplaceInstance) { return; @@ -182,7 +176,7 @@ const MyDiamondItems: React.FC = (props) => { (await diamondMarketplaceInstance.getTotalOfferCount()).toString() ); setStatus(`Found ${offerCount} addresses...`); - const deployments: string[] = []; + const deployments: Hex[] = []; for (let i = 0; i < offerCount; i++) { setStatus(`Querying address ${i + 1} of ${offerCount}...`); const singleOfferData: TSingleOfferData = diff --git a/rair-front/src/components/nft/myItems.tsx b/rair-front/src/components/nft/myItems.tsx deleted file mode 100644 index c5b284eab..000000000 --- a/rair-front/src/components/nft/myItems.tsx +++ /dev/null @@ -1,308 +0,0 @@ -import React, { useCallback, useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import { NavLink } from 'react-router-dom'; -import { Tab, TabList, TabPanel, Tabs } from 'react-tabs'; -import { faHeart, faSearch } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import HomeIcon from '@mui/icons-material/Home'; -import NavigateNextIcon from '@mui/icons-material/NavigateNext'; -import { Breadcrumbs, Typography } from '@mui/material'; -import Stack from '@mui/material/Stack'; - -import { IMyItems, TDiamondTokensType } from './nft.types'; - -import { RootState } from '../../ducks'; -import { getTokenError } from '../../ducks/auth/actions'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { TUsersInitialState } from '../../ducks/users/users.types'; -import useWindowDimensions from '../../hooks/useWindowDimensions'; -import { rFetch } from '../../utils/rFetch'; -import setDocumentTitle from '../../utils/setTitle'; -import InputField from '../common/InputField'; -import FilteringBlock from '../MockUpPage/FilteringBlock/FilteringBlock'; -import { TSortChoice } from '../MockUpPage/FilteringBlock/filteringBlock.types'; -import ModalItem from '../MockUpPage/FilteringBlock/portal/ModalItem/ModalItem'; - -import { PersonalProfileBackground } from './PersonalProfile/PersonalProfileBackground/PersonalProfileBackground'; -import PersonalProfileFavoritesTab from './PersonalProfile/PersonalProfileFavoritesTab/PersonalProfileFavoritesTab'; -import { PersonalProfileIcon } from './PersonalProfile/PersonalProfileIcon/PersonalProfileIcon'; -import { PersonalProfileMyCreated } from './PersonalProfile/PersonalProfileMyCreated/PersonalProfileMyCreated'; -import { PersonalProfileMyNftTab } from './PersonalProfile/PersonalProfileMyNftTab/PersonalProfileMyNftTab'; -import { PersonalProfileMyVideoTab } from './PersonalProfile/PersonalProfileMyVideoTab/PersonalProfileMyVideoTab'; - -import './MyItems.css'; - -const MyItems: React.FC = ({ - userData, - setIsSplashPage, - setTabIndexItems, - tabIndexItems -}) => { - const { width } = useWindowDimensions(); - const dispatch = useDispatch(); - const defaultImg = `${ - import.meta.env.VITE_IPFS_GATEWAY - }/QmNtfjBAPYEFxXiHmY5kcPh9huzkwquHBcn9ZJHGe7hfaW`; - const { userRd } = useSelector( - (store) => store.userStore - ); - - const { primaryColor, textColor } = useSelector( - (state) => state.colorStore - ); - const [tokens, setTokens] = useState([]); - const [selectedData, setSelectedData] = - useState(); - const [titleSearch, setTitleSearch] = useState(''); - const [sortItem, setSortItem] = useState(); - const [isOpenBlockchain, setIsOpenBlockchain] = useState(false); - const [isCreatedTab, setIsCreatedTab] = useState(false); - // const [tabIndex, setTabIndex] = useState(0); - - const getMyNft = useCallback(async () => { - if (userRd) { - const response = await rFetch( - `/api/nft/${userRd?.publicAddress}?itemsPerPage=${20}&pageNum=${1}` - ); - - if (response.success) { - const tokenData: TDiamondTokensType[] = []; - for await (const token of response.result) { - if (!token.contract) { - return; - } - const contractData = await rFetch(`/api/contracts/${token.contract}`); - tokenData.push({ - ...token, - ...contractData.contract - }); - } - setTokens(tokenData); - } - - if (response.error && response.message) { - dispatch(getTokenError(response.error)); - } - } - }, [dispatch, userRd]); - - const openModal = () => { - setIsOpenBlockchain(true); - }; - - const breadcrumbs = [ - - - , - - Personal profile - - ]; - - const filteredData = - tokens && - tokens - .filter((item: TDiamondTokensType) => { - return item?.title?.toLowerCase()?.includes(titleSearch?.toLowerCase()); - }) - .sort((a: TDiamondTokensType, b: TDiamondTokensType) => { - if (sortItem === 'up') { - if (a.title < b.title) { - return -1; - } - } - if (sortItem === 'down') { - if (a.title > b.title) { - return 1; - } - } - - return 0; - }); - - useEffect(() => { - getMyNft(); - }, [getMyNft]); - - useEffect(() => { - setDocumentTitle('My Items'); - window.scrollTo(0, 0); - setIsSplashPage(false); - }, [setIsSplashPage]); - - return ( -
-
- - } - aria-label="breadcrumb"> - {breadcrumbs} - - -
- -
- - {/*
navigate(-1)} className="my-items-title-wrapper"> - -

My Items

-
*/} - <> - setTabIndexItems(index)}> - - - {width <= 700 ? 'Created' : 'Created'} - - - {width <= 700 ? 'Video' : 'My Videos'} - - - {width <= 700 ? ( - - ) : ( - 'My favorites' - )} - - - Created - - - {/* Search block */} -
- - - - - -
- - - - - - - - - - - - -
- -
- {isOpenBlockchain && ( - - )} -
- ); -}; - -export default MyItems; diff --git a/rair-front/src/components/nft/nft.types.ts b/rair-front/src/components/nft/nft.types.ts index 028d68c0f..14b5e632a 100644 --- a/rair-front/src/components/nft/nft.types.ts +++ b/rair-front/src/components/nft/nft.types.ts @@ -1,4 +1,4 @@ -import { BigNumber } from 'ethers'; +import { Hex } from 'viem'; import { TMetadataType } from '../../axios.responseTypes'; @@ -11,13 +11,13 @@ export interface ITokenLayout { } export interface IItemsForContract { - item: string; + item: Hex; openModal: () => void; setSelectedData: (item: TMyDiamondItemsToken) => void; } export type TMyDiamondItemsToken = { - blockchain: BlockchainType | undefined; + blockchain: Hex | undefined; contract: string; metadata: TMetadataType | undefined; title: string; @@ -30,8 +30,6 @@ export interface IMyDiamondItems { } export interface IMyItems { - userData: object; - goHome: () => void; setIsSplashPage: (arg: boolean) => void; setTabIndexItems: (arg: number) => void; tabIndexItems: number; @@ -39,51 +37,51 @@ export interface IMyItems { export type TPercentageRecipient = { 0: string; - 1: BigNumber; - percentage: BigNumber; + 1: bigint; + percentage: bigint; recipient: string; }; export type TMintOffer = { 0: string; 1: string; - 2: BigNumber; + 2: bigint; 3: TPercentageRecipient[]; 4: boolean; - erc721Address: string; + erc721Address: Hex; fees: TPercentageRecipient[]; nodeAddress: string; - rangeIndex: BigNumber; + rangeIndex: bigint; visible: boolean; }; export type TRangeData = { - 0: BigNumber; - 1: BigNumber; - 2: BigNumber; - 3: BigNumber; - 4: BigNumber; - 5: BigNumber; + 0: bigint; + 1: bigint; + 2: bigint; + 3: bigint; + 4: bigint; + 5: bigint; 6: string; - lockedTokens: BigNumber; - mintableTokens: BigNumber; - rangeEnd: BigNumber; + lockedTokens: bigint; + mintableTokens: bigint; + rangeEnd: bigint; rangeName: string; - rangePrice: BigNumber; - rangeStart: BigNumber; - tokensAllowed: BigNumber; + rangePrice: bigint; + rangeStart: bigint; + tokensAllowed: bigint; }; export type TSingleOfferData = { 0: TMintOffer; 1: TRangeData; - 2: BigNumber; + 2: bigint; mintOffer: TMintOffer; - productIndex: BigNumber; + productIndex: bigint; rangeData: TRangeData; }; export type TDiamondTokensType = TTokenData & { - blockchain: BlockchainType | undefined; - contractAddress: string; + blockchain: Hex | undefined; + contractAddress: Hex; title: string; }; diff --git a/rair-front/src/components/video/video.types.ts b/rair-front/src/components/video/video.types.ts index 044eb7db7..28c33738e 100644 --- a/rair-front/src/components/video/video.types.ts +++ b/rair-front/src/components/video/video.types.ts @@ -1,4 +1,5 @@ import { TTokenData } from '../../axios.responseTypes'; +import { CatalogVideoItem } from '../../types/commonTypes'; import { ContractType } from './../adminViews/adminView.types'; export interface IVideoPlayer { @@ -21,7 +22,6 @@ export interface IVideoList { titleSearch: string; responseLabel?: string; endpoint?: string; - videos?: MediaListResponseType | null; handleVideoIsUnlocked?: () => void; } @@ -53,7 +53,5 @@ export type MediaListResponseType = { }; export interface IVideoItem { - mediaList: MediaListResponseType; - item: string; - handleVideoIsUnlocked?: () => void; + item: CatalogVideoItem; } diff --git a/rair-front/src/components/video/videoItem.tsx b/rair-front/src/components/video/videoItem.tsx index 3b61be7f6..e9801922b 100644 --- a/rair-front/src/components/video/videoItem.tsx +++ b/rair-front/src/components/video/videoItem.tsx @@ -1,22 +1,21 @@ import { useCallback, useEffect, useState } from 'react'; import Modal from 'react-modal'; -import { Provider, useSelector, useStore } from 'react-redux'; +import { Provider, useStore } from 'react-redux'; import { useNavigate } from 'react-router-dom'; import { faLock, faTimes } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import axios from 'axios'; -import { constants, utils } from 'ethers'; +import { isAddress, ZeroAddress } from 'ethers'; import { useStateIfMounted } from 'use-state-if-mounted'; import { IVideoItem, TVideoItemContractData } from './video.types'; import { TUserResponse } from '../../axios.responseTypes'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; -import { TUsersInitialState, UserType } from '../../ducks/users/users.types'; +import { useAppSelector } from '../../hooks/useReduxHooks'; import useSwal from '../../hooks/useSwal'; import useWindowDimensions from '../../hooks/useWindowDimensions'; +import { CustomModalStyle } from '../../types/commonTypes'; +import { User } from '../../types/databaseTypes'; import formatDuration from '../../utils/durationUtils'; import { rFetch } from '../../utils/rFetch'; import { TooltipBox } from '../common/Tooltip/TooltipBox'; @@ -31,23 +30,12 @@ import YotiPage from '../YotiPage/YotiPage'; Modal.setAppElement('#root'); -const VideoItem: React.FC = ({ - mediaList, - item - // handleVideoIsUnlocked -}) => { - // const [mintPopUp, setMintPopUp] = useState(false); - // const [firstStepPopUp, setFirstStepPopUp] = useState(false); - // const [purchaseStatus, setPurchaseStatus] = useState(false); +const VideoItem: React.FC = ({ item }) => { const [offersArray, setOffersArray] = useState([]); - const { userData } = useSelector( - (store) => store.userStore - ); + const { ageVerified } = useAppSelector((store) => store.user); - const { currentUserAddress } = useSelector( - (store) => store.contractStore - ); + const { currentUserAddress } = useAppSelector((store) => store.web3); const navigate = useNavigate(); // const [offerDataInfo,setOfferDataInfo] = useState(); @@ -55,11 +43,10 @@ const VideoItem: React.FC = ({ useStateIfMounted(null); const { width } = useWindowDimensions(); - const { primaryColor, textColor } = useSelector( - (store) => store.colorStore - ); + const { primaryColor, textColor, primaryButtonColor, isDarkMode } = + useAppSelector((store) => store.colors); - const customStyles = { + const customStyles: CustomModalStyle = { overlay: { position: 'fixed', display: 'flex', @@ -102,7 +89,7 @@ const VideoItem: React.FC = ({ const [hovering, setHovering] = useState(false); const [owned /*setOwned*/] = useState(false); const [openVideoplayer, setOpenVideoplayer] = useState(false); - const [dataUser, setDataUser] = useStateIfMounted(null); + const [dataUser, setDataUser] = useStateIfMounted(null); const reactSwal = useSwal(); const store = useStore(); @@ -119,13 +106,13 @@ const VideoItem: React.FC = ({ const ageVerificationPopUp = useCallback(() => { if ( modalIsOpen && - mediaList[item].ageRestricted === true && - (userData?.ageVerified === false || !userData?.ageVerified) + item.ageRestricted === true && + (ageVerified === false || !ageVerified) ) { reactSwal.fire({ html: ( - + ), showConfirmButton: false, @@ -137,7 +124,7 @@ const VideoItem: React.FC = ({ } else { setOpenVideoplayer(true); } - }, [modalIsOpen, mediaList, item, userData?.ageVerified, reactSwal, store]); + }, [modalIsOpen, item, ageVerified, reactSwal, store]); const goToCollectionView = () => { if (offersArray.length > 0) { @@ -149,10 +136,8 @@ const VideoItem: React.FC = ({ }; const getInfo = useCallback(async () => { - if (mediaList && item) { - const { data } = await rFetch( - `/api/files/${mediaList[item]._id}/unlocks` - ); + if (item) { + const { data } = await rFetch(`/api/files/${item._id}/unlocks`); if (data?.offers && data.offers.length > 0) { const firstOffer = data.offers[0]; @@ -167,22 +152,21 @@ const VideoItem: React.FC = ({ } } } - }, [mediaList, item, setContractData]); + }, [item, setContractData]); const getInfoUser = useCallback(async () => { + //# Optimize if ( - mediaList && - item && - mediaList[item].uploader && - utils.isAddress(mediaList[item].uploader) && - mediaList[item].uploader !== constants.AddressZero + item.uploader && + isAddress(item.uploader) && + item.uploader !== ZeroAddress ) { const response = await axios.get( - `/api/users/${mediaList[item].uploader}` + `/api/users/${item.uploader}` ); setDataUser(response.data.user); } - }, [mediaList, item, setDataUser]); + }, [item, setDataUser]); useEffect(() => { getInfoUser(); @@ -203,7 +187,7 @@ const VideoItem: React.FC = ({ border: 'none', backgroundColor: 'transparent' }} - onMouseEnter={() => setHovering(mediaList[item].animatedThumbnail !== '')} + onMouseEnter={() => setHovering(item.animatedThumbnail !== '')} onMouseLeave={() => setHovering(false)}>
openModal()} @@ -216,7 +200,7 @@ const VideoItem: React.FC = ({ }}> Video thumbnail = ({ /> Animated video thumbnail = ({ }} className="col-12 h-100 w-100" /> - {mediaList[item]?.isUnlocked ? null : } + {item?.isUnlocked ? null : }
- {mediaList[item].title.slice(0, 25)} - {mediaList[item].title.length > 26 ? '...' : ''} + {item.title.slice(0, 25)} + {item.title.length > 26 ? '...' : ''}
@@ -264,7 +248,7 @@ const VideoItem: React.FC = ({
{' '} - {formatDuration(mediaList[item].duration)} + {formatDuration(item.duration)}
@@ -278,7 +262,7 @@ const VideoItem: React.FC = ({ contentLabel="Video Modal">
= ({ className={`${ primaryColor !== 'rhyno' && 'text-white' } modal-content-wrapper-for-video ${ - mediaList[item]?.isUnlocked && !owned ? 'unlocked' : 'locked' + item?.isUnlocked && !owned ? 'unlocked' : 'locked' }`}>
- {mediaList[item]?.isUnlocked === false && !owned ? ( + {item?.isUnlocked === false && !owned ? ( <> = ({ ) : openVideoplayer ? ( - + ) : ( <>
@@ -344,18 +328,13 @@ const VideoItem: React.FC = ({
)} - {openVideoplayer ? null : mediaList[item]?.isUnlocked === - false && !owned ? ( + {!openVideoplayer && !!item.staticThumbnail && ( Modal content video thumbnail - ) : ( - Modal content video thumbnail )}
@@ -365,7 +344,7 @@ const VideoItem: React.FC = ({ primaryColor === 'rhyno' ? 'rhyno' : '' }`}>
- {mediaList[item] &&

{mediaList[item].title}

} + {item &&

{item.title}

}
= ({ width={'160px'} height={'30px'} margin={'5px'} - textColor={primaryColor === 'rhyno' ? '#222021' : 'white'} + textColor={textColor} onClick={goToCollectionView} custom={false} - background={`var(--${ - primaryColor === 'charcoal' - ? 'charcoal-80' - : 'charcoal-40' - })`} + background={primaryButtonColor} /> )}
-

About this collection:

- {mediaList[item].description && ( -

{mediaList[item].description}

- )} + Description + {item.description &&

{item.description}

}
diff --git a/rair-front/src/components/video/videoList.tsx b/rair-front/src/components/video/videoList.tsx index 7b1abf2c7..b927aa786 100644 --- a/rair-front/src/components/video/videoList.tsx +++ b/rair-front/src/components/video/videoList.tsx @@ -1,26 +1,22 @@ import { useContext } from 'react'; -import { useSelector } from 'react-redux'; import { IVideoList } from './video.types'; import VideoItem from './videoItem'; -import { RootState } from '../../ducks'; +import { useAppSelector } from '../../hooks/useReduxHooks'; import useWindowDimensions from '../../hooks/useWindowDimensions'; import { GlobalModalContext, TGlobalModalContext } from '../../providers/ModalProvider'; +import { dataStatuses } from '../../redux/commonTypes'; import LoadingComponent from '../common/LoadingComponent'; import HomePageFilterModal from '../GlobalModal/FilterModal/FilterModal'; import GlobalModal from '../GlobalModal/GlobalModal'; -const VideoList: React.FC = ({ - videos, - titleSearch, - handleVideoIsUnlocked -}) => { - const loading = useSelector( - (state) => state.videosStore.loading +const VideoList: React.FC = ({ titleSearch }) => { + const { videoListStatus, totalVideos, videos } = useAppSelector( + (state) => state.videos ); const { width } = useWindowDimensions(); const isMobileDesign = width < 1100; @@ -28,7 +24,7 @@ const VideoList: React.FC = ({ const { globalModalState } = useContext(GlobalModalContext); - if (loading) { + if (videoListStatus !== dataStatuses.Complete) { return ; } @@ -39,39 +35,24 @@ const VideoList: React.FC = ({ transition: 'all .2s ease', width: '100%' }}> - {/*
*/}
- {videos ? ( - Object.keys(videos).length > 0 ? ( - Object.keys(videos) - .filter((item) => - videos[item].title - .toLowerCase() - .includes(titleSearch.toLowerCase()) - ) - .map((item) => { - return ( - - ); - }) - ) : ( -

No videos found

- ) + {totalVideos === 0 ? ( +

No videos found

) : ( - 'Searching...' + videos + .filter((video) => + video.title.toLowerCase().includes(titleSearch.toLowerCase()) + ) + .map((video, index) => { + return ; + }) )}
diff --git a/rair-front/src/components/video/videoOfferBuy.tsx b/rair-front/src/components/video/videoOfferBuy.tsx index 7e334675a..60d33fa7b 100644 --- a/rair-front/src/components/video/videoOfferBuy.tsx +++ b/rair-front/src/components/video/videoOfferBuy.tsx @@ -1,11 +1,9 @@ import { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; import { useNavigate } from 'react-router'; import { TVideoItemContractData } from './video.types'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../hooks/useReduxHooks'; import { rFetch } from '../../utils/rFetch'; import CustomButton from '../MockUpPage/utils/button/CustomButton'; @@ -13,9 +11,7 @@ const OfferBuyButton = ({ offerName, contract, product }) => { const [contractData, setContractData] = useState(); const navigate = useNavigate(); - const { primaryColor } = useSelector( - (store) => store.colorStore - ); + const { primaryColor } = useAppSelector((store) => store.colors); const fetchContractData = useCallback(async () => { const data = await rFetch(`/api/contracts/${contract}`); diff --git a/rair-front/src/components/video/videoUpload/adminView.tsx b/rair-front/src/components/video/videoUpload/adminView.tsx deleted file mode 100644 index c51e74c30..000000000 --- a/rair-front/src/components/video/videoUpload/adminView.tsx +++ /dev/null @@ -1,174 +0,0 @@ -import { useCallback, useEffect, useState } from 'react'; -import { faTrash } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import axios from 'axios'; -import { v1 } from 'uuid'; - -import InputSelect from '../../common/InputSelect'; - -const AdminView = ({ - primaryColor, - contractOptions, - reusableStyle, - getFullContractData -}) => { - const [selectedContracts, setSelectedContracts] = useState(['null']); - const options = contractOptions && contractOptions; - - const [disabledOptions, setDisabledOptions] = useState(); - const [hiddenContracts, setHiddenContracts] = useState(); - const [loading, setLoading] = useState(false); - - const showHiddenContracts = useCallback((listContract) => { - setHiddenContracts( - listContract.filter( - (contract) => contract.blockSync && contract.blockView - ) - ); - }, []); - - const offOrOnContract = useCallback( - async (contract: string, option: string) => { - setLoading(true); - switch (option) { - case 'off': - await axios.patch( - `/api/contracts/${contract}`, - { - blockSync: true, - blockView: true - }, - { - headers: { - Accept: 'application/json' - } - } - ); - getFullContractData(); - setLoading(false); - break; - case 'on': - await axios.patch( - `/api/contracts/${contract}`, - { - blockSync: false, - blockView: false - }, - { - headers: { - Accept: 'application/json' - } - } - ); - getFullContractData(); - setLoading(false); - break; - } - }, - [getFullContractData] - ); - - const createEmptyInput = () => { - setSelectedContracts([...selectedContracts, 'null']); - }; - - const removeInput = (id) => { - const array = selectedContracts.filter((item, index) => index !== id); - setSelectedContracts(array); - }; - - const selectContract = (value, index) => { - const tempArr = [...selectedContracts]; - tempArr[index] = value; - setSelectedContracts([...tempArr]); - setDisabledOptions( - disabledOptions && - disabledOptions.filter( - (option) => option !== 'null' && option.value !== value - ) - ); - }; - - useEffect(() => { - showHiddenContracts(contractOptions); - }, [contractOptions, showHiddenContracts]); - - useEffect(() => { - setDisabledOptions(options); - }, [options]); - - return ( -
-
- - - - - - - - {hiddenContracts && - hiddenContracts.map((o) => ( - - - - - ))} -
HiddenShown
- {o.label} - - -
-
-
- {selectedContracts.map((item: string, index: number) => { - return ( -
- selectContract(e, index)} - placeholder="Select contract that needs to be hidden" - options={options.filter((el) => !el.blockView && !el.blockSync)} - /> -
- - - -
-
- ); - })} - -
-
- ); -}; - -export default AdminView; diff --git a/rair-front/src/components/video/videoUpload/videoUpload.css b/rair-front/src/components/video/videoUpload/videoUpload.css deleted file mode 100644 index 644145582..000000000 --- a/rair-front/src/components/video/videoUpload/videoUpload.css +++ /dev/null @@ -1,132 +0,0 @@ -.addButton { - border-radius: 50%; - width: 30px; - float: right; - margin-bottom: -30px; - margin-top: -34px; - margin-right: -35px; - border: 1px solid #4e4d4d; -} -.addButton:hover { - background: linear-gradient( - 96.34deg, - #725bdb 0%, - #805fda 10.31%, - #8c63da 20.63%, - #9867d9 30.94%, - #a46bd9 41.25%, - #af6fd8 51.56%, - #af6fd8 51.56%, - #bb73d7 61.25%, - #c776d7 70.94%, - #d27ad6 80.62%, - #dd7ed6 90.31%, - #e882d5 100% - ); -} -.btn-submit-custom { - margin-top: 0.5rem; - background: linear-gradient( - 96.34deg, - #725bdb 0%, - #805fda 10.31%, - #8c63da 20.63%, - #9867d9 30.94%, - #a46bd9 41.25%, - #af6fd8 51.56%, - #af6fd8 51.56%, - #bb73d7 61.25%, - #c776d7 70.94%, - #d27ad6 80.62%, - #dd7ed6 90.31%, - #e882d5 100% - ); -} -.hidden-block-wrapper { - display: flex; - justify-content: space-around; - padding: 30px 230px 50px; -} -.hidden-table-col-one { - color: rgb(211, 47, 47); -} -.hidden-table-col-two { - color: rgb(46, 125, 50); -} -.hidden-table-title { - color: var(--rhyno); -} - -.hidden-table-title.rhyno { - color: var(--charcoal); -} - -.hidden-table-button { - background-color: rgb(46, 125, 50); - border-radius: 12px; - padding: 5px 10px; - color: #fff; - border: 1px solid #fff; -} - -.hidden-table-button:hover { - background: rgb(27, 94, 32); -} - -.hidden-input-wrapper { - display: flex; - flex-direction: column; - margin: auto; - width: 70%; -} -.hidden-options-wrapper { - display: flex; - padding-top: 10px; - margin-bottom: 20px; - justify-content: space-evenly; -} -.hidden-options-button { - background-color: rgb(211, 47, 47); - border-radius: 12px; - padding: 5px 10px; - color: #fff; - border: 1px solid #fff; -} - -.hidden-options-button:hover { - background: rgb(168, 50, 50); -} - -.hidden-block-wrapper .add_contact { - padding: 5px 10px; - border-radius: 12px; - background: var(--stimorol); - color: #fff; - border: 1px solid #fff; -} - -.hidden-block-wrapper .add_contact:hover { - background: var(--stimorol-hover); -} - -.hidden-block-wrapper .add_contact:focus, -.hidden-block-wrapper .add_contact:active { - background: var(--stimorol-click); -} - -.hidden-block-wrapper .hidden-contracts-table { - height: 600px !important; - overflow: auto; -} - -.hidden-block-wrapper - .hidden-options-wrapper - button.hidden-options-button:disabled { - background: rgb(168, 50, 50); -} - -.hidden-block-wrapper - .hidden-options-wrapper - button.hidden-table-button:disabled { - background: rgb(27, 94, 32); -} diff --git a/rair-front/src/components/video/videoUpload/videoUpload.tsx b/rair-front/src/components/video/videoUpload/videoUpload.tsx deleted file mode 100644 index 26ef658d4..000000000 --- a/rair-front/src/components/video/videoUpload/videoUpload.tsx +++ /dev/null @@ -1,312 +0,0 @@ -/* eslint-disable no-console */ -//@ts-nocheck -import { useCallback, useEffect, useState } from 'react'; -import axios from 'axios'; -import io from 'socket.io-client'; -import Swal from 'sweetalert2'; - -import AdminView from './adminView'; - -import { - // TAuthGetChallengeResponse, - TUploadSocket -} from '../../../axios.responseTypes'; -import { getRandomValues } from '../../../utils/getRandomValues'; -import { rFetch } from '../../../utils/rFetch'; -import BlockChainSwitcher from '../../adminViews/BlockchainSwitcher'; -import ServerSettings from '../../adminViews/ServerSettings'; -import InputField from '../../common/InputField'; -import InputSelect from '../../common/InputSelect'; - -import './videoUpload.css'; -// const UPLOAD_PROGRESS_HOST = import.meta.env.VITE_UPLOAD_PROGRESS_HOST; - -//TODO: alternative env -// const hostname = window.location.hostname; -// console.log(hostname, 'hostname'); - -// Admin view to upload media to the server -const FileUpload = ({ /*address,*/ primaryColor, textColor }) => { - const [fullContractData, setFullContractData] = useState({}); - // const [contractID, setContractID] = useState('null'); - const [selectedOffers, setSelectedOffers] = useState([]); - - const [title, setTitle] = useState(''); - const [description, setDescription] = useState(''); - const [video, setVideo] = useState(undefined); - const [uploading, setUploading] = useState(false); - // const [adminNFT, setAdminNFT] = useState(''); - const [thisSessionId, setThisSessionId] = useState(''); - const [socket, setSocket] = useState(null); - const [status, setStatus] = useState(0); - const [message, setMessage] = useState(0); - const [, /*part,*/ setPart] = useState(0); - const [, setVPV] = useState(); - const [product, setProduct] = useState('null'); - const [productOptions, setProductOptions] = useState(); - const [offersOptions, setOffersOptions] = useState(); - const [offer, setOffer] = useState('null'); - const [, /*countOfSelects*/ setCountOfSelects] = useState(0); - const [, /*selects*/ setSelects] = useState([]); - const [selectsData /*setSelectsData*/] = useState({}); - const [contract, setContract] = useState('null'); - const [category, setCategory] = useState('null'); - const [storage, setStorage] = useState('null'); - const [contractOptions, setContractOptions] = useState([]); - const [offersData /*setOffersData*/] = useState([]); - const [, /*collectionIndex*/ setCollectionIndex] = useState({}); - const [, /*offersIndex,*/ setOffersIndex] = useState([]); - const [, /*networkId*/ setNetworkId] = useState(''); - - const [categoryArray, setCategoryArray] = useState([]); - const getCategories = useCallback(async () => { - const { success, categories } = await rFetch('/api/files/categories'); - if (success) { - setCategoryArray( - categories.map((item) => { - return { label: item.name, value: item.name }; - }) - ); - } - }, []); - - // const currentUserAddress = useSelector( - // (state) => state.contractStore.currentUserAddress - // ); - - useEffect(() => { - getCategories(); - }, [getCategories]); - - const getFullContractData = useCallback(async () => { - const request = await rFetch( - '/api/contracts/full?itemsPerPage=5&hidden=true' - ); - if (request.success) { - const { success, contracts } = await rFetch( - `/api/contracts/full?itemsPerPage=${ - request.totalNumber || '5' - }&hidden=true` - ); - if (success) { - const mapping = {}; - const options = []; - contracts.forEach((item) => { - const offerMapping = {}; - item.products.offers.forEach((offer) => { - offerMapping[ - offer[item.diamond ? 'diamondRangeIndex' : 'offerIndex'] - ] = offer; - }); - item.products.offers = offerMapping; - - if (mapping[item._id] !== undefined) { - mapping[item._id].products[ - item.products.collectionIndexInContract - ] = item.products; - } else { - const productMapping = {}; - productMapping[item.products.collectionIndexInContract] = - item.products; - item.products = productMapping; - mapping[item._id] = item; - options.push({ - label: `${item.title} (${ - item.external - ? 'External' - : item.diamond - ? 'Diamond' - : 'Classic' - })`, - value: item._id, - blockSync: item.blockSync, - blockView: item.blockView - }); - } - }); - - setFullContractData(mapping); - setContractOptions( - options.sort((a, b) => - a.label.toLowerCase() >= b.label.toLowerCase() ? 1 : -1 - ) - ); - } - } - }, []); - - useEffect(() => { - getFullContractData(); - }, [getFullContractData]); - - const getProduct = useCallback(async () => { - setProductOptions( - Object.keys(fullContractData[contract].products).map((key) => { - return { - label: fullContractData[contract].products[key].name, - value: - fullContractData[contract].products[key].collectionIndexInContract - }; - }) - ); - }, [contract, fullContractData]); - - useEffect(() => { - if (contract !== 'null') { - setProduct('null'); - getProduct(); - } - }, [contract, getProduct]); - - const getOffers = useCallback(async () => { - setOffersOptions( - Object.keys(fullContractData[contract].products[product].offers).map( - (key) => { - return { - label: - fullContractData[contract].products[product].offers[key] - .offerName, - value: - fullContractData[contract].products[product].offers[key][ - fullContractData[contract].diamond - ? 'diamondRangeIndex' - : 'offerIndex' - ] - }; - } - ) - ); - }, [contract, fullContractData, product]); - - const isOffersGet = useCallback(async () => { - if (product !== 'null') { - setSelectedOffers(['null']); - const offers = await getOffers(); - setCountOfSelects(offers?.length - 1); - } - }, [product, getOffers]); - - useEffect(() => { - isOffersGet(); - }, [isOffersGet]); - - useEffect(() => { - if (selectsData) { - Object.keys(selectsData).forEach((names) => { - offersData.forEach((offers) => { - if (selectsData[names] === offers.offerName) { - setOffersIndex((prev) => [...prev, offers.offerIndex]); - } - }); - }); - } - }, [selectsData, offer, offersData, setOffersIndex]); - - const goSession = useCallback(async () => { - const sessionId = getRandomValues().toString(36).slice(2, 9); - setThisSessionId(sessionId); - const so = io(); - // const so = io(`http://localhost:5000`, { transports: ["websocket"] }); - setSocket(so); - // so.on("connect", data => { - // console.log('Connected !'); - // }); - so.emit('init', sessionId); - - return () => { - so.emit('end', sessionId); - }; - }, []); - - useEffect(() => { - goSession(); - }, [goSession]); - - if (socket) { - socket.removeListener('uploadProgress'); - socket.on('uploadProgress', (data) => { - if (data.part) { - setPart(getRandomValues() / 10); - } - - if (data.done) { - setStatus(data.done); - } - - if (data.part) { - setStatus(getRandomValues() / 10); - } - - setMessage(data.message); - - if (data.last) { - socket.emit('end', thisSessionId); - Swal.fire('Success', 'Your file is being processed', 'success'); - setUploading(false); - setStatus(0); - setTitle(''); - setDescription(''); - setVideo(undefined); - setOffersIndex([]); - setCollectionIndex({}); - setCategory('null'); - setStorage('null'); - setContractOptions([]); - setProductOptions(); - setOffersOptions(); - document.getElementById('media_id').value = ''; - setMessage(0); - getFullContractData(); - } - }); - } - - // const handleChangeSelects = (value, name) => { - // setSelectsData({ - // ...selectsData, - // [name]: value - // }); - // }; - - const createSelects = () => { - const aux = [...selectedOffers]; - aux.push('null'); - setSelectedOffers(aux); - }; - - const handleOffer = (key, value) => { - const aux = [...selectedOffers]; - aux[key] = value; - setSelectedOffers(aux); - }; - - const reusableStyle = { - backgroundColor: primaryColor, - color: `var(--${textColor})` - }; - - const verifyOffer = () => { - return selectedOffers.reduce((prev, current) => { - return prev && current === 'null'; - }, true); - }; - - return ( - <> - - -
-
- -
- - ); -}; - -export default FileUpload; diff --git a/rair-front/src/components/videoManager/OfferSelector.tsx b/rair-front/src/components/videoManager/OfferSelector.tsx index cf124a15c..3fdc1ddc0 100644 --- a/rair-front/src/components/videoManager/OfferSelector.tsx +++ b/rair-front/src/components/videoManager/OfferSelector.tsx @@ -1,11 +1,9 @@ import { useCallback, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; import useSwal from '../../hooks/useSwal'; import { rFetch } from '../../utils/rFetch'; -import useServerSettings from '../adminViews/useServerSettings'; import InputSelect from '../common/InputSelect'; const OfferSelector = ({ fileId }) => { @@ -18,10 +16,9 @@ const OfferSelector = ({ fileId }) => { const reactSwal = useSwal(); const { getBlockchainData } = useServerSettings(); - const { textColor, secondaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { textColor, secondaryButtonColor } = useAppSelector( + (store) => store.colors + ); useEffect(() => { (async () => { @@ -34,8 +31,9 @@ const OfferSelector = ({ fileId }) => { setContractOptions( result .map((contract) => ({ - label: `${contract.title} (${getBlockchainData(contract.blockchain) - ?.symbol})`, + label: `${contract.title} (${ + getBlockchainData(contract.blockchain)?.symbol + })`, value: contract._id })) .sort((a, b) => { diff --git a/rair-front/src/components/videoManager/VideoManager.tsx b/rair-front/src/components/videoManager/VideoManager.tsx index 968bbac6b..80e376fff 100644 --- a/rair-front/src/components/videoManager/VideoManager.tsx +++ b/rair-front/src/components/videoManager/VideoManager.tsx @@ -1,19 +1,17 @@ import { useCallback, useEffect, useState } from 'react'; -import { Provider, useSelector, useStore } from 'react-redux'; +import { Provider, useStore } from 'react-redux'; import { faTrash } from '@fortawesome/free-solid-svg-icons'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { formatEther } from 'ethers/lib/utils'; import OfferSelector from './OfferSelector'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; +import { useAppSelector } from '../../hooks/useReduxHooks'; +import useServerSettings from '../../hooks/useServerSettings'; import useSwal from '../../hooks/useSwal'; import { rFetch } from '../../utils/rFetch'; -import useServerSettings from '../adminViews/useServerSettings'; import InputField from '../common/InputField'; import AnalyticsPopUp from '../DemoMediaUpload/UploadedListBox/AnalyticsPopUp/AnalyticsPopUp'; +import { formatEther } from 'ethers'; const VideoManager = () => { const [uploads, setUploads] = useState([]); @@ -23,13 +21,9 @@ const VideoManager = () => { const [filter, setFilter] = useState(''); const [selectedFile, setSelectedFile] = useState({}); - const { currentUserAddress } = useSelector( - (store) => store.contractStore - ); - const { textColor, primaryButtonColor, secondaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { currentUserAddress } = useAppSelector((store) => store.web3); + const { textColor, primaryButtonColor, secondaryButtonColor } = + useAppSelector((store) => store.colors); const { getBlockchainData } = useServerSettings(); diff --git a/rair-front/src/contracts/diamondMarketplaceABI.json b/rair-front/src/contracts/diamondMarketplaceABI.json index 8ff2897fa..686e6be6a 100644 --- a/rair-front/src/contracts/diamondMarketplaceABI.json +++ b/rair-front/src/contracts/diamondMarketplaceABI.json @@ -1 +1 @@ -{"address":"0x1F89Cc515dDc53dA2fac5B0Ca3b322066A71E6BA","abi":[{"inputs":[{"internalType":"address","name":"_initializationContractAddress","type":"address"},{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"InitializationFunctionReverted","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"enum IDiamondCut.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"indexed":false,"internalType":"struct IDiamondCut.FacetCut[]","name":"_diamondCut","type":"tuple[]"},{"indexed":false,"internalType":"address","name":"_init","type":"address"},{"indexed":false,"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"DiamondCut","type":"event"},{"inputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"enum IDiamondCut.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"internalType":"struct IDiamondCut.FacetCut[]","name":"_diamondCut","type":"tuple[]"},{"internalType":"address","name":"_init","type":"address"},{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"diamondCut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_functionSelector","type":"bytes4"}],"name":"facetAddress","outputs":[{"internalType":"address","name":"facetAddress_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facetAddresses","outputs":[{"internalType":"address[]","name":"facetAddresses_","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_facet","type":"address"}],"name":"facetFunctionSelectors","outputs":[{"internalType":"bytes4[]","name":"_facetFunctionSelectors","type":"bytes4[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facets","outputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"internalType":"struct IDiamondLoupe.Facet[]","name":"facets_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"length","type":"uint256"}],"name":"StringsInsufficientHexLength","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"indexed":false,"internalType":"string","name":"rangeName","type":"string"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeSplitsLength","type":"uint256"},{"indexed":false,"internalType":"bool","name":"visible","type":"bool"},{"indexed":false,"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"AddedMintingOffer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"}],"name":"MintedToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeSplitsLength","type":"uint256"},{"indexed":false,"internalType":"bool","name":"visible","type":"bool"},{"indexed":false,"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"UpdatedMintingOffer","type":"event"},{"inputs":[{"internalType":"address","name":"erc721Address_","type":"address"},{"internalType":"uint256","name":"rangeIndex_","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[]","name":"splits","type":"tuple[]"},{"internalType":"bool","name":"visible_","type":"bool"},{"internalType":"address","name":"nodeAddress_","type":"address"}],"name":"addMintingOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc721Address_","type":"address"},{"internalType":"uint256[]","name":"rangeIndexes","type":"uint256[]"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[][]","name":"splits","type":"tuple[][]"},{"internalType":"bool[]","name":"visibility","type":"bool[]"},{"internalType":"address","name":"nodeAddress_","type":"address"}],"name":"addMintingOfferBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex_","type":"uint256"},{"internalType":"uint256","name":"tokenIndex_","type":"uint256"}],"name":"buyMintingOffer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex_","type":"uint256"},{"internalType":"uint256[]","name":"tokenIndexes","type":"uint256[]"},{"internalType":"address[]","name":"recipients","type":"address[]"}],"name":"buyMintingOfferBatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"getOfferInfo","outputs":[{"components":[{"internalType":"address","name":"erc721Address","type":"address"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[]","name":"fees","type":"tuple[]"},{"internalType":"bool","name":"visible","type":"bool"}],"internalType":"struct mintingOffer","name":"mintOffer","type":"tuple"},{"components":[{"internalType":"uint256","name":"rangeStart","type":"uint256"},{"internalType":"uint256","name":"rangeEnd","type":"uint256"},{"internalType":"uint256","name":"tokensAllowed","type":"uint256"},{"internalType":"uint256","name":"mintableTokens","type":"uint256"},{"internalType":"uint256","name":"lockedTokens","type":"uint256"},{"internalType":"uint256","name":"rangePrice","type":"uint256"},{"internalType":"string","name":"rangeName","type":"string"}],"internalType":"struct IRAIR721.range","name":"rangeData","type":"tuple"},{"internalType":"uint256","name":"productIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc721Address","type":"address"},{"internalType":"uint256","name":"rangeIndex","type":"uint256"}],"name":"getOfferInfoForAddress","outputs":[{"internalType":"uint256","name":"offerIndex","type":"uint256"},{"components":[{"internalType":"address","name":"erc721Address","type":"address"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[]","name":"fees","type":"tuple[]"},{"internalType":"bool","name":"visible","type":"bool"}],"internalType":"struct mintingOffer","name":"mintOffer","type":"tuple"},{"components":[{"internalType":"uint256","name":"rangeStart","type":"uint256"},{"internalType":"uint256","name":"rangeEnd","type":"uint256"},{"internalType":"uint256","name":"tokensAllowed","type":"uint256"},{"internalType":"uint256","name":"mintableTokens","type":"uint256"},{"internalType":"uint256","name":"lockedTokens","type":"uint256"},{"internalType":"uint256","name":"rangePrice","type":"uint256"},{"internalType":"string","name":"rangeName","type":"string"}],"internalType":"struct IRAIR721.range","name":"rangeData","type":"tuple"},{"internalType":"uint256","name":"productIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc721Address","type":"address"}],"name":"getOffersCountForAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalOfferCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"mintingOfferId_","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[]","name":"splits_","type":"tuple[]"},{"internalType":"bool","name":"visible_","type":"bool"}],"name":"updateMintingOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"decimals","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"precalculatedMultiplier","type":"uint256"}],"name":"UpdatedDecimals","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"decimals","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newPercentage","type":"uint256"}],"name":"UpdatedNodeFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAddress","type":"address"}],"name":"UpdatedTreasuryAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"decimals","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newPercentage","type":"uint256"}],"name":"UpdatedTreasuryFee","type":"event"},{"inputs":[],"name":"MAINTAINER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDecimals","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNodeFee","outputs":[{"internalType":"uint16","name":"decimals","type":"uint16"},{"internalType":"uint256","name":"nodeFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTreasuryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTreasuryFee","outputs":[{"internalType":"uint16","name":"decimals","type":"uint16"},{"internalType":"uint256","name":"treasuryFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"newDecimals_","type":"uint16"}],"name":"updateDecimals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFee_","type":"uint256"}],"name":"updateNodeFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress_","type":"address"}],"name":"updateTreasuryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFee_","type":"uint256"}],"name":"updateTreasuryFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"uint256","name":"token","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"offerId","type":"uint256"}],"name":"TokenOfferCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"uint256","name":"token","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenPrice","type":"uint256"}],"name":"TokenSold","type":"event"},{"inputs":[],"name":"RESALE_ADMIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"},{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"tokenPrice","type":"uint256"},{"internalType":"address","name":"nodeAddress","type":"address"}],"name":"createGasTokenOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"},{"internalType":"address","name":"buyer","type":"address"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"tokenPrice","type":"uint256"},{"internalType":"address","name":"nodeAddress","type":"address"}],"name":"generateResaleHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"}],"name":"getRoyalties","outputs":[{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct ResaleStorage.feeSplits[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"purchaseGasTokenOffer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"},{"internalType":"address","name":"buyer","type":"address"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"tokenPrice","type":"uint256"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"purchaseTokenOffer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setDecimalPow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setPurchaseGracePeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct ResaleStorage.feeSplits[]","name":"fees","type":"tuple[]"}],"name":"setRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file +{"address":"0x58795f50b50d492C4252B9BBF78485EF4043FF3E","abi":[{"inputs":[{"internalType":"address","name":"_initializationContractAddress","type":"address"},{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"InitializationFunctionReverted","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"enum IDiamondCut.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"indexed":false,"internalType":"struct IDiamondCut.FacetCut[]","name":"_diamondCut","type":"tuple[]"},{"indexed":false,"internalType":"address","name":"_init","type":"address"},{"indexed":false,"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"DiamondCut","type":"event"},{"inputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"enum IDiamondCut.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"internalType":"struct IDiamondCut.FacetCut[]","name":"_diamondCut","type":"tuple[]"},{"internalType":"address","name":"_init","type":"address"},{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"diamondCut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_functionSelector","type":"bytes4"}],"name":"facetAddress","outputs":[{"internalType":"address","name":"facetAddress_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facetAddresses","outputs":[{"internalType":"address[]","name":"facetAddresses_","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_facet","type":"address"}],"name":"facetFunctionSelectors","outputs":[{"internalType":"bytes4[]","name":"_facetFunctionSelectors","type":"bytes4[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facets","outputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"internalType":"struct IDiamondLoupe.Facet[]","name":"facets_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"length","type":"uint256"}],"name":"StringsInsufficientHexLength","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"indexed":false,"internalType":"string","name":"rangeName","type":"string"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeSplitsLength","type":"uint256"},{"indexed":false,"internalType":"bool","name":"visible","type":"bool"},{"indexed":false,"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"AddedMintingOffer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"}],"name":"MintedToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeSplitsLength","type":"uint256"},{"indexed":false,"internalType":"bool","name":"visible","type":"bool"},{"indexed":false,"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"UpdatedMintingOffer","type":"event"},{"inputs":[{"internalType":"address","name":"erc721Address_","type":"address"},{"internalType":"uint256","name":"rangeIndex_","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[]","name":"splits","type":"tuple[]"},{"internalType":"bool","name":"visible_","type":"bool"},{"internalType":"address","name":"nodeAddress_","type":"address"}],"name":"addMintingOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc721Address_","type":"address"},{"internalType":"uint256[]","name":"rangeIndexes","type":"uint256[]"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[][]","name":"splits","type":"tuple[][]"},{"internalType":"bool[]","name":"visibility","type":"bool[]"},{"internalType":"address","name":"nodeAddress_","type":"address"}],"name":"addMintingOfferBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex_","type":"uint256"},{"internalType":"uint256","name":"tokenIndex_","type":"uint256"}],"name":"buyMintingOffer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex_","type":"uint256"},{"internalType":"uint256[]","name":"tokenIndexes","type":"uint256[]"},{"internalType":"address[]","name":"recipients","type":"address[]"}],"name":"buyMintingOfferBatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"getOfferInfo","outputs":[{"components":[{"internalType":"address","name":"erc721Address","type":"address"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[]","name":"fees","type":"tuple[]"},{"internalType":"bool","name":"visible","type":"bool"}],"internalType":"struct mintingOffer","name":"mintOffer","type":"tuple"},{"components":[{"internalType":"uint256","name":"rangeStart","type":"uint256"},{"internalType":"uint256","name":"rangeEnd","type":"uint256"},{"internalType":"uint256","name":"tokensAllowed","type":"uint256"},{"internalType":"uint256","name":"mintableTokens","type":"uint256"},{"internalType":"uint256","name":"lockedTokens","type":"uint256"},{"internalType":"uint256","name":"rangePrice","type":"uint256"},{"internalType":"string","name":"rangeName","type":"string"}],"internalType":"struct IRAIR721.range","name":"rangeData","type":"tuple"},{"internalType":"uint256","name":"productIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc721Address","type":"address"},{"internalType":"uint256","name":"rangeIndex","type":"uint256"}],"name":"getOfferInfoForAddress","outputs":[{"internalType":"uint256","name":"offerIndex","type":"uint256"},{"components":[{"internalType":"address","name":"erc721Address","type":"address"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[]","name":"fees","type":"tuple[]"},{"internalType":"bool","name":"visible","type":"bool"}],"internalType":"struct mintingOffer","name":"mintOffer","type":"tuple"},{"components":[{"internalType":"uint256","name":"rangeStart","type":"uint256"},{"internalType":"uint256","name":"rangeEnd","type":"uint256"},{"internalType":"uint256","name":"tokensAllowed","type":"uint256"},{"internalType":"uint256","name":"mintableTokens","type":"uint256"},{"internalType":"uint256","name":"lockedTokens","type":"uint256"},{"internalType":"uint256","name":"rangePrice","type":"uint256"},{"internalType":"string","name":"rangeName","type":"string"}],"internalType":"struct IRAIR721.range","name":"rangeData","type":"tuple"},{"internalType":"uint256","name":"productIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc721Address","type":"address"}],"name":"getOffersCountForAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalOfferCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"mintingOfferId_","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[]","name":"splits_","type":"tuple[]"},{"internalType":"bool","name":"visible_","type":"bool"}],"name":"updateMintingOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"decimals","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"precalculatedMultiplier","type":"uint256"}],"name":"UpdatedDecimals","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"decimals","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newPercentage","type":"uint256"}],"name":"UpdatedNodeFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAddress","type":"address"}],"name":"UpdatedTreasuryAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"decimals","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newPercentage","type":"uint256"}],"name":"UpdatedTreasuryFee","type":"event"},{"inputs":[],"name":"MAINTAINER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDecimals","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNodeFee","outputs":[{"internalType":"uint16","name":"decimals","type":"uint16"},{"internalType":"uint256","name":"nodeFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTreasuryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTreasuryFee","outputs":[{"internalType":"uint16","name":"decimals","type":"uint16"},{"internalType":"uint256","name":"treasuryFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"newDecimals_","type":"uint16"}],"name":"updateDecimals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFee_","type":"uint256"}],"name":"updateNodeFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress_","type":"address"}],"name":"updateTreasuryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFee_","type":"uint256"}],"name":"updateTreasuryFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"uint256","name":"token","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"offerId","type":"uint256"}],"name":"TokenOfferCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"offerId","type":"uint256"}],"name":"TokenOfferDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"offerId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTokenPrice","type":"uint256"}],"name":"TokenOfferUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"uint256","name":"token","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenPrice","type":"uint256"}],"name":"TokenSold","type":"event"},{"inputs":[],"name":"RESALE_ADMIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"},{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"tokenPrice","type":"uint256"},{"internalType":"address","name":"nodeAddress","type":"address"}],"name":"createGasTokenOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"deleteGasTokenOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"},{"internalType":"address","name":"buyer","type":"address"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"tokenPrice","type":"uint256"},{"internalType":"address","name":"nodeAddress","type":"address"}],"name":"generateResaleHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"getResaleOffer","outputs":[{"components":[{"internalType":"address","name":"erc721","type":"address"},{"internalType":"address","name":"buyer","type":"address"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"tokenPrice","type":"uint256"},{"internalType":"address","name":"nodeAddress","type":"address"}],"internalType":"struct ResaleStorage.resaleOffer","name":"offer","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"}],"name":"getRoyalties","outputs":[{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct ResaleStorage.feeSplits[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"purchaseGasTokenOffer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"},{"internalType":"address","name":"buyer","type":"address"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"tokenPrice","type":"uint256"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"purchaseTokenOffer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setDecimalPow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setPurchaseGracePeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct ResaleStorage.feeSplits[]","name":"fees","type":"tuple[]"}],"name":"setRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex","type":"uint256"},{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"updateGasTokenOffer","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/rair-front/src/contracts/index.ts b/rair-front/src/contracts/index.ts index 338dcec01..4666233f6 100644 --- a/rair-front/src/contracts/index.ts +++ b/rair-front/src/contracts/index.ts @@ -1,24 +1,40 @@ -//@ts-nocheck -import * as CreditHandler from './CreditHandlerABI.json'; -import * as DiamondFactory from './diamondFactoryABI.json'; -import * as DiamondMarketplace from './diamondMarketplaceABI.json'; -import * as DiamondERC721 from './diamondRAIR721ABI.json'; -import * as LicenseExchange from './LicenseExchangeABI.json'; -import * as MinterMarketplace from './Minter_Marketplace.json'; -import * as ERC721Token from './RAIR_ERC721.json'; -import * as Factory from './RAIR_Token_Factory.json'; -import * as TokenPurchaser from './RAIR_Token_Purchaser.json'; -import * as ERC777 from './RAIR777.json'; -import * as ResaleMarketplace from './Resale_Marketplace.json'; +import CreditHandler from './CreditHandlerABI.json'; +import DiamondFactory from './diamondFactoryABI.json'; +import DiamondMarketplace from './diamondMarketplaceABI.json'; +import DiamondERC721 from './diamondRAIR721ABI.json'; +import LicenseExchange from './LicenseExchangeABI.json'; +import MinterMarketplace from './Minter_Marketplace.json'; +import ERC721Token from './RAIR_ERC721.json'; +import Factory from './RAIR_Token_Factory.json'; +import TokenPurchaser from './RAIR_Token_Purchaser.json'; +import ERC777 from './RAIR777.json'; +import ResaleMarketplace from './Resale_Marketplace.json'; -export const diamond721Abi = DiamondERC721.default.abi; -export const diamondFactoryAbi = DiamondFactory.default.abi; -export const diamondMarketplaceAbi = DiamondMarketplace.default.abi; -export const erc721Abi = ERC721Token.default.abi; -export const minterAbi = MinterMarketplace.default.abi; -export const resaleAbi = ResaleMarketplace.default.abi; -export const factoryAbi = Factory.default.abi; -export const erc777Abi = ERC777.default.abi; -export const tokenPurchaserAbi = TokenPurchaser.default.abi; -export const creditHandlerAbi = CreditHandler.default.abi; -export const licenseExchangeABI = LicenseExchange.default.abi; +interface FunctionParameter { + indexed?: boolean; + internalType: string; + name: string; + type: string; +} + +interface AbiFragment { + anonymous?: boolean; + inputs?: FunctionParameter[]; + outputs?: FunctionParameter[]; + stateMutability?: string; + name?: string; + type: string; +} + +export type ContractABI = AbiFragment[]; +export const diamond721Abi: ContractABI = DiamondERC721.abi; +export const diamondFactoryAbi: ContractABI = DiamondFactory.abi; +export const diamondMarketplaceAbi: ContractABI = DiamondMarketplace.abi; +export const erc721Abi: ContractABI = ERC721Token.abi; +export const minterAbi: ContractABI = MinterMarketplace.abi; +export const resaleAbi: ContractABI = ResaleMarketplace.abi; +export const factoryAbi: ContractABI = Factory.abi; +export const erc777Abi: ContractABI = ERC777.abi; +export const tokenPurchaserAbi: ContractABI = TokenPurchaser.abi; +export const creditHandlerAbi: ContractABI = CreditHandler.abi; +export const licenseExchangeABI: ContractABI = LicenseExchange.abi; diff --git a/rair-front/src/ducks/auth/actions.ts b/rair-front/src/ducks/auth/actions.ts deleted file mode 100644 index 415584d2e..000000000 --- a/rair-front/src/ducks/auth/actions.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ethers } from 'ethers'; - -import * as types from './types'; - -//unused-snippet -const getProviderStart = () => ({ type: types.GET_PROVIDER_START }) as const; - -const getProviderComplete = (provider: ethers.providers.Web3Provider | null) => - ({ type: types.GET_PROVIDER_COMPLETE, provider }) as const; - -const getProviderError = (error: string | null) => - ({ type: types.GET_PROVIDER_ERROR, error }) as const; - -const getTokenStart = () => ({ type: types.GET_TOKEN_START }) as const; - -const getTokenComplete = (token: string | null) => - ({ type: types.GET_TOKEN_COMPLETE, token }) as const; - -const getTokenError = (error: boolean | null) => - ({ type: types.GET_TOKEN_ERROR, error }) as const; - -//unused-snippet -const getPublicAddressComplete = (publicAddress: string | null) => - ({ type: types.GET_PUBLIC_ADDRESS_COMPLETE, publicAddress }) as const; - -export { - getProviderComplete, - getProviderError, - getProviderStart, - getPublicAddressComplete, - getTokenComplete, - getTokenError, - getTokenStart -}; diff --git a/rair-front/src/ducks/auth/auth.types.ts b/rair-front/src/ducks/auth/auth.types.ts deleted file mode 100644 index e0b510ee0..000000000 --- a/rair-front/src/ducks/auth/auth.types.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { ethers } from 'ethers'; - -import { - getProviderComplete, - getProviderError, - getProviderStart, - getPublicAddressComplete, - getTokenComplete, - getTokenError, - getTokenStart -} from './actions'; - -export type TAuthInitialState = { - error: string | boolean | null; - provider: ethers.providers.Web3Provider | null; - token: string | null; - publicAddress: string | null; -}; - -export type TGetProviderStart = ReturnType; -export type TGetProviderComplete = ReturnType; -export type TGetProviderError = ReturnType; -export type TGetTokenStart = ReturnType; -export type TGetTokenComplete = ReturnType; -export type TGetTokenError = ReturnType; -export type TGetPublicAddressComplete = ReturnType< - typeof getPublicAddressComplete ->; - -export type TAuthActionsType = - | TGetProviderStart - | TGetProviderComplete - | TGetProviderError - | TGetTokenStart - | TGetTokenComplete - | TGetTokenError - | TGetPublicAddressComplete; diff --git a/rair-front/src/ducks/auth/reducers.ts b/rair-front/src/ducks/auth/reducers.ts deleted file mode 100644 index 7ffcdfa15..000000000 --- a/rair-front/src/ducks/auth/reducers.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { TAuthActionsType, TAuthInitialState } from './auth.types'; -import * as types from './types'; - -const InitialState: TAuthInitialState = { - error: null, - provider: null, - token: null, - publicAddress: null -}; - -export default function accessStore( - state: TAuthInitialState = InitialState, - action: TAuthActionsType -) { - switch (action.type) { - case types.GET_PROVIDER_START: - return { - ...state, - provider: null - }; - case types.GET_PROVIDER_COMPLETE: - return { - ...state, - provider: action.provider - }; - case types.GET_PROVIDER_ERROR: - return { - ...state, - provider: action.error - }; - case types.GET_TOKEN_START: - return { - ...state, - token: null - }; - case types.GET_TOKEN_COMPLETE: - return { - ...state, - token: action.token - }; - case types.GET_TOKEN_ERROR: - return { - ...state, - token: null, - error: action.error - }; - case types.GET_PUBLIC_ADDRESS_COMPLETE: - return { - ...state, - publicAddress: action.publicAddress - }; - default: - return state; - } -} diff --git a/rair-front/src/ducks/auth/sagas.ts b/rair-front/src/ducks/auth/sagas.ts deleted file mode 100644 index 2c9d55112..000000000 --- a/rair-front/src/ducks/auth/sagas.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { providers } from 'ethers'; -import { put, takeLatest } from 'redux-saga/effects'; - -import { getProviderComplete, getProviderError } from './actions'; -import * as types from './types'; - -export function* getProvider() { - try { - const provider = new providers.Web3Provider(window.ethereum); - yield put(getProviderComplete(provider)); - } catch (error: any) { - if (error.response !== undefined) { - if (error.response.status === 404) { - const errorDirec = 'This address does not exist'; - yield put(getProviderError(errorDirec)); - } else if (error.response.status === 500) { - const errorServer = 'Sorry. an internal server problem has occurred'; - yield put(getProviderError(errorServer)); - } else { - yield put(getProviderError(error.response.data.message)); - } - } else { - const errorConex = 'Connection error!'; - yield put(getProviderError(errorConex)); - } - } -} - -export function* sagaAccess() { - yield takeLatest(types.GET_PROVIDER_START, getProvider); - // yield takeLatest(types.GET_TOKEN_START, getToken); -} diff --git a/rair-front/src/ducks/auth/types.ts b/rair-front/src/ducks/auth/types.ts deleted file mode 100644 index b5d9cb9dd..000000000 --- a/rair-front/src/ducks/auth/types.ts +++ /dev/null @@ -1,9 +0,0 @@ -export const GET_PROVIDER_START = 'GET_PROVIDER_START'; -export const GET_PROVIDER_COMPLETE = 'GET_PROVIDER_COMPLETE'; -export const GET_PROVIDER_ERROR = 'GET_PROVIDER_ERROR'; - -export const GET_TOKEN_START = 'GET_TOKEN_START'; -export const GET_TOKEN_COMPLETE = 'GET_TOKEN_COMPLETE'; -export const GET_TOKEN_ERROR = 'GET_TOKEN_ERROR'; - -export const GET_PUBLIC_ADDRESS_COMPLETE = 'GET_PUBLIC_ADDRESS_COMPLETE'; diff --git a/rair-front/src/ducks/colors/actions.ts b/rair-front/src/ducks/colors/actions.ts deleted file mode 100644 index 729fd9f4a..000000000 --- a/rair-front/src/ducks/colors/actions.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as types from './types'; - -export const setColorScheme = (colorScheme: string) => - ({ type: types.SET_COLOR_SCHEME, colorScheme }) as const; - -export const setCustomColors = (value: { - primary: string; - secondary: string; - text: string; - primaryButton: string; - fadeButton: string; - secondaryButton: string; -}) => ({ type: types.SET_CUSTOM_COLORS, value }) as const; - -export const setCustomLogosDark = (value: { - desktop: string; - mobile: string; -}) => ({ type: types.SET_CUSTOM_LOGOS_DARK, value }) as const; - -export const setCustomLogosLight = (value: { - desktop: string; - mobile: string; -}) => ({ type: types.SET_CUSTOM_LOGOS_LIGHT, value }) as const; diff --git a/rair-front/src/ducks/colors/colorStore.types.ts b/rair-front/src/ducks/colors/colorStore.types.ts deleted file mode 100644 index c8e97db22..000000000 --- a/rair-front/src/ducks/colors/colorStore.types.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { - setColorScheme, - setCustomColors, - setCustomLogosDark, - setCustomLogosLight -} from './actions'; - -export type BackgroundBlendModeType = - | 'difference' - | 'exclusion' - | 'soft-light' - | 'hue' - | 'saturation' - | 'color' - | 'luminosity' - | 'hard-light' - | 'color-burn' - | 'color-dodge' - | 'normal' - | 'multiply' - | 'screen' - | 'overlay' - | 'darken' - | 'lighten'; - -export type ColorSchemaType = { - primaryColor: string; - secondaryColor: string; - headerLogo: string; - headerLogoMobile: string; - textColor: string; - backgroundImage: string; - backgroundImageEffect: { - backgroundBlendMode: BackgroundBlendModeType | undefined; - }; - iconColor: string; -}; -export type ColorStoreType = ColorSchemaType & { - primaryButtonColor: string; - secondaryButtonColor: string; -}; - -export type SchemaType = { - [key: string]: ColorSchemaType; -}; - -export type SetColorSchemeType = ReturnType; -export type SetCustomColorsType = ReturnType; -export type SetCustomLogosDarkType = ReturnType; -export type SetCustomLogosLightType = ReturnType; - -export type ColorStoreActionsType = - | SetColorSchemeType - | SetCustomColorsType - | SetCustomLogosDarkType - | SetCustomLogosLightType; diff --git a/rair-front/src/ducks/colors/reducer.ts b/rair-front/src/ducks/colors/reducer.ts deleted file mode 100644 index aa67165b3..000000000 --- a/rair-front/src/ducks/colors/reducer.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { - ColorStoreActionsType, - ColorStoreType, - SchemaType -} from './colorStore.types'; -import * as types from './types'; - -import { - headerLogoBlackMobile, - headerLogoWhiteMobile, - HotDropsLogo, - HotDropsLogoLight, - HotDropsLogoMobile -} from '../../images'; -import { headerLogoBlack, headerLogoWhite } from '../../images'; -import { bgLogoBlack, bgLogoWhite } from '../../images'; - -const charcoal = '#222021'; -const rhyno = '#dedede'; -const bubblegum = '#e882d5'; -const royalPurple = '#725bdb'; -const arcticBlue = '#19a7f6'; - -const buttons = { - primaryButtonColor: `linear-gradient(to right, ${royalPurple}, ${bubblegum})`, - secondaryButtonColor: `linear-gradient(to right, ${arcticBlue}, ${royalPurple})` -}; - -const hotdropsVar = import.meta.env.VITE_TESTNET; - -const schemes: SchemaType = { - rhyno: { - primaryColor: rhyno, - secondaryColor: charcoal, - headerLogo: hotdropsVar === 'true' ? HotDropsLogoLight : headerLogoBlack, - headerLogoMobile: - hotdropsVar === 'true' ? HotDropsLogoMobile : headerLogoBlackMobile, - textColor: 'black', - backgroundImage: bgLogoWhite, - backgroundImageEffect: { backgroundBlendMode: undefined }, - iconColor: '#F95631' - }, - charcoal: { - primaryColor: charcoal, - secondaryColor: rhyno, - headerLogo: hotdropsVar === 'true' ? HotDropsLogo : headerLogoWhite, - headerLogoMobile: - hotdropsVar === 'true' ? HotDropsLogoMobile : headerLogoWhiteMobile, - textColor: 'white', - backgroundImage: bgLogoBlack, - backgroundImageEffect: { backgroundBlendMode: 'lighten' }, - iconColor: '#F95631' - } -}; - -const InitialColorScheme: ColorStoreType = { - ...schemes[localStorage.colorScheme ? localStorage.colorScheme : 'charcoal'], - ...buttons -}; - -if (!localStorage.colorScheme) { - localStorage.setItem('colorScheme', 'charcoal'); -} - -export default function colorStore( - state: ColorStoreType = InitialColorScheme, - action: ColorStoreActionsType -): ColorStoreType { - switch (action.type) { - case types.SET_CUSTOM_COLORS: - schemes.charcoal.primaryColor = action.value.primary - ? action.value.primary - : charcoal; - schemes.charcoal.secondaryColor = action.value.secondary - ? action.value.secondary - : rhyno; - schemes.charcoal.textColor = action.value.text - ? action.value.text - : 'white'; - if (action.value.primaryButton) { - buttons.primaryButtonColor = action.value.primaryButton; - if (action.value.fadeButton) { - buttons.primaryButtonColor = `linear-gradient(to right, ${action.value.fadeButton}, ${action.value.primaryButton})`; - } - } - if (action.value.secondaryButton) { - buttons.secondaryButtonColor = action.value.secondaryButton; - if (action.value.fadeButton) { - buttons.secondaryButtonColor = `linear-gradient(to right, ${action.value.secondaryButton}, ${action.value.fadeButton})`; - schemes.rhyno.iconColor = action.value.secondaryButton; - schemes.charcoal.iconColor = action.value.secondaryButton; - } - } - return { - ...state, - ...schemes[localStorage.colorScheme], - ...buttons - }; - case types.SET_CUSTOM_LOGOS_DARK: - schemes.charcoal.headerLogo = action.value.desktop - ? action.value.desktop - : headerLogoWhite; - schemes.charcoal.headerLogoMobile = action.value.mobile - ? action.value.mobile - : headerLogoWhiteMobile; - return { - ...state, - ...schemes[localStorage.colorScheme], - ...buttons - }; - case types.SET_CUSTOM_LOGOS_LIGHT: - schemes.rhyno.headerLogo = action.value.desktop - ? action.value.desktop - : headerLogoBlack; - schemes.rhyno.headerLogoMobile = action.value.mobile - ? action.value.mobile - : headerLogoBlackMobile; - return { - ...state, - ...schemes[localStorage.colorScheme], - ...buttons - }; - case types.SET_COLOR_SCHEME: - localStorage.setItem('colorScheme', action.colorScheme); - return { - ...state, - ...schemes[action.colorScheme], - ...buttons - }; - default: - return state; - } -} diff --git a/rair-front/src/ducks/colors/types.ts b/rair-front/src/ducks/colors/types.ts deleted file mode 100644 index ba9f749bb..000000000 --- a/rair-front/src/ducks/colors/types.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const SET_COLOR_SCHEME = 'SET_COLOR_SCHEME'; -export const SET_CUSTOM_COLORS = 'SET_CUSTOM_COLORS'; -export const SET_CUSTOM_LOGOS_DARK = 'SET_CUSTOM_LOGOS_DARK'; -export const SET_CUSTOM_LOGOS_LIGHT = 'SET_CUSTOM_LOGOS_LIGHT'; diff --git a/rair-front/src/ducks/contracts/actions.ts b/rair-front/src/ducks/contracts/actions.ts deleted file mode 100644 index 930af0c47..000000000 --- a/rair-front/src/ducks/contracts/actions.ts +++ /dev/null @@ -1,42 +0,0 @@ -import * as types from './types'; - -import { BlockchainSetting } from '../../components/adminViews/adminView.types'; - -const setCoingeckoRates = (rates: { [key: string]: number }) => - ({ - type: types.SET_COINGECKO_RATE, - rates - }) as const; - -const setChainId = ( - currentChain: BlockchainType | undefined, - blockchainSettings?: BlockchainSetting[] -) => - ({ - type: types.SET_CHAIN_ID, - currentChain, - blockchainSettings - }) as const; - -const setUserAddress = (currentUserAddress: string | undefined) => - ({ type: types.SET_USER_ADDRESS, currentUserAddress }) as const; - -const setProgrammaticProvider = (programmaticProvider: any) => - ({ - type: types.SET_PROGRAMMATIC_PROVIDER, - programmaticProvider - }) as const; - -const setRealChain = (realChain: BlockchainType | undefined) => - ({ - type: types.SET_REAL_CHAIN, - realChain - }) as const; - -export { - setChainId, - setCoingeckoRates, - setProgrammaticProvider, - setRealChain, - setUserAddress -}; diff --git a/rair-front/src/ducks/contracts/contracts.types.ts b/rair-front/src/ducks/contracts/contracts.types.ts deleted file mode 100644 index 254c10b6f..000000000 --- a/rair-front/src/ducks/contracts/contracts.types.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { MultiOwnerModularAccount } from '@alchemy/aa-accounts'; -import { AccountSigner } from '@alchemy/aa-ethers'; -import { ethers } from 'ethers'; - -import { - setChainId, - setCoingeckoRates, - setProgrammaticProvider, - setRealChain, - setUserAddress -} from './actions'; - -type AbiInputs = { - indexed?: boolean; - internalType: string; - name: string; - type: string; -}; - -type AbiSingleType = { - anonymous: boolean; - inputs?: AbiInputs[]; - outputs?: AbiInputs[]; - stateMutability: string; - name: string; - type: string; -}; - -export type AbiType = AbiSingleType[]; - -export type ContractsInitialType = { - factoryInstance: ethers.Contract | undefined; - minterInstance: ethers.Contract | undefined; - mainTokenInstance: ethers.Contract | undefined; - diamondFactoryInstance: ethers.Contract | undefined; - diamondMarketplaceInstance: ethers.Contract | undefined; - licenseExchangeInstance: ethers.Contract | undefined; - currentChain: BlockchainType | undefined; - currentUserAddress: string | undefined; - programmaticProvider: AccountSigner | undefined; - contractCreator: - | undefined - | (( - address: string | undefined, - abi: AbiType - ) => ethers.Contract | undefined); - realChain: BlockchainType | undefined; - web3Provider?: undefined | ethers.providers.Web3Provider; - coingeckoRates?: { [key: string]: number }; -}; - -export type ContractContents = { - factory?: string; - erc777?: string; - minterMarketplace?: string; - diamondFactory?: string; - diamondMarketplace?: string; - resaleMarketplace?: string; - tokenPurchaser?: string; - creditHandler?: string; - licenseExchange?: string; -}; - -export type ContractAddressesType = { - [key in BlockchainType]?: ContractContents; -}; - -export type SetChainId = ReturnType; -export type SetUserAddress = ReturnType; -export type SetProgrammaticProvider = ReturnType< - typeof setProgrammaticProvider ->; -export type SetRealChain = ReturnType; -export type SetCoingeckoRates = ReturnType; - -export type ContractsActionsType = - | SetChainId - | SetUserAddress - | SetProgrammaticProvider - | SetRealChain - | SetCoingeckoRates; diff --git a/rair-front/src/ducks/contracts/reducer.ts b/rair-front/src/ducks/contracts/reducer.ts deleted file mode 100644 index bfa78103d..000000000 --- a/rair-front/src/ducks/contracts/reducer.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { Contract, providers } from 'ethers'; - -import { ContractsActionsType, ContractsInitialType } from './contracts.types'; -import * as types from './types'; - -import { - diamondFactoryAbi, - diamondMarketplaceAbi, - erc777Abi, - factoryAbi, - licenseExchangeABI, - minterAbi -} from '../../contracts'; - -const InitialState: ContractsInitialType = { - minterInstance: undefined, - factoryInstance: undefined, - mainTokenInstance: undefined, - diamondFactoryInstance: undefined, - diamondMarketplaceInstance: undefined, - licenseExchangeInstance: undefined, - currentChain: import.meta.env.VITE_DEFAULT_BLOCKCHAIN as BlockchainType, - currentUserAddress: undefined, - programmaticProvider: undefined, - contractCreator: undefined, - realChain: undefined, - coingeckoRates: undefined -}; - -export default function userStore( - state: ContractsInitialType = InitialState, - action: ContractsActionsType -): ContractsInitialType { - switch (action.type) { - case types.SET_CHAIN_ID: - // eslint-disable-next-line - const addresses = action.blockchainSettings?.find( - (chain) => chain.hash === action.currentChain - ); - if (action.currentChain !== undefined && addresses !== undefined) { - let signer; - if (state.programmaticProvider) { - signer = state.programmaticProvider; - } else if (window.ethereum) { - const provider = new providers.Web3Provider(window.ethereum, 'any'); - provider.on( - 'debug', - ({ - // action, - request, - response - // provider - }) => { - if (import.meta.env.VITE_LOG_WEB3 === 'true') { - console.info( - response ? 'Receiving response to' : 'Sending request', - request.method - ); - } - } - ); - provider.on('network', (newNetwork, oldNetwork) => { - // When a Provider makes its initial connection, it emits a "network" - // event with a null oldNetwork along with the newNetwork. So, if the - // oldNetwork exists, it represents a changing network - /* - Example of a network object: - { - "name": "goerli", - "chainId": 5, - "ensAddress": "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e" - } - */ - if (oldNetwork) { - console.info( - `Detected a network change, from ${oldNetwork.name} to ${newNetwork.name}` - ); - } else { - console.info(`Connected to ${newNetwork.name}`); - } - }); - signer = provider.getSigner(0); - } else { - return { - ...state, - currentChain: action.currentChain, - web3Provider: undefined, - minterInstance: undefined, - factoryInstance: undefined, - mainTokenInstance: undefined, - contractCreator: undefined, - diamondFactoryInstance: undefined, - diamondMarketplaceInstance: undefined, - licenseExchangeInstance: undefined - }; - } - const contractCreator = (address, abi) => { - if (address) { - return new Contract(address, abi, signer); - } - return undefined; - }; - - return { - ...state, - currentChain: action.currentChain, - factoryInstance: contractCreator( - addresses.classicFactoryAddress, - factoryAbi - ), - minterInstance: contractCreator( - undefined, //addresses.classicMarketplaceAddress, - minterAbi - ), - mainTokenInstance: contractCreator( - addresses.mainTokenAddress, - erc777Abi - ), - diamondFactoryInstance: contractCreator( - addresses.diamondFactoryAddress, - diamondFactoryAbi - ), - diamondMarketplaceInstance: contractCreator( - addresses.diamondMarketplaceAddress, - diamondMarketplaceAbi - ), - licenseExchangeInstance: contractCreator( - addresses.licenseExchangeAddress, - licenseExchangeABI - ), - contractCreator: contractCreator - }; - } else { - return { - ...state, - currentChain: action.currentChain, - minterInstance: undefined, - factoryInstance: undefined, - mainTokenInstance: undefined, - contractCreator: undefined, - diamondFactoryInstance: undefined, - diamondMarketplaceInstance: undefined - }; - } - case types.SET_USER_ADDRESS: - // eslint-disable-next-line no-case-declarations - const update = { - ...state, - currentUserAddress: action.currentUserAddress - }; - if (action.currentUserAddress === undefined) { - update.currentChain = import.meta.env - .VITE_DEFAULT_BLOCKCHAIN as BlockchainType; - } - return update; - case types.SET_PROGRAMMATIC_PROVIDER: - return { - ...state, - programmaticProvider: action.programmaticProvider - }; - case types.SET_REAL_CHAIN: - return { - ...state, - realChain: action.realChain - }; - case types.SET_COINGECKO_RATE: - return { - ...state, - coingeckoRates: action.rates - }; - default: - return state; - } -} diff --git a/rair-front/src/ducks/contracts/types.ts b/rair-front/src/ducks/contracts/types.ts deleted file mode 100644 index 1ecf43e6c..000000000 --- a/rair-front/src/ducks/contracts/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export const SET_CHAIN_ID = 'SET_CHAIN_ID'; -export const SET_USER_ADDRESS = 'SET_USER_ADDRESS'; -export const SET_PROGRAMMATIC_PROVIDER = 'SET_PROGRAMMATIC_PROVIDER'; -export const SET_REAL_CHAIN = 'SET_REAL_CHAIN'; -export const SET_COINGECKO_RATE = 'SET_COINGECKO_RATE'; diff --git a/rair-front/src/ducks/index.ts b/rair-front/src/ducks/index.ts deleted file mode 100644 index 48882cfbc..000000000 --- a/rair-front/src/ducks/index.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { createReduxEnhancer } from '@sentry/react'; -import { - applyMiddleware, - combineReducers, - compose, - createStore, - StoreEnhancer -} from 'redux'; -import createSagaMiddleware from 'redux-saga'; - -import rootSaga from './sagas'; - -import accessStore from './auth/reducers'; -//REDUCERS -import colorStore from './colors/reducer'; -import contractStore from './contracts/reducer'; -import metadataStore from './metadata/reducers'; -import nftDataStore from './nftData/reducers'; -import getPageStore from './pages/reducers'; -import resalesStore from './resales/reducers'; -import allInformationFromSearch from './search/reducers'; -import seoStore from './seo/reducers'; -import videoDemoStore from './uploadDemo/reducers'; -import userStore from './users/reducers'; -import videosStore from './videos/reducers'; - -const reducers = combineReducers({ - accessStore, - userStore, - videosStore, - contractStore, - colorStore, - metadataStore, - getPageStore, - allInformationFromSearch, - nftDataStore, - resalesStore, - seoStore, - videoDemoStore -}); - -const sentryReduxEnhancer = createReduxEnhancer({ - // Optionally pass options listed below -}); - -const sagaMiddleware = createSagaMiddleware(); - -const store = createStore( - reducers, - undefined, - compose(sentryReduxEnhancer as StoreEnhancer, applyMiddleware(sagaMiddleware)) -); -sagaMiddleware.run(rootSaga); - -export type RootState = ReturnType; -export type AppDispatch = typeof store.dispatch; - -export default store; diff --git a/rair-front/src/ducks/metadata/actions.ts b/rair-front/src/ducks/metadata/actions.ts deleted file mode 100644 index 7b990c0ef..000000000 --- a/rair-front/src/ducks/metadata/actions.ts +++ /dev/null @@ -1,19 +0,0 @@ -import * as types from './types'; - -const updateTokenMetadataAC = (url: string, formData: any) => - ({ - type: types.UPDATE_TOKEN_METADATA, - url, - formData - }) as const; -const setShowSidebarFalse = () => ({ type: types.SHOW_SIDEBAR_FALSE }) as const; -const setShowSidebarTrue = () => ({ type: types.SHOW_SIDEBAR_TRUE }) as const; -const updateTokenMetadataError = (errorMessage: string | null) => - ({ type: types.UPDATE_TOKEN_METADATA_ERROR, errorMessage }) as const; - -export { - setShowSidebarFalse, - setShowSidebarTrue, - updateTokenMetadataAC, - updateTokenMetadataError -}; diff --git a/rair-front/src/ducks/metadata/metadata.types.ts b/rair-front/src/ducks/metadata/metadata.types.ts deleted file mode 100644 index 27c04f096..000000000 --- a/rair-front/src/ducks/metadata/metadata.types.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { - setShowSidebarFalse, - setShowSidebarTrue, - updateTokenMetadataAC, - updateTokenMetadataError -} from './actions'; - -export type TMetadataInitialType = { - showSidebar: boolean; - errorMessage: string | null; -}; - -export type TSetShowSidebarTrue = ReturnType; -export type TSetShowSidebarFalse = ReturnType; -export type TUpdateTokenMetadata = ReturnType; -export type TUpdateTokenMetadataError = ReturnType< - typeof updateTokenMetadataError ->; - -export type TMetadataActions = - | TSetShowSidebarTrue - | TSetShowSidebarFalse - | TUpdateTokenMetadata - | TUpdateTokenMetadataError; diff --git a/rair-front/src/ducks/metadata/reducers.ts b/rair-front/src/ducks/metadata/reducers.ts deleted file mode 100644 index 0bd5b0f89..000000000 --- a/rair-front/src/ducks/metadata/reducers.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { TMetadataActions, TMetadataInitialType } from './metadata.types'; -import * as types from './types'; - -const InitialState: TMetadataInitialType = { - showSidebar: true, - errorMessage: null -}; - -export default function metadataStore( - state: TMetadataInitialType = InitialState, - action: TMetadataActions -) { - switch (action.type) { - case types.SHOW_SIDEBAR_TRUE: - return { - ...state, - showSidebar: true - }; - case types.SHOW_SIDEBAR_FALSE: - return { - ...state, - showSidebar: false - }; - case types.UPDATE_TOKEN_METADATA_ERROR: - return { - ...state, - error_message: action.errorMessage - }; - // case types.UPDATE_TOKEN_METADATA: - // return { - // ...state, - - // } - default: - return state; - } -} diff --git a/rair-front/src/ducks/metadata/sagas.ts b/rair-front/src/ducks/metadata/sagas.ts deleted file mode 100644 index bd205cb03..000000000 --- a/rair-front/src/ducks/metadata/sagas.ts +++ /dev/null @@ -1,51 +0,0 @@ -import axios, { AxiosError } from 'axios'; -import { put, takeLatest } from 'redux-saga/effects'; - -import { updateTokenMetadataError } from './actions'; -import { TUpdateTokenMetadata } from './metadata.types'; -import * as types from './types'; - -import { BackendResponse } from '../../axios.responseTypes'; - -export function* updateTokenMetadata({ url, formData }) { - try { - axios - .post(url, formData, { - headers: { - 'Content-Type': 'multipart/form-data' - } - }) - .then((res) => res.data) - .then((response) => { - console.info(response); - }) - .catch((error) => { - console.error(error); - }); - } catch (errors) { - const error = errors as AxiosError; - const errorData: BackendResponse = error?.response?.data as BackendResponse; - - if (error.response !== undefined) { - if (error.response.status === 404) { - const errorDirec = 'This address does not exist'; - yield put(updateTokenMetadataError(errorDirec)); - } else if (error.response.status === 500) { - const errorServer = 'Sorry. an internal server problem has occurred'; - yield put(updateTokenMetadataError(errorServer)); - } else { - yield put(updateTokenMetadataError(errorData.message)); - } - } else { - const errorConex = 'Connection error!'; - yield put(updateTokenMetadataError(errorConex)); - } - } -} - -export function* sagaMetadata() { - yield takeLatest( - types.UPDATE_TOKEN_METADATA, - updateTokenMetadata - ); -} diff --git a/rair-front/src/ducks/metadata/types.ts b/rair-front/src/ducks/metadata/types.ts deleted file mode 100644 index 544c55c05..000000000 --- a/rair-front/src/ducks/metadata/types.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const SHOW_SIDEBAR_TRUE = 'SHOW_SIDEBAR_TRUE'; -export const SHOW_SIDEBAR_FALSE = 'SHOW_SIDEBAR_FALSE'; -export const UPDATE_TOKEN_METADATA = 'UPDATE_TOKEN_METADATA'; -export const UPDATE_TOKEN_METADATA_ERROR = 'UPDATE_TOKEN_METADATA_ERROR'; diff --git a/rair-front/src/ducks/nftData/action.ts b/rair-front/src/ducks/nftData/action.ts deleted file mode 100644 index a2067ac6b..000000000 --- a/rair-front/src/ducks/nftData/action.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { TNftDataItem } from './nftData.types'; -import * as types from './types'; - -import { TTokenData } from '../../axios.responseTypes'; - -const getNftDataStart = () => - ({ - type: types.GET_NFTLIST_START - }) as const; - -const getNftDataStartWithParams = (params: object) => - ({ - type: types.GET_NFTLIST_START, - params - }) as const; - -const setNftData = (nftList: Array) => - ({ - type: types.GET_NFTLIST_COMPLETE, - nftList - }) as const; - -const getNftListTotal = (nftListTotal: number) => - ({ - type: types.GET_NFT_LIST_TOTAL, - nftListTotal - }) as const; - -const getNftListTotalClear = () => - ({ - type: types.GET_NFT_TOTAL_CLEAR - }) as const; - -const getNftDataError = (errorMessage: string) => - ({ - type: types.GET_NFT_DATA_ERROR, - errorMessage - }) as const; - -const setTokenDataStart = () => - ({ - type: types.SET_TOKEN_DATA_START - }) as const; - -const setTokenData = (tokenData: { [index: string]: TTokenData }) => - ({ type: types.SET_TOKEN_DATA, tokenData }) as const; - -const setTokenDataTotalCount = (tokenDataListTotal) => - ({ type: types.SET_TOKEN_DATA_TOTAL_COUNT, tokenDataListTotal }) as const; - -export { - getNftDataError, - getNftDataStart, - getNftDataStartWithParams, - getNftListTotal, - getNftListTotalClear, - setNftData, - setTokenData, - setTokenDataStart, - setTokenDataTotalCount -}; diff --git a/rair-front/src/ducks/nftData/nftData.types.ts b/rair-front/src/ducks/nftData/nftData.types.ts deleted file mode 100644 index 341733f03..000000000 --- a/rair-front/src/ducks/nftData/nftData.types.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { - getNftDataError, - getNftDataStart, - getNftListTotal, - getNftListTotalClear, - setNftData, - setTokenData, - setTokenDataStart, - setTokenDataTotalCount -} from './action'; - -import { TTokenData } from '../../axios.responseTypes'; - -export interface InitialNftDataStateType { - loading: boolean; - nftList: Array | null; - nftListTotal: number | undefined; - itemsPerPage: number; - errorMessage: string; - tokenData: { [index: string]: TTokenData } | undefined; - tokenDataListTotal: number | undefined; -} - -export type TNftDataItem = { - blockchain: BlockchainType | undefined; - collectionIndexInContract: string; - contract: string; - copiesProduct: number; - cover: string; - id: string; - name: string; - offerData: Array; - productId: string; - title: string; - user: string; - price?: string; -}; - -export type TOfferData = { - offerIndex: string; - offerName: string; - price: number | bigint; - productNumber: string; -}; - -export type TParamsNftDataProps = { - type: string; - params: TParamsNftData; -}; - -export type TParamsNftData = { - itemsPerPage: number; - currentPage: number; - blockchain?: string; - category?: string[]; - type?: string; - contractTitle?: string; -}; - -export type TGetNftDataStartType = ReturnType; -export type TSetNftData = ReturnType; -export type TGetNftListTotal = ReturnType; -export type TGetNftListTotalClear = ReturnType; -export type TGetNftDataErrorType = ReturnType; -export type TSetTokenDataStart = ReturnType; -export type TSetTokenData = ReturnType; -export type TSetTokenDataTotalCount = ReturnType; - -export type TNftDataReducerActionType = - | TGetNftDataStartType - | TSetNftData - | TGetNftListTotal - | TGetNftListTotalClear - | TGetNftDataErrorType - | TSetTokenDataStart - | TSetTokenData - | TSetTokenDataTotalCount; diff --git a/rair-front/src/ducks/nftData/reducers.ts b/rair-front/src/ducks/nftData/reducers.ts deleted file mode 100644 index 651f30066..000000000 --- a/rair-front/src/ducks/nftData/reducers.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { - InitialNftDataStateType, - TNftDataReducerActionType -} from './nftData.types'; -import * as types from './types'; - -const InitialState: InitialNftDataStateType = { - loading: false, - nftList: null, - nftListTotal: undefined, - itemsPerPage: 20, - errorMessage: '', - tokenData: undefined, - tokenDataListTotal: undefined -}; - -export default function nftDataStore( - state: InitialNftDataStateType = InitialState, - action: TNftDataReducerActionType -): InitialNftDataStateType { - switch (action.type) { - case types.GET_NFTLIST_START: - return { - ...state, - loading: true, - nftList: null - }; - - case types.GET_NFTLIST_COMPLETE: - return { - ...state, - loading: false, - nftList: action.nftList - }; - - case types.GET_NFT_TOTAL_CLEAR: - return { - ...state, - nftListTotal: undefined - }; - - case types.GET_NFT_LIST_TOTAL: - return { - ...state, - loading: false, - nftListTotal: action.nftListTotal - }; - - case types.GET_NFT_DATA_ERROR: - return { - ...state, - loading: false, - nftList: null, - errorMessage: action.errorMessage - }; - - case types.SET_TOKEN_DATA_START: { - return { - ...state, - loading: true, - tokenData: undefined, - tokenDataListTotal: undefined - }; - } - - case types.SET_TOKEN_DATA: { - return { - ...state, - loading: false, - tokenData: action.tokenData - }; - } - - case types.SET_TOKEN_DATA_TOTAL_COUNT: { - return { - ...state, - loading: false, - tokenDataListTotal: action.tokenDataListTotal - }; - } - - default: - return state; - } -} diff --git a/rair-front/src/ducks/nftData/saga.ts b/rair-front/src/ducks/nftData/saga.ts deleted file mode 100644 index 30187b1a2..000000000 --- a/rair-front/src/ducks/nftData/saga.ts +++ /dev/null @@ -1,58 +0,0 @@ -import axios, { AxiosResponse } from 'axios'; -import { call, put, takeLatest } from 'redux-saga/effects'; - -import { getNftListTotal, getNftListTotalClear } from './action'; -import { TParamsNftDataProps } from './nftData.types'; -import * as types from './types'; - -import { TContract, TGetFullContracts } from '../../axios.responseTypes'; - -export function* setNftDataContract({ params }: TParamsNftDataProps) { - getNftListTotalClear(); - - try { - const { data }: AxiosResponse = yield call( - axios.get, - `/api/contracts/full?itemsPerPage=${params.itemsPerPage}&pageNum=${params.currentPage}` + - `${params.blockchain ? '&blockchain=' + params.blockchain : ''}` + - `${ - params.category && params.category !== undefined - ? params.category - : '' - }` + - `${ - params.contractTitle ? '&contractTitle=' + params.contractTitle : '' - }` - ); - - if (data.success) { - const covers = data.contracts.map((item: TContract) => ({ - id: item._id, - productId: item.products?._id, - blockchain: item.blockchain, - collectionIndexInContract: item.products.collectionIndexInContract, - contract: item.contractAddress, - cover: item.products.cover, - title: item.title, - name: item.products.name, - user: item.user, - userData: item.userData, - copiesProduct: item.products.copies, - offerData: item.products.offers?.map((elem) => ({ - price: elem.price, - offerName: elem.offerName, - offerIndex: elem.offerIndex, - productNumber: elem.product - })) - })); - yield put({ type: types.GET_NFTLIST_COMPLETE, nftList: covers }); - yield put(getNftListTotal(data.totalNumber)); - } - } catch (error) { - yield put({ type: types.GET_NFT_DATA_ERROR, errorMessage: 'error' }); - } -} - -export function* sagaNftData() { - yield takeLatest(types.GET_NFTLIST_START, setNftDataContract); -} diff --git a/rair-front/src/ducks/nftData/types.ts b/rair-front/src/ducks/nftData/types.ts deleted file mode 100644 index 9671eb40e..000000000 --- a/rair-front/src/ducks/nftData/types.ts +++ /dev/null @@ -1,10 +0,0 @@ -export const GET_NFTLIST_START = 'GET_NFTLIST_START'; -export const GET_NFTLIST_COMPLETE = 'GET_NFTLIST_COMPLETE'; -export const GET_NFT_TOTAL_CLEAR = 'GET_NFT_TOTAL_CLEAR'; -export const GET_NFT_LIST_TOTAL = 'GET_NFT_LIST_TOTAL'; -export const GET_MEDIA_LIST_START = 'GET_MEDIA_LIST_START'; -export const GET_MEDIA_LIST_COMPLETE = 'GET_MEDIA_LIST_COMPLETE'; -export const GET_NFT_DATA_ERROR = 'GET_NFT_DATA_ERROR'; -export const SET_TOKEN_DATA_START = 'SET_TOKEN_DATA_START'; -export const SET_TOKEN_DATA = 'SET_TOKEN_DATA'; -export const SET_TOKEN_DATA_TOTAL_COUNT = 'SET_TOKEN_DATA_TOTAL_COUNT'; diff --git a/rair-front/src/ducks/pages/actions.ts b/rair-front/src/ducks/pages/actions.ts deleted file mode 100644 index 4a3347348..000000000 --- a/rair-front/src/ducks/pages/actions.ts +++ /dev/null @@ -1,27 +0,0 @@ -import * as types from './types'; - -const getCurrentPage = (currentPage: number) => - ({ - type: types.GET_CURRENT_PAGE_START, - currentPage - }) as const; - -const getCurrentPageEnd = () => - ({ - type: types.GET_CURRENT_PAGE_END - }) as const; - -const getCurrentPageNull = () => - ({ - type: types.GET_CURRENT_NULL - }) as const; - -const getCurrentPageComplete = (currentPage: number) => - ({ type: types.GET_CURRENT_PAGE_COMPLETE, currentPage }) as const; - -export { - getCurrentPage, - getCurrentPageComplete, - getCurrentPageEnd, - getCurrentPageNull -}; diff --git a/rair-front/src/ducks/pages/pages.types.ts b/rair-front/src/ducks/pages/pages.types.ts deleted file mode 100644 index af7769bb8..000000000 --- a/rair-front/src/ducks/pages/pages.types.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { - getCurrentPage, - getCurrentPageComplete, - getCurrentPageEnd, - getCurrentPageNull -} from './actions'; - -export type TPagesInitialState = { - currentPage: number; - loading: boolean | null; -}; - -export type TGetCurrentPageStart = ReturnType; -export type TGetCurrentPageEnd = ReturnType; -export type TGetCurrentPageComplete = ReturnType; -export type TGetCurrentPageNull = ReturnType; - -export type TPagesActionsType = - | TGetCurrentPageStart - | TGetCurrentPageEnd - | TGetCurrentPageComplete - | TGetCurrentPageNull; diff --git a/rair-front/src/ducks/pages/reducers.ts b/rair-front/src/ducks/pages/reducers.ts deleted file mode 100644 index 0efb5e478..000000000 --- a/rair-front/src/ducks/pages/reducers.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { TPagesActionsType, TPagesInitialState } from './pages.types'; -import * as types from './types'; - -const InitialState: TPagesInitialState = { - currentPage: 1, - loading: null -}; - -export default function getPageStore( - state: TPagesInitialState = InitialState, - action: TPagesActionsType -): TPagesInitialState { - switch (action.type) { - case types.GET_CURRENT_PAGE_START: - return { - ...state, - currentPage: action.currentPage, - loading: true - }; - case types.GET_CURRENT_PAGE_COMPLETE: - return { - ...state, - currentPage: action.currentPage, - loading: false - }; - case types.GET_CURRENT_PAGE_END: - return { - ...state, - currentPage: 1, - loading: true - }; - case types.GET_CURRENT_NULL: - return { - ...state, - currentPage: 1 - }; - default: - return state; - } -} diff --git a/rair-front/src/ducks/pages/types.ts b/rair-front/src/ducks/pages/types.ts deleted file mode 100644 index d637ff797..000000000 --- a/rair-front/src/ducks/pages/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -//@ts-nocheck -export const GET_CURRENT_PAGE_START = 'GET_CURRENT_PAGE_START'; -export const GET_CURRENT_PAGE_COMPLETE = 'GET_CURRENT_PAGE_COMPLETE'; -export const GET_CURRENT_PAGE_END = 'GET_CURRENT_PAGE_END'; -export const GET_CURRENT_NULL = 'GET_CURRENT_NULL'; diff --git a/rair-front/src/ducks/resales/actions.ts b/rair-front/src/ducks/resales/actions.ts deleted file mode 100644 index b945ac93c..000000000 --- a/rair-front/src/ducks/resales/actions.ts +++ /dev/null @@ -1,35 +0,0 @@ -import * as types from './types'; - -const getListResalesStart = () => - ({ - type: types.GET_RESALES_LIST_START - }) as const; - -const getResalesListComplete = (resaleList: any | null) => - ({ type: types.GET_RESALES_LIST_COMPLETE, resaleList }) as const; - -const getResalesListTotalClear = () => - ({ - type: types.GET_RESALES_LIST_TOTAL_CLEAR - }) as const; - -const getResalesListTotal = (totalNumberVideo: number) => - ({ type: types.GET_RESALES_LIST_TOTAL, totalNumberVideo }) as const; - -const refreshAction = (refresh: boolean) => - ({ - type: types.REFRESH_RESALES_LIST, - refresh - }) as const; - -const getListResalesError = (error: string | null) => - ({ type: types.GET_RESALES_LIST_ERROR, error }) as const; - -export { - getListResalesError, - getListResalesStart, - getResalesListComplete, - getResalesListTotal, - getResalesListTotalClear, - refreshAction -}; diff --git a/rair-front/src/ducks/resales/reducers.ts b/rair-front/src/ducks/resales/reducers.ts deleted file mode 100644 index 0ede94d0f..000000000 --- a/rair-front/src/ducks/resales/reducers.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { TResalesActions, TResalesInitialState } from './resalesDucks.types'; -import * as types from './types'; - -const InitialState: TResalesInitialState = { - resales: null, - error: null, - totalNumberResales: null, - refresh: false, - loading: false -}; - -export default function resaleStore( - state: TResalesInitialState = InitialState, - action: TResalesActions -): TResalesInitialState { - switch (action.type) { - case types.GET_RESALES_LIST_START: - return { - ...state, - resales: null, - loading: true - }; - case types.GET_RESALES_LIST_COMPLETE: - return { - ...state, - resales: action.resaleList, - loading: false - }; - case types.GET_RESALES_LIST_TOTAL_CLEAR: - return { - ...state, - totalNumberResales: null - }; - case types.GET_RESALES_LIST_TOTAL: - return { - ...state, - loading: false, - totalNumberResales: action.totalNumberVideo - }; - case types.GET_RESALES_LIST_ERROR: - return { - ...state, - resales: null, - error: action.error - }; - case types.REFRESH_RESALES_LIST: - return { - ...state, - refresh: action.refresh - }; - default: - return state; - } -} diff --git a/rair-front/src/ducks/resales/resalesDucks.types.ts b/rair-front/src/ducks/resales/resalesDucks.types.ts deleted file mode 100644 index d150af4d8..000000000 --- a/rair-front/src/ducks/resales/resalesDucks.types.ts +++ /dev/null @@ -1,34 +0,0 @@ -// import { MediaListResponseType } from '../../components/video/video.types'; -import { - getListResalesError, - getListResalesStart, - getResalesListComplete, - getResalesListTotal, - getResalesListTotalClear, - refreshAction -} from './actions'; - -export type TResalesInitialState = { - resales: any | null; - error: string | null; - refresh: boolean; - loading: boolean; - totalNumberResales: number | null; -}; - -export type TGetListResalesStart = ReturnType; -export type TGetResaleListComplete = ReturnType; -export type TRefreshAction = ReturnType; -export type TGetListResalesTotalClear = ReturnType< - typeof getResalesListTotalClear ->; -export type TetListResalesTotal = ReturnType; -export type TGetListResalesError = ReturnType; - -export type TResalesActions = - | TGetListResalesStart - | TGetResaleListComplete - | TRefreshAction - | TGetListResalesTotalClear - | TetListResalesTotal - | TGetListResalesError; diff --git a/rair-front/src/ducks/resales/sagas.ts b/rair-front/src/ducks/resales/sagas.ts deleted file mode 100644 index efd22cbe8..000000000 --- a/rair-front/src/ducks/resales/sagas.ts +++ /dev/null @@ -1,42 +0,0 @@ -//@ts-nocheck -import axios, { AxiosError, AxiosRequestHeaders, AxiosResponse } from 'axios'; -import { call, put, takeLatest } from 'redux-saga/effects'; - -import { - getListResalesError, - getResalesListComplete, - getResalesListTotal -} from './actions'; -import * as types from './types'; - -export function* getResales() { - try { - const resales: AxiosResponse = yield call< - (url: string, config: AxiosRequestHeaders) => any - >(axios.get, `/api/resales/`); - if (resales !== undefined && resales.status === 200) { - yield put(getResalesListComplete(resales.data.data.doc)); - yield put(getResalesListTotal(resales.data.data.doc.length)); - } - } catch (error) { - const errors = error as AxiosError; - if (errors.response !== undefined) { - if (errors.response.status === 404) { - const errorDirec = 'This address does not exist'; - yield put(getListResalesError(errorDirec)); - } else if (errors.response.status === 500) { - const errorServer = 'Sorry. an internal server problem has occurred'; - yield put(getListResalesError(errorServer)); - } else { - yield put(getListResalesError(errors.response.data.message)); - } - } else { - const errorConex = 'Connection error!'; - yield put(getListResalesError(errorConex)); - } - } -} - -export function* sagaResales() { - yield takeLatest(types.GET_RESALES_LIST_START, getResales); -} diff --git a/rair-front/src/ducks/resales/types.ts b/rair-front/src/ducks/resales/types.ts deleted file mode 100644 index 21dec4d1f..000000000 --- a/rair-front/src/ducks/resales/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const GET_RESALES_LIST_START = 'GET_RESALES_LIST_START'; -export const GET_RESALES_LIST_COMPLETE = 'GET_RESALES_LIST_COMPLETE'; -export const GET_RESALES_LIST_TOTAL_CLEAR = 'GET_RESALES_LIST_TOTAL_CLEAR'; -export const GET_RESALES_LIST_TOTAL = 'GET_RESALES_LIST_TOTAL'; -export const GET_RESALES_LIST_ERROR = 'GET_RESALES_LIST_ERROR'; -export const REFRESH_RESALES_LIST = 'REFRESH_RESALES_LIST'; diff --git a/rair-front/src/ducks/sagas.ts b/rair-front/src/ducks/sagas.ts deleted file mode 100644 index 622ddfea4..000000000 --- a/rair-front/src/ducks/sagas.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { all } from 'redux-saga/effects'; - -import { sagaAccess } from './auth/sagas'; -import { sagaMetadata } from './metadata/sagas'; -import { sagaNftData } from './nftData/saga'; -import { sagaResales } from './resales/sagas'; -import { sagaAllInformationFromSearch } from './search/sagas'; -import { sagaUser } from './users/sagas'; -import { sagaVideos } from './videos/sagas'; - -export default function* rootSaga() { - yield all([ - sagaAccess(), - sagaUser(), - sagaVideos(), - sagaAllInformationFromSearch(), - sagaMetadata(), - sagaNftData(), - sagaResales() - ]); -} diff --git a/rair-front/src/ducks/search/actions.ts b/rair-front/src/ducks/search/actions.ts deleted file mode 100644 index 857d43a30..000000000 --- a/rair-front/src/ducks/search/actions.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { TSearchDataObject } from './search.types'; -import * as types from './types'; - -const getDataAllStart = (titleSearchDemo: string) => - ({ - type: types.GET_DATA_ALL_START, - titleSearchDemo - }) as const; -const getDataAllComplete = (data: TSearchDataObject) => - ({ - type: types.GET_DATA_ALL_COMPLETE, - data - }) as const; -const getDataAllEmpty = (message: string) => - ({ - type: types.GET_DATA_ALL_EMPTY, - message - }) as const; -const getDataAllClear = () => - ({ - type: types.GET_DATA_ALL_CLEAR - }) as const; - -export { - getDataAllClear, - getDataAllComplete, - getDataAllEmpty, - getDataAllStart -}; diff --git a/rair-front/src/ducks/search/reducers.ts b/rair-front/src/ducks/search/reducers.ts deleted file mode 100644 index ab9e07c22..000000000 --- a/rair-front/src/ducks/search/reducers.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { TSeacrhActionsType, TSearchInitialState } from './search.types'; -import * as types from './types'; - -const InitialState: TSearchInitialState = { - titleSearchDemo: '', - dataAll: null, - message: '', - loading: null -}; - -export default function allInformationFromSearch( - state: TSearchInitialState = InitialState, - action: TSeacrhActionsType -): TSearchInitialState { - switch (action.type) { - case types.GET_DATA_ALL_START: - return { - ...state, - dataAll: null, - loading: true, - message: '', - titleSearchDemo: action.titleSearchDemo - }; - case types.GET_DATA_ALL_COMPLETE: - return { - ...state, - dataAll: action.data, - loading: false, - message: '' - }; - case types.GET_DATA_ALL_CLEAR: - return { - ...state, - dataAll: null, - loading: false, - message: '' - }; - case types.GET_DATA_ALL_EMPTY: - return { - ...state, - dataAll: null, - loading: false, - message: action.message - }; - default: - return state; - } -} diff --git a/rair-front/src/ducks/search/sagas.ts b/rair-front/src/ducks/search/sagas.ts deleted file mode 100644 index 8cfaa3925..000000000 --- a/rair-front/src/ducks/search/sagas.ts +++ /dev/null @@ -1,64 +0,0 @@ -import axios, { AxiosError, AxiosResponse } from 'axios'; -import { call, put, takeLatest } from 'redux-saga/effects'; - -import { - getDataAllClear, - getDataAllComplete, - getDataAllEmpty -} from './actions'; -import { TGetDataAllStart, TSearchDataResponseType } from './search.types'; -import * as types from './types'; - -import { BackendResponse } from '../../axios.responseTypes'; - -export function* getAllInformationFromSearch( - titleSearchDemo: TGetDataAllStart -) { - try { - if (titleSearchDemo.titleSearchDemo) { - const titleSearchDemoEncoded = encodeURIComponent( - titleSearchDemo.titleSearchDemo - ); - - const searchData: AxiosResponse = yield call( - () => { - return axios.get( - `/api/search/${titleSearchDemoEncoded}` - ); - } - ); - - // if (searchData.data.data) { - if (searchData.status === 200) { - if (searchData.data.data) { - yield put(getDataAllComplete(searchData.data.data)); - } else if (!searchData.data.data) { - yield put(getDataAllClear()); - } - } - } - } catch (errors) { - const error = errors as AxiosError; - console.error(error, 'error from sagas'); - const errorData: BackendResponse = error?.response?.data as BackendResponse; - - if (error.response !== undefined) { - if (error.response.status === 404) { - const errorDirec = 'Nothing can found'; - yield put(getDataAllEmpty(errorDirec)); - } else if (error.response.status === 500) { - const errorServer = 'Sorry. an internal server problem has occurred'; - yield put(getDataAllEmpty(errorServer)); - } else { - yield put(getDataAllEmpty(errorData.message)); - } - } else { - const errorConnection = 'Nothing can fiend error!'; - yield put(getDataAllEmpty(errorConnection)); - } - } -} - -export function* sagaAllInformationFromSearch() { - yield takeLatest(types.GET_DATA_ALL_START, getAllInformationFromSearch); -} diff --git a/rair-front/src/ducks/search/search.types.ts b/rair-front/src/ducks/search/search.types.ts deleted file mode 100644 index 0b1aab5f7..000000000 --- a/rair-front/src/ducks/search/search.types.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { - getDataAllClear, - getDataAllComplete, - getDataAllEmpty, - getDataAllStart -} from './actions'; - -import { TProducts } from '../../axios.responseTypes'; -import { UserType } from '../users/users.types'; - -import { TTokenData } from './../../axios.responseTypes'; - -export type TSearchInitialState = { - titleSearchDemo: string; - dataAll: TSearchDataObject | null; - message: string; - loading: boolean | null; -}; - -export type TSearchDataUser = Pick< - UserType, - 'avatar' | 'nickName' | '_id' | 'publicAddress' ->; -export type TSearchDataProduct = Pick< - TProducts, - 'collectionIndexInContract' | 'contract' | '_id' | 'copies' | 'cover' | 'name' ->; -export type TSearchDataTokens = Pick< - TTokenData, - 'contract' | 'uniqueIndexInContract' | '_id' | 'metadata' ->; - -export type TSearchDataObject = { - products: TSearchDataProduct[]; - tokens: TSearchDataTokens[]; - users: TSearchDataUser[]; -}; - -export type TSearchDataResponseType = { - success: boolean; - data: TSearchDataObject; -}; - -export type TGetDataAllStart = ReturnType; -export type TGetDataAllComplete = ReturnType; -export type TGetDataAllEmpty = ReturnType; -export type TGetDataAllClear = ReturnType; - -export type TSeacrhActionsType = - | TGetDataAllStart - | TGetDataAllComplete - | TGetDataAllEmpty - | TGetDataAllClear; diff --git a/rair-front/src/ducks/search/types.ts b/rair-front/src/ducks/search/types.ts deleted file mode 100644 index 710ef60b8..000000000 --- a/rair-front/src/ducks/search/types.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const GET_DATA_ALL_START = 'GET_DATA_ALL_START'; -export const GET_DATA_ALL_COMPLETE = 'GET_DATA_ALL_COMPLETE'; -export const GET_DATA_ALL_EMPTY = 'GET_DATA_ALL_EMPTY'; -export const GET_DATA_ALL_CLEAR = 'GET_DATA_ALL_CLEAR'; diff --git a/rair-front/src/ducks/seo/actions.ts b/rair-front/src/ducks/seo/actions.ts deleted file mode 100644 index 3480799b1..000000000 --- a/rair-front/src/ducks/seo/actions.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { TInfoSeo } from './seo.types'; -import * as types from './types'; - -export const setInfoSEO = (info: TInfoSeo) => - ({ - type: types.SET_INFO_HELMET, - info - }) as const; - -export const resetInfoSeo = () => - ({ - type: types.RESET_INFO_HELMET - }) as const; diff --git a/rair-front/src/ducks/seo/reducers.ts b/rair-front/src/ducks/seo/reducers.ts deleted file mode 100644 index 62e4574f8..000000000 --- a/rair-front/src/ducks/seo/reducers.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { TInfoSeo, TSeoActionTypes } from './seo.types'; -import * as types from './types'; - -import HotDropsFavicon from '../../components/MockUpPage/assets/Hotdrops-favicon.ico'; -import RairFavicon from '../../components/MockUpPage/assets/rair_favicon.ico'; -import { LoadingDefaultFavicon } from '../../images'; - -const hotDropsVar = import.meta.env.VITE_TESTNET; - -export let InitialState: TInfoSeo; - -if (hotDropsVar === 'true') { - InitialState = { - title: 'HotDrops Technologies', - ogTitle: 'HotDrops Technologies', - twitterTitle: 'HotDrops Technologies', - contentName: 'author', - content: 'Digital Ownership Encryption', - description: - 'HotDrops is a Blockchain-based digital rights management platform that uses NFTs to gate access to streaming content', - ogDescription: 'Encrypted, Streaming NFTs', - twitterDescription: 'Encrypted, Streaming NFTs', - image: 'https://hotdrops.live/static/media/hotdrops-default.e7c4e7eb.png', - favicon: LoadingDefaultFavicon, - faviconMobile: LoadingDefaultFavicon - }; -} else { - InitialState = { - title: 'RAIR Technologies', - ogTitle: 'RAIR Technologies', - twitterTitle: 'RAIR Technologies', - contentName: 'author', - content: 'Digital Ownership Encryption', - description: - 'RAIR is a Blockchain-based digital rights management platform that uses NFTs to gate access to streaming content', - ogDescription: 'Encrypted, Streaming NFTs', - twitterDescription: 'Encrypted, Streaming NFTs', - image: `${ - import.meta.env.VITE_IPFS_GATEWAY - }/QmNtfjBAPYEFxXiHmY5kcPh9huzkwquHBcn9ZJHGe7hfaW`, - favicon: LoadingDefaultFavicon, - faviconMobile: LoadingDefaultFavicon - }; -} - -export default function seoStore( - state: TInfoSeo = InitialState, - action: TSeoActionTypes -): TInfoSeo { - switch (action.type) { - case types.SET_INFO_HELMET: - return { - ...state, - title: action.info.title, - ogTitle: action.info.ogTitle, - ogDescription: action.info.ogDescription, - contentName: action.info.contentName, - content: action.info.content, - description: action.info.description, - favicon: action.info.favicon, - faviconMobile: action.info.faviconMobile, - image: action.info.image, - twitterTitle: action.info.twitterTitle, - twitterDescription: action.info.twitterDescription - }; - case types.RESET_INFO_HELMET: - return { - ...state, - title: '', - ogTitle: '', - ogDescription: '', - contentName: '', - content: '', - description: '', - favicon: '', - faviconMobile: '', - image: '', - twitterTitle: '', - twitterDescription: '' - }; - - default: - return state; - } -} diff --git a/rair-front/src/ducks/seo/seo.types.ts b/rair-front/src/ducks/seo/seo.types.ts deleted file mode 100644 index c331761c4..000000000 --- a/rair-front/src/ducks/seo/seo.types.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { resetInfoSeo, setInfoSEO } from './actions'; - -export type TInfoSeo = { - title?: string; - ogTitle?: string; - ogDescription?: string; - contentName: string; - content?: string; - description?: string; - favicon?: string; - faviconMobile?: string; - image?: string; - twitterTitle?: string; - twitterDescription?: string; -}; - -export type TSetInfoSeo = ReturnType; -export type TResetInfoSeo = ReturnType; - -export type TSeoActionTypes = TSetInfoSeo | TResetInfoSeo; diff --git a/rair-front/src/ducks/seo/types.ts b/rair-front/src/ducks/seo/types.ts deleted file mode 100644 index d460cb741..000000000 --- a/rair-front/src/ducks/seo/types.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const SET_INFO_HELMET = 'SET_INFO_HELMET'; -export const RESET_INFO_HELMET = 'RESET_INFO_HELMET'; diff --git a/rair-front/src/ducks/uploadDemo/action.ts b/rair-front/src/ducks/uploadDemo/action.ts deleted file mode 100644 index 00404a079..000000000 --- a/rair-front/src/ducks/uploadDemo/action.ts +++ /dev/null @@ -1,15 +0,0 @@ -import * as types from './types'; - -const uploadVideoStart = () => ({ type: types.UPLOAD_VIDEO_START }) as const; -const uploadVideoEnd = () => ({ type: types.UPLOAD_VIDEO_END }) as const; -const uploadVideoSuccess = () => - ({ type: types.UPLOAD_VIDEO_SUCCESS }) as const; -const getProviderError = (error: string | null) => - ({ type: types.UPLOAD_VIDEO_ERROR, error }) as const; - -export { - getProviderError, - uploadVideoEnd, - uploadVideoStart, - uploadVideoSuccess -}; diff --git a/rair-front/src/ducks/uploadDemo/reducers.ts b/rair-front/src/ducks/uploadDemo/reducers.ts deleted file mode 100644 index 17dcef428..000000000 --- a/rair-front/src/ducks/uploadDemo/reducers.ts +++ /dev/null @@ -1,36 +0,0 @@ -import * as types from './types'; - -const InitialState = { - error: null, - uploadVideo: false, - successUploaded: false -}; - -export default function VideoDemoStore(state = InitialState, action) { - switch (action.type) { - case types.UPLOAD_VIDEO_START: - return { - ...state, - uploadVideo: true, - successUploaded: false - }; - case types.UPLOAD_VIDEO_END: - return { - ...state, - uploadVideo: false - }; - - case types.UPLOAD_VIDEO_SUCCESS: - return { - ...state, - successUploaded: true - }; - case types.UPLOAD_VIDEO_ERROR: - return { - ...state, - error: action.error - }; - default: - return state; - } -} diff --git a/rair-front/src/ducks/uploadDemo/types.ts b/rair-front/src/ducks/uploadDemo/types.ts deleted file mode 100644 index b8d157b94..000000000 --- a/rair-front/src/ducks/uploadDemo/types.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const UPLOAD_VIDEO_START = 'UPLOAD_VIDEO_START'; -export const UPLOAD_VIDEO_END = 'UPLOAD_VIDEO_END'; -export const UPLOAD_VIDEO_ERROR = 'UPLOAD_VIDEO_ERROR'; -export const UPLOAD_VIDEO_SUCCESS = 'UPLOAD_VIDEO_SUCCESS'; diff --git a/rair-front/src/ducks/users/actions.ts b/rair-front/src/ducks/users/actions.ts deleted file mode 100644 index 5a2654c87..000000000 --- a/rair-front/src/ducks/users/actions.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { - GET_USER_COMPLETE, - GET_USER_ERROR, - GET_USER_START, - LOGIN_PROCESS_UPDATE, - LOGIN_STATUS_UPDATE, - SET_ADMIN_RIGHTS, - SET_LOGIN_TYPE, - SET_SUPER_ADMIN, - SET_USER_DATA -} from './types'; -import { UserQueryType, UserType } from './users.types'; - -const setLoginType = (loginType: string) => - ({ - type: SET_LOGIN_TYPE, - loginType - }) as const; - -const setUserData = (userData: UserQueryType) => - ({ - type: SET_USER_DATA, - userData - }) as const; - -const setLoginProcessStatus = (value: boolean) => - ({ - type: LOGIN_PROCESS_UPDATE, - value - }) as const; - -const setLogInStatus = (value: boolean) => - ({ - type: LOGIN_STATUS_UPDATE, - value - }) as const; - -const getUserStart = (publicAddress: string) => - ({ - type: GET_USER_START, - publicAddress: publicAddress - }) as const; - -const setAdminRights = (adminRights: boolean | undefined) => - ({ - type: SET_ADMIN_RIGHTS, - adminRights - }) as const; -const setSuperAdmin = (superAdmin: boolean | undefined) => - ({ - type: SET_SUPER_ADMIN, - superAdmin - }) as const; -const getUserComplete = (userRd: UserType | null) => - ({ - type: GET_USER_COMPLETE, - userRd - }) as const; -const getUserError = (error: string) => - ({ - type: GET_USER_ERROR, - error - }) as const; - -export { - getUserComplete, - getUserError, - getUserStart, - setAdminRights, - setLoginProcessStatus, - setLogInStatus, - setLoginType, - setSuperAdmin, - setUserData -}; diff --git a/rair-front/src/ducks/users/reducers.ts b/rair-front/src/ducks/users/reducers.ts deleted file mode 100644 index 991f3a6e4..000000000 --- a/rair-front/src/ducks/users/reducers.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { - GET_USER_COMPLETE, - GET_USER_ERROR, - GET_USER_START, - LOGIN_PROCESS_UPDATE, - LOGIN_STATUS_UPDATE, - SET_ADMIN_RIGHTS, - SET_LOGIN_TYPE, - SET_SUPER_ADMIN, - SET_USER_DATA -} from './types'; -import { TUsersInitialState, UserReducerActionTypes } from './users.types'; - -const InitialState: TUsersInitialState = { - userRd: null, - error: null, - adminRights: undefined, - superAdmin: undefined, - loginProcess: false, - loggedIn: false, - userData: undefined, - loginType: undefined -}; - -export default function userStore( - state: TUsersInitialState = InitialState, - action: UserReducerActionTypes -): TUsersInitialState { - switch (action.type) { - case LOGIN_STATUS_UPDATE: - return { - ...state, - loggedIn: action.value - }; - case LOGIN_PROCESS_UPDATE: - return { - ...state, - loginProcess: action.value - }; - case SET_USER_DATA: - return { - ...state, - userData: action.userData - }; - case SET_LOGIN_TYPE: - return { - ...state, - loginType: action.loginType - }; - case GET_USER_START: - return { - ...state, - userRd: null - }; - case SET_ADMIN_RIGHTS: - return { - ...state, - adminRights: action.adminRights - }; - case SET_SUPER_ADMIN: - return { - ...state, - superAdmin: action.superAdmin - }; - case GET_USER_COMPLETE: - return { - ...state, - userRd: action.userRd - }; - case GET_USER_ERROR: - return { - ...state, - userRd: null, - error: action.error - }; - default: - return state; - } -} diff --git a/rair-front/src/ducks/users/sagas.ts b/rair-front/src/ducks/users/sagas.ts deleted file mode 100644 index 35bead53c..000000000 --- a/rair-front/src/ducks/users/sagas.ts +++ /dev/null @@ -1,49 +0,0 @@ -import axios, { AxiosError, AxiosResponse } from 'axios'; -import { constants, utils } from 'ethers'; -import { call, put, takeLatest } from 'redux-saga/effects'; - -import { getUserComplete, getUserError } from './actions'; -import * as types from './types'; - -import { TUserResponse } from '../../axios.responseTypes'; - -export type Params = { publicAddress: string; type: string }; - -export function* getUser({ publicAddress }: Params) { - try { - if ( - !utils.isAddress(publicAddress) || - publicAddress !== constants.AddressZero - ) { - return; - } - const response: AxiosResponse = yield call( - axios.get, - `/api/users/${publicAddress}` - ); - - if (response.data.user !== null && response.status === 200) { - yield put(getUserComplete(response.data.user)); - } - } catch (error) { - const errors = error as AxiosError; - if (errors.response !== undefined) { - if (errors.response.status === 404) { - const errorDirec = 'This address does not exist'; - yield put(getUserError(errorDirec)); - } else if (errors.response.status === 500) { - const errorServer = 'Sorry. an internal server problem has occurred'; - yield put(getUserError(errorServer)); - } else { - yield put(getUserError(errors.message)); - } - } else { - const errorConex = 'Connection error!'; - yield put(getUserError(errorConex)); - } - } -} - -export function* sagaUser() { - yield takeLatest(types.GET_USER_START, getUser); -} diff --git a/rair-front/src/ducks/users/types.ts b/rair-front/src/ducks/users/types.ts deleted file mode 100644 index f7c19982d..000000000 --- a/rair-front/src/ducks/users/types.ts +++ /dev/null @@ -1,10 +0,0 @@ -export const GET_USER_START = 'GET_USER_START'; -export const GET_USER_COMPLETE = 'GET_USER_COMPLETE'; -export const GET_USER_ERROR = 'GET_USER_ERROR'; -export const SET_ADMIN_RIGHTS = 'SET_ADMIN_RIGHTS'; -export const SET_SUPER_ADMIN = 'SET_SUPER_ADMIN'; -export const USER_LOGOUT = 'USER_LOGOUT'; -export const LOGIN_STATUS_UPDATE = 'LOGIN_STATUS_UPDATE'; -export const LOGIN_PROCESS_UPDATE = 'LOGIN_PROCESS_UPDATE'; -export const SET_USER_DATA = 'SET_USER_DATA'; -export const SET_LOGIN_TYPE = 'SET_LOGIN_TYPE'; diff --git a/rair-front/src/ducks/users/users.types.ts b/rair-front/src/ducks/users/users.types.ts deleted file mode 100644 index 19662f7df..000000000 --- a/rair-front/src/ducks/users/users.types.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { - getUserComplete, - getUserError, - getUserStart, - setAdminRights, - setLoginProcessStatus, - setLogInStatus, - setLoginType, - setSuperAdmin, - setUserData -} from './actions'; - -export type TUsersInitialState = { - userRd: UserType | null; - error: string | null; - adminRights: boolean | undefined; - superAdmin: boolean | undefined; - loginProcess: boolean; - loggedIn: boolean; - userData: UserQueryType | undefined; - loginType: string | undefined; -}; - -export type UserQueryType = { - email: string; - avatar: string | null; - firstName: string | null; - lastName: string | null; - publicAddress: string; - nickName: string | null; - adminRights: boolean; - superAdmin: boolean; - ageVerified: boolean | undefined; -}; - -export type UserType = { - adminNFT?: string; - avatar: string | null; - creationDate: string; - email: string | null; - firstName: string | null; - lastName: string | null; - nickName: string | null; - background: string | null; - ageVerified: boolean | undefined; - nonce?: string; - publicAddress: string; - _id: string; -}; - -export type UserResponseType = { - succes: boolean; - user: UserType; -}; - -export type GetUsersType = ReturnType; -export type SetAdminRights = ReturnType; -export type SetSuperAdmin = ReturnType; -export type GetUserComplete = ReturnType; -export type GetUserError = ReturnType; - -export type SetLoginProcessStatus = ReturnType; -export type SetLogInStatus = ReturnType; -export type SetUserData = ReturnType; -export type SetLoginType = ReturnType; - -export type UserReducerActionTypes = - | GetUsersType - | SetAdminRights - | SetSuperAdmin - | GetUserComplete - | GetUserError - | SetLoginProcessStatus - | SetLogInStatus - | SetUserData - | SetLoginType; diff --git a/rair-front/src/ducks/videos/actions.ts b/rair-front/src/ducks/videos/actions.ts deleted file mode 100644 index 0fced2bf6..000000000 --- a/rair-front/src/ducks/videos/actions.ts +++ /dev/null @@ -1,36 +0,0 @@ -import * as types from './types'; -import { TUpdataVideoParams } from './videosDucks.types'; - -import { MediaListResponseType } from '../../components/video/video.types'; - -const getListVideosStart = (params: TUpdataVideoParams) => - ({ - type: types.GET_LIST_VIDEOS_START, - params - }) as const; - -const setLoading = (loading: boolean) => - ({ type: types.SET_LOADING, loading }) as const; - -const getVideoListComplete = (videoList: MediaListResponseType | null) => - ({ type: types.GET_LIST_VIDEOS_COMPLETE, videoList }) as const; - -const getVideoListTotalClear = () => - ({ - type: types.GET_LIST_VIDEOS_TOTAL_CLEAR - }) as const; - -const getVideoListTotal = (totalNumberVideo: number) => - ({ type: types.GET_LIST_VIDEOS_TOTAL, totalNumberVideo }) as const; - -const getListVideosError = (error: string | null) => - ({ type: types.GET_LIST_VIDEOS_ERROR, error }) as const; - -export { - getListVideosError, - getListVideosStart, - getVideoListComplete, - getVideoListTotal, - getVideoListTotalClear, - setLoading -}; diff --git a/rair-front/src/ducks/videos/reducers.ts b/rair-front/src/ducks/videos/reducers.ts deleted file mode 100644 index 8810710cb..000000000 --- a/rair-front/src/ducks/videos/reducers.ts +++ /dev/null @@ -1,46 +0,0 @@ -import * as types from './types'; -import { TVideosActions, TVideosInitialState } from './videosDucks.types'; - -const InitialState: TVideosInitialState = { - videos: null, - error: null, - totalNumberVideo: undefined, - loading: false -}; - -export default function videosStore( - state: TVideosInitialState = InitialState, - action: TVideosActions -): TVideosInitialState { - switch (action.type) { - case types.GET_LIST_VIDEOS_COMPLETE: - return { - ...state, - videos: action.videoList - }; - case types.GET_LIST_VIDEOS_TOTAL_CLEAR: - return { - ...state, - totalNumberVideo: 0 - }; - case types.GET_LIST_VIDEOS_TOTAL: - return { - ...state, - totalNumberVideo: action.totalNumberVideo - }; - case types.GET_LIST_VIDEOS_ERROR: - return { - ...state, - videos: null, - error: action.error - }; - - case types.SET_LOADING: - return { - ...state, - loading: action.loading - }; - default: - return state; - } -} diff --git a/rair-front/src/ducks/videos/sagas.ts b/rair-front/src/ducks/videos/sagas.ts deleted file mode 100644 index 1eaf1a312..000000000 --- a/rair-front/src/ducks/videos/sagas.ts +++ /dev/null @@ -1,65 +0,0 @@ -import axios, { AxiosError, AxiosResponse } from 'axios'; -import { call, put, takeLatest } from 'redux-saga/effects'; - -import { - getListVideosError, - getVideoListComplete, - getVideoListTotal, - setLoading -} from './actions'; -import * as types from './types'; -import { TUpdataVideoParams } from './videosDucks.types'; - -import { BackendResponse, TMediaList } from '../../axios.responseTypes'; - -export type TParamsVideosSaga = { - type: string; - params: TUpdataVideoParams; -}; - -export function* getVideos({ params }: TParamsVideosSaga) { - try { - yield put(setLoading(true)); - const videos: AxiosResponse = yield call( - axios.get, - `/api/files/list?itemsPerPage=${params.itemsPerPage}` + - `${params.pageNum ? '&pageNum=' + params.pageNum : ''}` + - `${params.blockchain ? '&blockchain=' + params.blockchain : ''}` + - `${params.category ? params.category : ''}` + - `${ - params.publicAddress ? '&userAddress=' + params.publicAddress : '' - }` + - `${params.mediaTitle ? '&mediaTitle=' + params.mediaTitle : ''}` - ); - - if (videos !== undefined && videos.status === 200) { - yield put(getVideoListComplete(videos.data.list)); - yield put(getVideoListTotal(videos.data.totalNumber)); - yield put(setLoading(false)); - } - } catch (error) { - const errors = error as AxiosError; - yield put(setLoading(false)); - const errorData: BackendResponse = errors?.response - ?.data as BackendResponse; - - if (errors.response !== undefined) { - if (errors.response.status === 404) { - const errorDirec = 'This address does not exist'; - yield put(getListVideosError(errorDirec)); - } else if (errors.response.status === 500) { - const errorServer = 'Sorry. an internal server problem has occurred'; - yield put(getListVideosError(errorServer)); - } else { - yield put(getListVideosError(errorData.message)); - } - } else { - const errorConex = 'Connection error!'; - yield put(getListVideosError(errorConex)); - } - } -} - -export function* sagaVideos() { - yield takeLatest(types.GET_LIST_VIDEOS_START, getVideos); -} diff --git a/rair-front/src/ducks/videos/types.ts b/rair-front/src/ducks/videos/types.ts deleted file mode 100644 index 46613e66f..000000000 --- a/rair-front/src/ducks/videos/types.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const GET_LIST_VIDEOS_START = 'GET_LIST_VIDEOS_START'; -export const GET_LIST_VIDEOS_COMPLETE = 'GET_LIST_VIDEOS_COMPLETE'; -export const GET_LIST_VIDEOS_TOTAL_CLEAR = 'GET_LIST_VIDEOS_TOTAL_CLEAR'; -export const GET_LIST_VIDEOS_TOTAL = 'GET_LIST_VIDEOS_TOTAL'; -export const GET_LIST_VIDEOS_ERROR = 'GET_LIST_VIDEOS_ERROR'; -export const SET_LOADING = 'SET_LOADING'; diff --git a/rair-front/src/ducks/videos/videosDucks.types.ts b/rair-front/src/ducks/videos/videosDucks.types.ts deleted file mode 100644 index 1c000ccf6..000000000 --- a/rair-front/src/ducks/videos/videosDucks.types.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { - getListVideosError, - getListVideosStart, - getVideoListComplete, - getVideoListTotal, - getVideoListTotalClear, - setLoading -} from './actions'; - -import { MediaListResponseType } from '../../components/video/video.types'; - -export type TVideosInitialState = { - videos: MediaListResponseType | null; - error: string | null; - loading: boolean; - totalNumberVideo: number | undefined; -}; - -export type TUpdataVideoParams = { - itemsPerPage: number; - pageNum: number; - category: string; - blockchain: string; - publicAddress?: string; - mediaTitle?: string; -}; - -export type TGetListVideosStart = ReturnType; -export type TGetVideoListComplete = ReturnType; -export type TGetListVideosTotalClear = ReturnType< - typeof getVideoListTotalClear ->; -export type TetListVideosTotal = ReturnType; -export type TGetListVideosError = ReturnType; -export type TSetLoading = ReturnType; - -export type TVideosActions = - | TGetListVideosStart - | TGetVideoListComplete - | TGetListVideosError - | TGetListVideosTotalClear - | TetListVideosTotal - | TSetLoading; diff --git a/rair-front/src/hooks/useConnectUser.tsx b/rair-front/src/hooks/useConnectUser.tsx index 84afcc081..f7e50cc3c 100644 --- a/rair-front/src/hooks/useConnectUser.tsx +++ b/rair-front/src/hooks/useConnectUser.tsx @@ -1,39 +1,32 @@ -//@ts-nocheck import { useCallback, useEffect, useState } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; import { useNavigate } from 'react-router'; -import { MultiOwnerModularAccount } from '@alchemy/aa-accounts'; -import { AccountSigner } from '@alchemy/aa-ethers'; +import { Action } from '@reduxjs/toolkit'; import axios from 'axios'; +import { Hex } from 'viem'; +import { useAppDispatch, useAppSelector } from './useReduxHooks'; +import useServerSettings from './useServerSettings'; import useSwal from './useSwal'; -import useWeb3Tx from './useWeb3Tx'; import { TUserResponse } from '../axios.responseTypes'; -import useServerSettings from '../components/adminViews/useServerSettings'; import { OnboardingButton } from '../components/common/OnboardingButton/OnboardingButton'; -import { RootState } from '../ducks'; -import { getTokenComplete, getTokenStart } from '../ducks/auth/actions'; -import { ColorStoreType } from '../ducks/colors/colorStore.types'; +import { dataStatuses } from '../redux/commonTypes'; +import { loadCurrentUser } from '../redux/userSlice'; import { - setChainId, - setCoingeckoRates, - setProgrammaticProvider, - setUserAddress -} from '../ducks/contracts/actions'; -import { ContractsInitialType } from '../ducks/contracts/contracts.types'; -import { - getUserComplete, - setAdminRights, - setLoginProcessStatus, - setLogInStatus, - setLoginType, - setSuperAdmin, - setUserData -} from '../ducks/users/actions'; -import { TUsersInitialState } from '../ducks/users/users.types'; + connectChainMetamask, + connectChainWeb3Auth, + setConnectedChain, + setExchangeRates, + setProgrammaticProvider +} from '../redux/web3Slice'; +import { CombinedBlockchainData } from '../types/commonTypes'; +import { User } from '../types/databaseTypes'; import chainData from '../utils/blockchainData'; -import { rFetch, signWeb3Message } from '../utils/rFetch'; +import { + rFetch, + signWeb3MessageMetamask, + signWeb3MessageWeb3Auth +} from '../utils/rFetch'; import sockets from '../utils/sockets'; const getCoingeckoRates = async () => { @@ -63,25 +56,19 @@ const getCoingeckoRates = async () => { }; const useConnectUser = () => { - const dispatch = useDispatch(); - const { blockchainSettings, getBlockchainData, refreshBlockchainData } = - useServerSettings(); - const { adminRights, loginProcess, loggedIn } = useSelector< - RootState, - TUsersInitialState - >((store) => store.userStore); + const dispatch = useAppDispatch(); + const { getBlockchainData } = useServerSettings(); + const { adminRights, loginStatus, isLoggedIn } = useAppSelector( + (store) => store.user + ); const [metamaskInstalled, setMetamaskInstalled] = useState(false); - const { currentUserAddress, programmaticProvider, currentChain } = - useSelector( - (store) => store.contractStore - ); - const { connectWeb3AuthProgrammaticProvider } = useWeb3Tx(); + const { currentUserAddress, programmaticProvider, connectedChain } = + useAppSelector((store) => store.web3); - const { textColor, primaryButtonColor, primaryColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); + const { textColor, primaryButtonColor, primaryColor } = useAppSelector( + (store) => store.colors + ); const hotdropsVar = import.meta.env.VITE_TESTNET; @@ -104,53 +91,57 @@ const useConnectUser = () => { }, [currentUserAddress]); const loginWithWeb3Auth = useCallback(async () => { - if (!currentChain) { - return; - } - const chainInformation = getBlockchainData(currentChain); + const defaultChain: Hex = import.meta.env.VITE_DEFAULT_BLOCKCHAIN; + const chainInformation = getBlockchainData(defaultChain); if ( + !chainInformation?.hash || !chainInformation?.alchemy || !chainInformation?.viem || !chainInformation?.alchemyAppKey ) { - return; + return {}; } - const provider = - await connectWeb3AuthProgrammaticProvider(chainInformation); + reactSwal.fire({ + title: 'Connecting', + html: 'Please wait', + icon: 'info', + showConfirmButton: false + }); + + const { connectedChain, currentUserAddress, userDetails } = await dispatch( + connectChainWeb3Auth(chainInformation as CombinedBlockchainData) + ).unwrap(); return { - userAddress: provider.account.account.address, - ownerAddress: provider.account.account.publicKey, - blockchain: currentChain, - alchemyProvider: provider + userAddress: currentUserAddress, + blockchain: connectedChain, + userDetails }; - }, [currentChain, connectWeb3AuthProgrammaticProvider]); + }, [getBlockchainData, reactSwal, dispatch]); const loginWithMetamask = useCallback(async () => { - const accounts = await window.ethereum.request({ - method: 'eth_requestAccounts' - }); - if (!accounts) { - return { address: undefined, blockchain: undefined }; + const { connectedChain, currentUserAddress } = await dispatch( + connectChainMetamask() + ).unwrap(); + if (!currentUserAddress) { + return {}; } return { - userAddress: accounts[0], - signerAddress: accounts[0], - blockchain: window.ethereum.chainId?.toLowerCase() as BlockchainType + userAddress: currentUserAddress, + blockchain: connectedChain }; - }, []); + }, [dispatch]); const loginWithProgrammaticProvider = useCallback(async () => { if (!programmaticProvider) { - return { address: undefined, blockchain: undefined }; + return {}; } return { - userAddress: programmaticProvider.address, - signerAddress: programmaticProvider.address, - blockchain: currentChain + userAddress: (await programmaticProvider.getAddress()) as Hex, + blockchain: connectedChain }; - }, [currentChain, programmaticProvider]); + }, [connectedChain, programmaticProvider]); const selectMethod = useCallback( () => @@ -219,18 +210,12 @@ const useConnectUser = () => { ); const connectUserData = useCallback(async () => { - dispatch(setLoginProcessStatus(true)); - let loginData: - | { - userAddress: string | undefined; - ownerAddress: string | undefined; - blockchain: BlockchainType | undefined; - idToken?: string; - provider?: string; - alchemyProvider?: AccountSigner; - } - | undefined; - const dispatchStack = []; + let loginData: { + userAddress?: Hex; + blockchain?: Hex; + userDetails?: any; + }; + const dispatchStack: Array = []; const loginMethod: string = await selectMethod(); reactSwal.close(); try { @@ -254,23 +239,19 @@ const useConnectUser = () => { ), icon: 'error' }); - dispatch(setLoginProcessStatus(false)); return; } } catch (err) { console.error('Login error', err); - dispatch(setLoginProcessStatus(false)); return; } - if (!loginData?.userAddress || loginData?.userAddress === '') { + if (!loginData?.userAddress) { reactSwal.fire('Error', 'No user address found', 'error'); - dispatch(setLoginProcessStatus(false)); return; } - dispatchStack.push(setCoingeckoRates(await getCoingeckoRates())); - - dispatchStack.push(setChainId(loginData.blockchain, blockchainSettings)); + dispatchStack.push(setExchangeRates(await getCoingeckoRates())); + dispatchStack.push(setConnectedChain(loginData.blockchain)); let firstTimeLogin = false; @@ -293,7 +274,7 @@ const useConnectUser = () => { } } ); - user = userCreation.data; + user = userCreation.data.user; } // Authorize user @@ -302,29 +283,24 @@ const useConnectUser = () => { adminRights === undefined || !currentUserAddress ) { - dispatchStack.push(getTokenStart()); let loginResponse; switch (loginMethod) { case 'programmatic': - loginResponse = await signWeb3Message( - loginData.userAddress, - 'programmatic', - programmaticProvider?._signTypedData - ); + console.error('Programmatic support not available'); break; case 'metamask': - loginResponse = await signWeb3Message(loginData.userAddress); + loginResponse = await signWeb3MessageMetamask( + loginData.userAddress + ); break; case 'web3auth': - loginResponse = await signWeb3Message( - loginData.userAddress, - 'web3auth', - loginData.alchemyProvider.signTypedData, - loginData.ownerAddress + loginResponse = await signWeb3MessageWeb3Auth( + loginData.userAddress ); + reactSwal.close(); if (firstTimeLogin) { - const userData = await loginData.alchemyProvider.userDetails(); - const availableData = {}; + const userData = await loginData.userDetails; + const availableData: Partial = {}; if (userData.email) { availableData.email = userData.email; availableData.nickName = userData.email?.split('@')?.[0]; @@ -342,27 +318,16 @@ const useConnectUser = () => { // provider.accountProvider.signTypedData break; } - if (!userDataResponse.data.success) { - dispatch(setAdminRights(false)); - dispatch(setUserData(undefined)); - } else if (loginResponse.success) { - dispatch(setUserData(user)); - dispatchStack.push(setUserAddress(loginResponse.user.publicAddress)); - dispatchStack.push(getUserComplete(loginResponse.user)); - dispatchStack.push(setAdminRights(loginResponse.user.adminRights)); - dispatchStack.push(setSuperAdmin(loginResponse.user.superAdmin)); - dispatchStack.push(setLoginType(loginMethod)); + dispatch(loadCurrentUser()); + if (loginResponse.success) { dispatchStack.forEach((dispatchItem) => { dispatch(dispatchItem); }); - dispatch(setLogInStatus(true)); sockets.nodeSocket.connect(); } } - dispatch(setLoginProcessStatus(false)); } catch (err) { console.error('Error on login', err); - dispatch(setLoginProcessStatus(false)); } }, [ selectMethod, @@ -372,69 +337,47 @@ const useConnectUser = () => { reactSwal, adminRights, currentUserAddress, - programmaticProvider, - dispatch, - blockchainSettings + dispatch ]); useEffect(() => { checkMetamask(); }, [checkMetamask]); - useEffect(() => { - if (loggedIn || loginProcess) { - return; - } - (async () => { - dispatch(setLoginProcessStatus(true)); - const { success, user } = await rFetch( - '/api/auth/me/', - undefined, - undefined, - false - ); - if (success && user) { - if (!window?.ethereum?.selectedAddress) { - // Metamask isn't connected anymore to the page, - // it's unreliable to use the login data in this case - dispatch(setLoginProcessStatus(false)); - return await logoutUser(); - } - const chains = await refreshBlockchainData(); - dispatch(setChainId(window.ethereum.chainId, chains)); - dispatch(setLoginType('metamask')); // Because web3 logins end on page reload - dispatch(setCoingeckoRates(await getCoingeckoRates())); - dispatch(setUserData(user)); - dispatch(setUserAddress(user.publicAddress)); - dispatch(getUserComplete(user)); - dispatch(setAdminRights(user.adminRights)); - dispatch(setSuperAdmin(user.superAdmin)); - dispatch(setLogInStatus(true)); - } - dispatch(setLoginProcessStatus(false)); - })(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - const logoutUser = useCallback(async () => { const { success } = await rFetch('/api/auth/logout'); if (success) { - sockets.nodeSocket.emit('logout', currentUserAddress.toLowerCase()); + dispatch(loadCurrentUser()); + sockets.nodeSocket.emit('logout', currentUserAddress?.toLowerCase()); sockets.nodeSocket.disconnect(); - dispatch(getTokenComplete(null)); - dispatch(setUserAddress(undefined)); - dispatch(setAdminRights(false)); - dispatch(setLoginType(undefined)); - dispatch(setLogInStatus(false)); - dispatch(setUserData(undefined)); dispatch(setProgrammaticProvider(undefined)); - dispatch( - setChainId(import.meta.env.VITE_DEFAULT_BLOCKCHAIN), - blockchainSettings - ); + dispatch(setConnectedChain(import.meta.env.VITE_DEFAULT_BLOCKCHAIN)); navigate('/'); } - }, [dispatch, navigate, currentUserAddress, blockchainSettings]); + }, [dispatch, navigate, currentUserAddress]); + + const checkLoginOnStart = useCallback(async () => { + if (isLoggedIn || loginStatus !== dataStatuses.Uninitialized) { + return; + } + const userData = await dispatch(loadCurrentUser()).unwrap(); + switch (userData?.loginType) { + case 'metamask': + if (window.ethereum.selectedAddress !== userData.publicAddress) { + return await logoutUser(); + } + dispatch(setExchangeRates(await getCoingeckoRates())); + dispatch(connectChainMetamask()); + break; + default: + logoutUser(); + break; + } + }, [dispatch, isLoggedIn, loginStatus, logoutUser]); + + useEffect(() => { + checkLoginOnStart(); + }, []); return { connectUserData, diff --git a/rair-front/src/hooks/useContracts.tsx b/rair-front/src/hooks/useContracts.tsx new file mode 100644 index 000000000..7d30aff69 --- /dev/null +++ b/rair-front/src/hooks/useContracts.tsx @@ -0,0 +1,221 @@ +//@ts-nocheck +/* eslint-disable no-case-declarations */ +import { useCallback, useEffect, useState } from 'react'; +import { createModularAccountAlchemyClient } from '@alchemy/aa-alchemy'; +import { SmartContractAccount } from '@alchemy/aa-core'; +import { AccountSigner, EthersProviderAdapter } from '@alchemy/aa-ethers'; +import { Web3AuthSigner } from '@alchemy/aa-signers/web3auth'; +import { Alchemy } from 'alchemy-sdk'; +import { BrowserProvider, Contract, isAddress, JsonRpcSigner } from 'ethers'; +import { Hex } from 'viem'; + +import { useAppSelector } from './useReduxHooks'; +import useServerSettings from './useServerSettings'; + +import { + ContractABI, + diamondFactoryAbi, + diamondMarketplaceAbi, + erc777Abi, + factoryAbi, + licenseExchangeABI +} from '../contracts'; + +const useContracts = () => { + const { getBlockchainData } = useServerSettings(); + const { loginType, isLoggedIn } = useAppSelector((store) => store.user); + const { connectedChain } = useAppSelector((store) => store.web3); + + const [signer, setSigner] = useState< + JsonRpcSigner | AccountSigner + >(); + const [diamondFactoryInstance, setDiamondFactoryInstance] = useState< + Contract | undefined + >(); + const [diamondMarketplaceInstance, setDiamondMarketplaceInstance] = useState< + Contract | undefined + >(); + const [mainTokenInstance, setMainTokenInstance] = useState< + Contract | undefined + >(); + const [classicFactoryInstance, setClassicFactoryInstance] = useState< + Contract | undefined + >(); + const [licenseExchangeInstance, setLicenseExchangeInstance] = useState< + Contract | undefined + >(); + + const createWeb3AuthSigner = useCallback(async () => { + const chainData = getBlockchainData(connectedChain); + + if (!chainData) { + return; + } + + const web3AuthSigner = new Web3AuthSigner({ + clientId: import.meta.env.VITE_WEB3AUTH_CLIENT_ID, + chainConfig: { + chainNamespace: 'eip155', + chainId: chainData.chainId, + rpcTarget: chainData.rpcEndpoint, + displayName: chainData.name, + blockExplorer: chainData.blockExplorerGateway, + ticker: chainData.symbol, + tickerName: chainData.name + }, + web3AuthNetwork: chainData.testnet + ? 'sapphire_devnet' + : 'sapphire_mainnet' + }); + + await web3AuthSigner.authenticate({ + init: async () => { + await web3AuthSigner.inner.initModal(); + }, + connect: async () => { + await web3AuthSigner.inner.connect(); + } + }); + + const modularAccount = await createModularAccountAlchemyClient({ + apiKey: chainData.alchemyAppKey, + chain: chainData.viem!, + signer: web3AuthSigner, + gasManagerConfig: chainData.alchemyGasPolicy + ? { + policyId: chainData.alchemyGasPolicy + } + : undefined + }); + + const alchemy = new Alchemy({ + apiKey: chainData.alchemyAppKey, + network: chainData?.alchemy, + maxRetries: 10 + }); + + const ethersProvider = await alchemy.config.getProvider(); + const provider = + EthersProviderAdapter.fromEthersProvider(ethersProvider).connectToAccount( + modularAccount + ); + + return provider; + }, [connectedChain, getBlockchainData]); + + const refreshSigner = useCallback(async () => { + if (!isLoggedIn) { + return; + } + switch (loginType) { + case 'metamask': + if (!window.ethereum.isConnected()) { + return; + } + const metamaskProvider = new BrowserProvider(window.ethereum); + const signer = await metamaskProvider.getSigner(0); + setSigner(signer); + break; + case 'web3auth': + setSigner(await createWeb3AuthSigner()); + break; + } + }, [loginType, isLoggedIn, createWeb3AuthSigner]); + + useEffect(() => { + refreshSigner(); + }, [refreshSigner, connectedChain]); + + const contractCreator = useCallback( + (address: Hex | undefined, abi: ContractABI) => { + if (isLoggedIn && !signer) { + refreshSigner(); + return; + } + if (address && isAddress(address) && signer) { + return new Contract(address, abi, signer); + } + }, + [isLoggedIn, refreshSigner, signer] + ); + + useEffect(() => { + if (!signer) { + return; + } + const chainData = getBlockchainData(connectedChain); + if ( + chainData?.diamondFactoryAddress && + isAddress(chainData?.diamondFactoryAddress) + ) { + setDiamondFactoryInstance( + new Contract( + chainData?.diamondFactoryAddress, + diamondFactoryAbi, + signer + ) + ); + } else { + setDiamondFactoryInstance(undefined); + } + + if ( + chainData?.diamondMarketplaceAddress && + isAddress(chainData?.diamondMarketplaceAddress) + ) { + setDiamondMarketplaceInstance( + new Contract( + chainData?.diamondMarketplaceAddress, + diamondMarketplaceAbi, + signer + ) + ); + } else { + setDiamondMarketplaceInstance(undefined); + } + + if (chainData?.mainTokenAddress && isAddress(chainData?.mainTokenAddress)) { + setMainTokenInstance( + new Contract(chainData?.mainTokenAddress, erc777Abi, signer) + ); + } else { + setMainTokenInstance(undefined); + } + if ( + chainData?.classicFactoryAddress && + isAddress(chainData?.classicFactoryAddress) + ) { + setClassicFactoryInstance( + new Contract(chainData?.classicFactoryAddress, factoryAbi, signer) + ); + } else { + setClassicFactoryInstance(undefined); + } + if ( + chainData?.licenseExchangeAddress && + isAddress(chainData?.licenseExchangeAddress) + ) { + setLicenseExchangeInstance( + new Contract( + chainData?.licenseExchangeAddress, + licenseExchangeABI, + signer + ) + ); + } else { + setLicenseExchangeInstance(undefined); + } + }, [getBlockchainData, connectedChain, signer]); + + return { + diamondFactoryInstance, + diamondMarketplaceInstance, + mainTokenInstance, + classicFactoryInstance, + licenseExchangeInstance, + contractCreator, + refreshSigner + }; +}; + +export default useContracts; diff --git a/rair-front/src/hooks/useIPFSImageLink.tsx b/rair-front/src/hooks/useIPFSImageLink.tsx index bbee561c5..ff6f31ec5 100644 --- a/rair-front/src/hooks/useIPFSImageLink.tsx +++ b/rair-front/src/hooks/useIPFSImageLink.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react'; -function useIPFSImageLink(initialImageLink: any) { - const [ipfsLink, setIpfsLink] = useState(''); +function useIPFSImageLink(initialImageLink: string | undefined) { + const [ipfsLink, setIpfsLink] = useState(''); useEffect(() => { if (initialImageLink) { const linkSplit = initialImageLink?.split('/'); diff --git a/rair-front/src/hooks/useOpenVideoPlayer.tsx b/rair-front/src/hooks/useOpenVideoPlayer.tsx index fc684824c..d997a274c 100644 --- a/rair-front/src/hooks/useOpenVideoPlayer.tsx +++ b/rair-front/src/hooks/useOpenVideoPlayer.tsx @@ -2,7 +2,7 @@ import { useState } from 'react'; export type TUseOpenVideoPlayer = [ boolean, - (value: boolean) => void, + React.Dispatch>, () => void ]; diff --git a/rair-front/src/hooks/useReduxHooks.tsx b/rair-front/src/hooks/useReduxHooks.tsx new file mode 100644 index 000000000..5b77c5450 --- /dev/null +++ b/rair-front/src/hooks/useReduxHooks.tsx @@ -0,0 +1,6 @@ +import { useDispatch, useSelector } from 'react-redux'; + +import type { AppDispatch, RootState } from '../redux/store'; + +export const useAppDispatch = useDispatch.withTypes(); +export const useAppSelector = useSelector.withTypes(); diff --git a/rair-front/src/hooks/useServerSettings.tsx b/rair-front/src/hooks/useServerSettings.tsx new file mode 100644 index 000000000..9d75c39cf --- /dev/null +++ b/rair-front/src/hooks/useServerSettings.tsx @@ -0,0 +1,87 @@ +import { useCallback, useEffect } from 'react'; +import { Hex } from 'viem'; + +import { useAppDispatch, useAppSelector } from './useReduxHooks'; +import useSwal from './useSwal'; + +import { HotdropsFavicon, RairFavicon } from '../images'; +import { loadSettings } from '../redux/settingsSlice'; +import chainData from '../utils/blockchainData'; +import { rFetch } from '../utils/rFetch'; + +const useServerSettings = () => { + const dispatch = useAppDispatch(); + + const reactSwal = useSwal(); + + const { blockchainSettings, favicon, customValues } = useAppSelector( + (store) => store.settings + ); + + const getBlockchainData = useCallback( + (chainId?: Hex) => { + if (!chainId) { + return; + } + return { + ...chainData[chainId], + ...blockchainSettings.find((chain) => chain.hash === chainId) + }; + }, + [blockchainSettings] + ); + + useEffect(() => { + const link: HTMLLinkElement = + document.querySelector("link[rel*='icon']") || + document.createElement('link'); + link.type = 'image/x-icon'; + link.rel = 'icon'; + link.href = favicon + ? favicon + : RairFavicon; + document.getElementsByTagName('head')[0].appendChild(link); + + return () => { + if (link?.parentNode) { + link.parentNode.removeChild(link); + } + }; + }, [favicon]); + + const getCustomValue = useCallback( + (key) => { + if (!key) { + return; + } + const data = customValues?.find((item) => item.name === key); + return data?.value; + }, + [customValues] + ); + + const updateServerSetting = useCallback( + async (setting) => { + const { success } = await rFetch(`/api/settings/`, { + method: 'POST', + body: JSON.stringify(setting), + headers: { + 'Content-Type': 'application/json' + } + }); + if (success) { + dispatch(loadSettings()); + reactSwal.fire('Success', 'Setting updated', 'success'); + } + }, + [dispatch, reactSwal] + ); + + return { + updateServerSetting, + getBlockchainData, + getCustomValue + }; +}; + +export default useServerSettings; diff --git a/rair-front/src/hooks/useSwal.ts b/rair-front/src/hooks/useSwal.ts index 4a6bca393..ab7e55e54 100644 --- a/rair-front/src/hooks/useSwal.ts +++ b/rair-front/src/hooks/useSwal.ts @@ -1,15 +1,11 @@ import { useCallback } from 'react'; -import { useSelector } from 'react-redux'; import Swal from 'sweetalert2'; import withReactContent from 'sweetalert2-react-content'; -import { RootState } from '../ducks'; -import { ColorStoreType } from '../ducks/colors/colorStore.types'; +import { useAppSelector } from './useReduxHooks'; const useSwal = () => { - const { primaryColor, textColor } = useSelector( - (store) => store.colorStore - ); + const { primaryColor, textColor } = useAppSelector((store) => store.colors); // eslint-disable-next-line react-hooks/exhaustive-deps const reactSwal = useCallback( diff --git a/rair-front/src/hooks/useWeb3Tx.ts b/rair-front/src/hooks/useWeb3Tx.ts index 59d8722d1..6be6fd1dc 100644 --- a/rair-front/src/hooks/useWeb3Tx.ts +++ b/rair-front/src/hooks/useWeb3Tx.ts @@ -1,55 +1,41 @@ -//@ts-nocheck -import { useCallback, useEffect } from 'react'; -import { useDispatch, useSelector } from 'react-redux'; -import { createModularAccountAlchemyClient } from '@alchemy/aa-alchemy'; +/* eslint-disable no-case-declarations */ +import { useCallback } from 'react'; import { SendUserOperationResult, UserOperationOverrides } from '@alchemy/aa-core'; -import { EthersProviderAdapter } from '@alchemy/aa-ethers'; -import { Web3AuthSigner } from '@alchemy/aa-signers/web3auth'; -import { Alchemy } from 'alchemy-sdk'; -import { Contract, ContractReceipt, ContractTransaction } from 'ethers'; -import { encodeFunctionData } from 'viem'; +import { Contract, ContractTransactionResponse } from 'ethers'; +import { encodeFunctionData, Hex } from 'viem'; +import { useAppDispatch, useAppSelector } from './useReduxHooks'; +import useServerSettings from './useServerSettings'; import useSwal from './useSwal'; -import useServerSettings from '../components/adminViews/useServerSettings'; -import { RootState } from '../ducks'; -import { - setChainId, - setProgrammaticProvider -} from '../ducks/contracts/actions'; -import { ContractsInitialType } from '../ducks/contracts/contracts.types'; -import { TUsersInitialState } from '../ducks/users/users.types'; +import { connectChainWeb3Auth, setConnectedChain } from '../redux/web3Slice'; +import { CombinedBlockchainData } from '../types/commonTypes'; import { rFetch } from '../utils/rFetch'; -import { TChainItemData } from '../utils/utils.types'; const confirmationsRequired = 2; type web3Options = { failureMessage?: string; callback?: () => void; - intendedBlockchain: BlockchainType; + intendedBlockchain?: Hex; sponsored?: Boolean; }; const useWeb3Tx = () => { - const dispatch = useDispatch(); - const { blockchainSettings, getBlockchainData } = useServerSettings(); + const dispatch = useAppDispatch(); + const { getBlockchainData } = useServerSettings(); - const { currentChain, currentUserAddress, programmaticProvider } = - useSelector( - (store) => store.contractStore - ); - const { loginType } = useSelector( - (store) => store.userStore - ); + const { connectedChain, currentUserAddress, programmaticProvider } = + useAppSelector((store) => store.web3); + const { loginType } = useAppSelector((store) => store.user); const reactSwal = useSwal(); const handleReceipt = useCallback( async (transactionHash: string, callback?: (() => void) | undefined) => { try { - await rFetch(`/api/transaction/${currentChain}/${transactionHash}`, { + await rFetch(`/api/transaction/${connectedChain}/${transactionHash}`, { method: 'POST' }); callback && callback(); @@ -57,7 +43,7 @@ const useWeb3Tx = () => { console.error(error); } }, - [currentChain] + [connectedChain] ); const handleWeb3Error = useCallback( @@ -145,67 +131,77 @@ const useWeb3Tx = () => { callback?: () => void; } ) => { - let paramsValidation: ContractTransaction; - if ( - (await contract.provider.getNetwork()).chainId !== Number(currentChain) - ) { - return; - } - if (!contract[method]) { - console.error(`Error calling function ${method}, no method found`); - return false; + let paramsValidation: ContractTransactionResponse; + const web3Function = contract.getFunction(method); + if (!web3Function) { + console.error(`Error no method called ${method} found`); + return undefined; } try { paramsValidation = await contract[method](...args); } catch (errorMessage) { + console.error('paramsValidation error', method); return handleWeb3Error(errorMessage, options?.failureMessage); } if (paramsValidation?.wait) { - let transactionReceipt: ContractReceipt; try { - transactionReceipt = await paramsValidation.wait( + const transactionReceipt = await paramsValidation.wait( confirmationsRequired ); + if (transactionReceipt && transactionReceipt.blockNumber) { + handleReceipt(transactionReceipt.hash, options?.callback); + } + return transactionReceipt?.hash; } catch (errorMessage) { console.error(`Error calling ${method}`); return handleWeb3Error(errorMessage, options?.failureMessage); } - if (transactionReceipt && transactionReceipt.blockNumber) { - handleReceipt(transactionReceipt.transactionHash, options?.callback); - } - return transactionReceipt.transactionHash; } return paramsValidation; }, - [handleReceipt, handleWeb3Error, currentChain] + [handleReceipt, handleWeb3Error] ); const verifyAAUserOperation = useCallback( - async (userOperation: SendUserOperationResult, options: web3Options) => { - if (!programmaticProvider) { + async ( + contractProvider: any, + userOperation: SendUserOperationResult, + options: web3Options + ) => { + if (!contractProvider) { console.error('Provider not found'); return; } try { - const txHash = - await programmaticProvider.waitForUserOperationTransaction({ - hash: userOperation.hash - }); + const txHash = await contractProvider.waitForUserOperationTransaction({ + hash: userOperation.hash + }); handleReceipt(txHash, options?.callback); return true; } catch (err: any) { const stringified = err.toString(); if ( - stringified.includes('Failed to find transaction for User Operation') + stringified + .toLowerCase() + .includes('failed to find transaction for user operation') ) { - reactSwal.fire('Please wait', 'Verifying user operation', 'info'); - return await verifyAAUserOperation(userOperation, options); + reactSwal.fire({ + title: 'Please wait', + html: 'Verifying user operation', + icon: 'info', + showConfirmButton: false + }); + return await verifyAAUserOperation( + contractProvider, + userOperation, + options + ); } console.error(err); reactSwal.fire('Error', err.toString(), 'error'); } }, - [programmaticProvider, handleReceipt, reactSwal] + [handleReceipt, reactSwal] ); const web3AuthCall = useCallback( @@ -215,24 +211,20 @@ const useWeb3Tx = () => { args: any[], options: web3Options ) => { - if (!currentUserAddress || !programmaticProvider) { + if (!currentUserAddress || !contract) { return; } - const methodFound = Object.keys(contract.interface.functions).find( - (item) => item.includes(`${method}(`) - ); - if ( - methodFound && - contract.interface.functions[methodFound].stateMutability === 'view' - ) { + const methodFound = contract.getFunction(method); + let fragment = methodFound.fragment; + if (!fragment) { + fragment = methodFound.getFragment(); + } + if (fragment.stateMutability === 'view') { // If the method is a view function, query the info directly through Ethers return await contract[method](...args); } - const fragment = contract.interface.fragments.find((fragment) => { - return fragment.name === method; - }); let transactionValue: bigint = BigInt(0); - if (args.at(-1).value) { + if (args?.at(-1)?.value !== undefined) { transactionValue = BigInt(args.pop().value); } const uoCallData = encodeFunctionData({ @@ -244,11 +236,9 @@ const useWeb3Tx = () => { const elegibleForSponsorship = options.sponsored && !transactionValue && - (await ( - programmaticProvider.account as any - ).checkGasSponsorshipEligibility({ + (await (contract.runner as any).account.checkGasSponsorshipEligibility({ uo: { - target: contract.address as `0x${string}`, + target: await contract.getAddress(), data: uoCallData, value: transactionValue } @@ -258,96 +248,52 @@ const useWeb3Tx = () => { paymasterAndData: '0x' }; - const userOperation = await (programmaticProvider.account as any) + const userOperation = await (contract.runner as any).account .sendUserOperation({ uo: { - target: contract.address as `0x${string}`, + target: await contract.getAddress(), data: uoCallData, value: transactionValue }, overrides: elegibleForSponsorship ? undefined : overrides }) .catch((err) => { - // console.info(err); + console.error(err); reactSwal.fire('Error', err.details, 'error'); }); if (!userOperation?.hash) { return false; } - return await verifyAAUserOperation(userOperation, options); + return await verifyAAUserOperation( + contract.runner, + userOperation, + options + ); }, - [currentUserAddress, programmaticProvider, reactSwal, verifyAAUserOperation] + [currentUserAddress, reactSwal, verifyAAUserOperation] ); const connectWeb3AuthProgrammaticProvider = useCallback( - async (chainData?: TChainItemData) => { + async (chainData?: CombinedBlockchainData) => { if (!chainData) { return; } - const alchemy = new Alchemy({ - apiKey: chainData.alchemyAppKey, - network: chainData?.alchemy, - maxRetries: 10 - }); - const ethersProvider = await alchemy.config.getProvider(); - - const alchemyProvider = - EthersProviderAdapter.fromEthersProvider(ethersProvider); - - const web3AuthSigner = new Web3AuthSigner({ - clientId: import.meta.env.VITE_WEB3AUTH_CLIENT_ID, - chainConfig: { - chainNamespace: 'eip155', - chainId: chainData.chainId, - rpcTarget: chainData.addChainData.rpcUrls[0], - displayName: chainData.name, - blockExplorer: chainData.addChainData.blockExplorerUrls[0], - ticker: chainData.symbol, - tickerName: chainData.name - }, - web3AuthNetwork: chainData.testnet - ? 'sapphire_devnet' - : 'sapphire_mainnet' - }); - - await web3AuthSigner.authenticate({ - init: async () => { - await web3AuthSigner.inner.initModal(); - }, - connect: async () => { - await web3AuthSigner.inner.connect(); - } - }); - - const a = await createModularAccountAlchemyClient({ - apiKey: chainData.alchemyAppKey, - chain: chainData.viem!, - signer: web3AuthSigner, - gasManagerConfig: chainData.alchemyGasPolicy - ? { - policyId: chainData.alchemyGasPolicy - } - : undefined - }); - - const provider = alchemyProvider.connectToAccount(a); - - dispatch(setProgrammaticProvider(provider)); - dispatch(setChainId(chainData.addChainData.chainId, blockchainSettings)); - provider.signTypedData = web3AuthSigner.signTypedData; - provider.userDetails = web3AuthSigner.getAuthDetails; - - return provider; + dispatch(connectChainWeb3Auth(chainData)); }, - [dispatch, blockchainSettings] + [dispatch] ); const metamaskSwitch = useCallback( - async (chainId: BlockchainType) => { + async (chainId: Hex) => { + const chainData = getBlockchainData(chainId); + if (!chainData) { + return; + } + dispatch(setConnectedChain()); try { await window.ethereum.request({ method: 'wallet_switchEthereumChain', - params: [{ chainId: chainId && getBlockchainData(chainId)?.hash }] + params: [{ chainId: chainData.hash }] }); } catch (switchError: any) { // This error code indicates that the chain has not been added to MetaMask. @@ -355,17 +301,31 @@ const useWeb3Tx = () => { try { await window.ethereum.request({ method: 'wallet_addEthereumChain', - params: [chainId && getBlockchainData(chainId)?.addChainData] + params: [ + { + chainId: chainData.hash, + chainName: chainData.name, + nativeCurrency: { + name: chainData.name, + symbol: chainData.symbol, + decimals: 18 + }, + rpcUrls: [chainData.rpcEndpoint], + blockExplorerUrls: [chainData.blockExplorerGateway] + } + ] }); } catch (addError) { + dispatch(setConnectedChain(connectedChain)); console.error(addError); } } else { + dispatch(setConnectedChain(connectedChain)); console.error(switchError); } } }, - [getBlockchainData] + [getBlockchainData, connectedChain, dispatch] ); const web3TxSignMessage = useCallback( @@ -383,7 +343,7 @@ const useWeb3Tx = () => { case 'web3auth': return programmaticProvider?.signMessage(message); default: - reactSwal.fire('Error', 'Please login', 'error'); + reactSwal.fire('Error', 'Please login.', 'error'); } }, [programmaticProvider, currentUserAddress, loginType, reactSwal] @@ -395,12 +355,12 @@ const useWeb3Tx = () => { method: string, args: any[] = [], options: web3Options = { - intendedBlockchain: currentChain as BlockchainType + intendedBlockchain: connectedChain } ) => { if (!currentUserAddress) { console.error(`Login required for Web3 call ${method}`); - return; + return undefined; } switch (loginType) { case 'metamask': @@ -409,10 +369,11 @@ const useWeb3Tx = () => { return web3AuthCall(contract, method, args, options); default: reactSwal.fire('Error', 'Please login', 'error'); + return undefined; } }, [ - currentChain, + connectedChain, currentUserAddress, loginType, metamaskCall, @@ -422,9 +383,9 @@ const useWeb3Tx = () => { ); const web3Switch = useCallback( - async (chainId: BlockchainType | undefined) => { + async (chainId: Hex | undefined) => { if (!chainId) { - reactSwal.fire('Unsupported blockchain'); + reactSwal.fire('Error', 'Blockchain not supported', 'error'); return; } if (!currentUserAddress) { @@ -438,15 +399,21 @@ const useWeb3Tx = () => { case 'metamask': return await metamaskSwitch(chainId); case 'web3auth': - if (!getBlockchainData(chainId)?.alchemyAppKey) { + const chainData = getBlockchainData(chainId); + if (!chainData) { + return; + } + if (!chainData?.alchemyAppKey) { reactSwal.fire( 'Sorry!', - `${getBlockchainData(chainId).name} is not supported currently`, + `${chainData?.name} is not supported currently`, 'info' ); return; } - await connectWeb3AuthProgrammaticProvider(getBlockchainData(chainId)); + await connectWeb3AuthProgrammaticProvider( + chainData as CombinedBlockchainData + ); } }, [ @@ -460,18 +427,17 @@ const useWeb3Tx = () => { ); const correctBlockchain = useCallback( - (chainId: BlockchainType) => { - return chainId === currentChain; + (chainId?: Hex) => { + return chainId === connectedChain; }, - [currentChain] + [connectedChain] ); return { correctBlockchain, web3Switch, web3TxHandler, - web3TxSignMessage, - connectWeb3AuthProgrammaticProvider + web3TxSignMessage }; }; diff --git a/rair-front/src/images/coreIdlogo.avif b/rair-front/src/images/coreIdlogo.avif new file mode 100644 index 000000000..c98c2abad Binary files /dev/null and b/rair-front/src/images/coreIdlogo.avif differ diff --git a/rair-front/src/images/coreNewIcon.png b/rair-front/src/images/coreNewIcon.png new file mode 100644 index 000000000..051ea552b Binary files /dev/null and b/rair-front/src/images/coreNewIcon.png differ diff --git a/rair-front/src/images/index.tsx b/rair-front/src/images/index.tsx index 34fac8d12..6135fc8ef 100644 --- a/rair-front/src/images/index.tsx +++ b/rair-front/src/images/index.tsx @@ -19,13 +19,13 @@ import HotdropsFaviconDefault from './Hotdrops-favicon.ico'; import logoHotDropsLight from './HotdropsLogoLight.png'; import kigGif from './kid.gif'; import lennyGif from './lenny.gif'; +import loadingFavicon from './loading-favicon.svg'; import logoHotDrops from './logo-hotdrops.png'; import metamaskLogo from './metamask_logo.webp'; import minTable from './mintable-logo.webp'; import hotdropsLogoMobile from './mobile-logo-hotdrops.png'; import oneOf from './oneOf-logo.webp'; import openSea from './openSea-logo.webp'; -import loadingFavicon from "./loading-favicon.svg"; // import Icons import polygonMatic from './polygon-matic.svg'; import RairFaviconDefault from './rair_favicon.ico'; @@ -35,8 +35,12 @@ import rairTechLogoBlue from './rairLogo_blue.webp'; import rairTechLogoBlack from './rairTechLogoBlack.webp'; import rairTechLogoWhite from './rairTechLogoWhite.webp'; import rarible from './rarible-logo.webp'; +import soniumLogo from './sonium_logo.svg'; import verifiedIcon from './verify-icon.png'; import yotiLogo from './yoti-logo.png'; +import coreIdLogo from './coreNewIcon.png'; + +import { useAppSelector } from '../hooks/useReduxHooks'; // images export const bgLogoBlack = blackBg; @@ -77,7 +81,9 @@ export const EthereumLogo = ethereum; export const DocumentIcon = documentIcon; export const AstarLogo = astar; export const BaseLogo = baseMainnet; +export const SoniumLogo = soniumLogo; export const LoadingDefaultFavicon = loadingFavicon; +export const CoreIdLogo = coreIdLogo; export const DiscordIcon = ({ color, primaryColor }) => { return ( @@ -90,7 +96,7 @@ export const DiscordIcon = ({ color, primaryColor }) => { @@ -98,7 +104,7 @@ export const DiscordIcon = ({ color, primaryColor }) => { @@ -116,7 +122,7 @@ export const TelegramIcon = ({ color, primaryColor }) => { xmlns="http://www.w3.org/2000/svg"> ); @@ -132,7 +138,7 @@ export const TwitterIcon = ({ color, primaryColor }) => { xmlns="http://www.w3.org/2000/svg"> ); @@ -146,14 +152,15 @@ export const InstagramIcon = ({ color, primaryColor }) => { height="20" viewBox="0 0 24 24"> ); }; -export const SunIcon = ({ primaryColor }) => { +export const SunIcon = () => { + const { isDarkMode } = useAppSelector((store) => store.colors); return ( { xmlns="http://www.w3.org/2000/svg"> { @@ -314,6 +321,7 @@ export const MenuIcon = ({ primaryColor }) => { }; export const CloseIconMobile = ({ primaryColor }) => { + console.info(primaryColor, 'primaryColor') return ( { fillRule="evenodd" clipRule="evenodd" d="M16 8C16 6.34315 14.6569 5 13 5H4C2.34315 5 1 6.34315 1 8V16C1 17.6569 2.34315 19 4 19H13C14.6569 19 16 17.6569 16 16V13.9432L21.4188 17.8137C21.7236 18.0315 22.1245 18.0606 22.4576 17.8892C22.7907 17.7178 23 17.3746 23 17V7C23 6.62541 22.7907 6.28224 22.4576 6.11083C22.1245 5.93943 21.7236 5.96854 21.4188 6.18627L16 10.0568V8ZM16.7205 12L21 8.94319V15.0568L16.7205 12ZM13 7C13.5523 7 14 7.44772 14 8V12V16C14 16.5523 13.5523 17 13 17H4C3.44772 17 3 16.5523 3 16V8C3 7.44772 3.44772 7 4 7H13Z" - fill={primaryColor === 'rhyno' ? '#222021' : 'white'} + fill={primaryColor === '#dedede' ? '#222021' : 'white'} /> ); @@ -451,7 +459,7 @@ export const BillTransferIcon = ({ primaryColor }) => { return ( diff --git a/rair-front/src/images/sonium_logo.svg b/rair-front/src/images/sonium_logo.svg new file mode 100644 index 000000000..b58bd202a --- /dev/null +++ b/rair-front/src/images/sonium_logo.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/rair-front/src/main.tsx b/rair-front/src/main.tsx index bacf80c0d..face02237 100644 --- a/rair-front/src/main.tsx +++ b/rair-front/src/main.tsx @@ -1,11 +1,11 @@ import React, { useEffect } from 'react'; -import ReactDOM from 'react-dom/client'; +import { createRoot } from 'react-dom/client'; import { HelmetProvider } from 'react-helmet-async'; import { Provider } from 'react-redux'; -import store from './ducks'; - import { GlobalModalStateProvider } from './providers/ModalProvider/ModalProvider'; +import { store } from './redux/store'; + const sentryIoTraceRate = Number(import.meta.env.VITE_SENTRY_IO_TRACE_RATE); import { BrowserRouter, @@ -42,7 +42,7 @@ if (import.meta.env.VITE_SENTRY_ENABLED) { }); } -const root = ReactDOM.createRoot(document.getElementById('root')!); +const root = createRoot(document.getElementById('root')!); root.render( diff --git a/rair-front/src/redux/colorSlice.ts b/rair-front/src/redux/colorSlice.ts new file mode 100644 index 000000000..670e27960 --- /dev/null +++ b/rair-front/src/redux/colorSlice.ts @@ -0,0 +1,230 @@ +import { headerLogoBlack, headerLogoWhite } from '../images'; +import { bgLogoBlack, bgLogoWhite } from '../images'; +import { + headerLogoBlackMobile, + headerLogoWhiteMobile, + HotDropsLogo, + HotDropsLogoLight, + HotDropsLogoMobile +} from '../images'; + +export const charcoal = '#222021'; +export const rhyno = '#dedede'; +export const bubblegum = '#e882d5'; +export const royalPurple = '#725bdb'; +export const arcticBlue = '#19a7f6'; +export const hotdropsOrange = '#f95631'; + +type CustomButtonColorData = Pick< + ServerSettings, + 'buttonPrimaryColor' | 'buttonFadeColor' | 'buttonSecondaryColor' +>; +interface ButtonInfo { + primaryButtonColor: string; + secondaryButtonColor: string; +} + +type DarkModeLogoInfo = Pick< + ServerSettings, + 'darkModeBannerLogo' | 'darkModeMobileLogo' +>; + +type LightModeLogoInfo = Pick< + ServerSettings, + 'lightModeBannerLogo' | 'lightModeMobileLogo' +>; + +type CustomColorData = Pick< + ServerSettings, + 'darkModePrimary' | 'darkModeSecondary' | 'darkModeText' | 'iconColor' +>; + +interface ColorInfo { + primaryColor?: string; + secondaryColor?: string; + textColor?: string; + iconColor?: string; + headerLogo: string; + headerLogoMobile: string; + backgroundImage: string; + backgroundImageEffect: { backgroundBlendMode?: string }; +} + +interface ColorLibrary { + [key: string]: ColorInfo; +} + +export interface ColorState extends ColorInfo, ButtonInfo { + isDarkMode: boolean; +} + +const hotdropsVar = import.meta.env.VITE_TESTNET; + +const logos = { + light: { + headerLogo: hotdropsVar === 'true' ? HotDropsLogoLight : headerLogoBlack, + headerLogoMobile: + hotdropsVar === 'true' ? HotDropsLogoMobile : headerLogoBlackMobile + }, + dark: { + headerLogo: hotdropsVar === 'true' ? HotDropsLogo : headerLogoWhite, + headerLogoMobile: + hotdropsVar === 'true' ? HotDropsLogoMobile : headerLogoWhiteMobile + } +}; + +import type { PayloadAction } from '@reduxjs/toolkit'; +import { createSlice } from '@reduxjs/toolkit'; + +import { ServerSettings } from '../types/databaseTypes'; + +const buttons: ButtonInfo = { + primaryButtonColor: `linear-gradient(to right, ${royalPurple}, ${bubblegum})`, + secondaryButtonColor: `linear-gradient(to right, ${bubblegum}, ${royalPurple})` +}; + +const colorThemes: ColorLibrary = { + light: { + primaryColor: rhyno, + secondaryColor: charcoal, + headerLogo: headerLogoBlack, + headerLogoMobile: headerLogoBlackMobile, + textColor: 'black', + backgroundImage: bgLogoWhite, + backgroundImageEffect: { backgroundBlendMode: undefined }, + iconColor: bubblegum + }, + dark: { + primaryColor: charcoal, + secondaryColor: rhyno, + headerLogo: headerLogoWhite, + headerLogoMobile: headerLogoWhiteMobile, + textColor: 'white', + backgroundImage: bgLogoBlack, + backgroundImageEffect: { backgroundBlendMode: 'lighten' }, + iconColor: bubblegum + }, + hotdrops: { + primaryColor: '', + secondaryColor: '', + headerLogo: '', + headerLogoMobile: '', + textColor: '', + backgroundImage: '', + backgroundImageEffect: {}, + iconColor: hotdropsOrange + } +}; + +if (!Object.keys(colorThemes).includes(localStorage.colorScheme)) { + localStorage.setItem('colorScheme', 'dark'); +} + +const initialState: ColorState = { + isDarkMode: localStorage.colorScheme === 'dark', + ...colorThemes[localStorage.colorScheme || 'dark'], + ...buttons +}; + +export const colorSlice = createSlice({ + name: 'settings', + initialState, + reducers: { + setCustomColors: ( + state, + action: PayloadAction + ) => { + const { + darkModePrimary, + darkModeSecondary, + darkModeText, + buttonFadeColor, + buttonPrimaryColor, + buttonSecondaryColor, + iconColor + } = action.payload; + if (darkModePrimary) { + colorThemes.dark.primaryColor = darkModePrimary; + } + if (darkModeSecondary) { + colorThemes.dark.secondaryColor = darkModeSecondary; + } + if (darkModeText) { + colorThemes.dark.textColor = darkModeText; + } + if (iconColor) { + colorThemes.dark.iconColor = iconColor; + } + if (buttonPrimaryColor) { + buttons.primaryButtonColor = buttonPrimaryColor; + if (buttonFadeColor) { + buttons.primaryButtonColor = `linear-gradient(to right, ${buttonFadeColor}, ${buttonPrimaryColor})`; + } + } + if (buttonSecondaryColor) { + buttons.secondaryButtonColor = buttonSecondaryColor; + if (buttonFadeColor) { + buttons.secondaryButtonColor = `linear-gradient(to right, ${buttonSecondaryColor}, ${buttonFadeColor})`; + } + } + return { + ...state, + ...colorThemes[localStorage.colorScheme], + ...logos[localStorage.colorScheme], + ...buttons + }; + }, + setColorScheme: (state, action: PayloadAction) => { + localStorage.setItem('colorScheme', action.payload); + return { + ...state, + isDarkMode: action.payload === 'dark', + ...colorThemes[localStorage.colorScheme], + ...logos[action.payload], + ...buttons + }; + }, + setLightModeCustomLogos: ( + state, + action: PayloadAction> + ) => { + if (action.payload.lightModeBannerLogo) { + logos.light.headerLogo = action.payload.lightModeBannerLogo; + } + if (action.payload.lightModeMobileLogo) { + logos.light.headerLogoMobile = action.payload.lightModeMobileLogo; + } + return { + ...state, + ...colorThemes[localStorage.colorScheme], + ...logos[localStorage.colorScheme], + ...buttons + }; + }, + setDarkModeCustomLogos: ( + state, + action: PayloadAction> + ) => { + if (action.payload.darkModeBannerLogo) { + logos.dark.headerLogo = action.payload.darkModeBannerLogo; + } + if (action.payload.darkModeMobileLogo) { + logos.dark.headerLogoMobile = action.payload.darkModeMobileLogo; + } + return { + ...state, + ...colorThemes[localStorage.colorScheme], + ...logos[localStorage.colorScheme], + ...buttons + }; + } + } +}); + +export const { + setCustomColors, + setColorScheme, + setLightModeCustomLogos, + setDarkModeCustomLogos +} = colorSlice.actions; +export default colorSlice.reducer; diff --git a/rair-front/src/redux/commonTypes.ts b/rair-front/src/redux/commonTypes.ts new file mode 100644 index 000000000..1433d16f1 --- /dev/null +++ b/rair-front/src/redux/commonTypes.ts @@ -0,0 +1,6 @@ +export enum dataStatuses { + Uninitialized = 0, + Loading = 1, + Complete = 2, + Failed = 3 +} diff --git a/rair-front/src/redux/searchbarSlice.ts b/rair-front/src/redux/searchbarSlice.ts new file mode 100644 index 000000000..8f2160695 --- /dev/null +++ b/rair-front/src/redux/searchbarSlice.ts @@ -0,0 +1,72 @@ +import type { PayloadAction } from '@reduxjs/toolkit'; +import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; +import axios from 'axios'; + +import { dataStatuses } from './commonTypes'; + +import { ApiCallResponse } from '../types/commonTypes'; +import { MintedToken, Product, User } from '../types/databaseTypes'; + +interface SearchResults { + users?: Array; + products?: Array; + tokens?: Array; +} + +interface SearchbarResponse extends ApiCallResponse { + data: SearchResults; +} + +interface SearchBarParam { + searchTerm: string; +} + +export const startSearch = createAsyncThunk( + 'searchbar/startSearch', + async ({ searchTerm }: SearchBarParam) => { + const encodedSearchTerm = encodeURIComponent(searchTerm); + const response = await axios.get( + `/api/search/${encodedSearchTerm}` + ); + return response.data; + } +); + +interface SearchbarState { + searchStatus: dataStatuses; + searchResults: SearchResults; +} + +const initialState: SearchbarState = { + searchStatus: dataStatuses.Uninitialized, + searchResults: {} +}; + +export const searchbarSlice = createSlice({ + name: 'searchbar', + initialState, + reducers: { + clearResults: (state) => { + state.searchResults = {}; + } + }, + extraReducers: (builder) => { + builder + .addCase(startSearch.pending, (state) => { + state.searchStatus = dataStatuses.Loading; + }) + .addCase( + startSearch.fulfilled, + (state, action: PayloadAction) => { + state.searchStatus = dataStatuses.Complete; + state.searchResults = action.payload.data; + } + ) + .addCase(startSearch.rejected, (state) => { + state.searchStatus = dataStatuses.Failed; + }); + } +}); + +export const { clearResults } = searchbarSlice.actions; +export default searchbarSlice.reducer; diff --git a/rair-front/src/redux/seoSlice.ts b/rair-front/src/redux/seoSlice.ts new file mode 100644 index 000000000..8ec449df2 --- /dev/null +++ b/rair-front/src/redux/seoSlice.ts @@ -0,0 +1,75 @@ +import { LoadingDefaultFavicon } from '../images'; + +// const hotdropsVar = import.meta.env.VITE_TESTNET; + +import type { PayloadAction } from '@reduxjs/toolkit'; +import { createSlice } from '@reduxjs/toolkit'; + +interface SeoInformation { + title: string; + ogTitle: string; + twitterTitle: string; + contentName: string; + content: string; + description: string; + ogDescription: string; + twitterDescription: string; + image: string; + favicon: string; + faviconMobile: string; +} + +const initialStates: { [key: string]: SeoInformation } = { + hotdrops: { + title: 'HotDrops Technologies', + ogTitle: 'HotDrops Technologies', + twitterTitle: 'HotDrops Technologies', + contentName: 'author', + content: 'Digital Ownership Encryption', + description: + 'HotDrops is a Blockchain-based digital rights management platform that uses NFTs to gate access to streaming content', + ogDescription: 'Encrypted, Streaming NFTs', + twitterDescription: 'Encrypted, Streaming NFTs', + image: 'https://hotdrops.live/static/media/hotdrops-default.e7c4e7eb.png', + favicon: LoadingDefaultFavicon, + faviconMobile: LoadingDefaultFavicon + }, + rair: { + title: import.meta.env.VITE_HTML_META_TITLE, + ogTitle: import.meta.env.VITE_HTML_META_TITLE, + twitterTitle: import.meta.env.VITE_HTML_META_TITLE, + contentName: 'author', + content: import.meta.env.VITE_HTML_META_AUTHOR, + description: + import.meta.env.VITE_HTML_META_DESCRIPTION, + ogDescription: import.meta.env.VITE_HTML_META_DESCRIPTION, + twitterDescription: import.meta.env.VITE_HTML_META_DESCRIPTION, + image: `${ + import.meta.env.VITE_IPFS_GATEWAY + }/QmNtfjBAPYEFxXiHmY5kcPh9huzkwquHBcn9ZJHGe7hfaW`, + favicon: LoadingDefaultFavicon, + faviconMobile: LoadingDefaultFavicon + } +}; + +const initialState: SeoInformation = { + ...initialStates['rair'] +}; + +export const seoSlice = createSlice({ + name: 'seo', + initialState, + reducers: { + setSEOInfo: (state, action: PayloadAction) => { + return action.payload || initialStates['rair']; + }, + resetSEOInfo: (state) => { + Object.keys(state).forEach((key) => { + state[key] = ''; + }); + } + } +}); + +export const { setSEOInfo, resetSEOInfo } = seoSlice.actions; +export default seoSlice.reducer; diff --git a/rair-front/src/redux/settingsSlice.ts b/rair-front/src/redux/settingsSlice.ts new file mode 100644 index 000000000..4dff05673 --- /dev/null +++ b/rair-front/src/redux/settingsSlice.ts @@ -0,0 +1,135 @@ +import type { PayloadAction } from '@reduxjs/toolkit'; +import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; +import axios from 'axios'; + +import { + setCustomColors, + setDarkModeCustomLogos, + setLightModeCustomLogos +} from './colorSlice'; +import { dataStatuses } from './commonTypes'; + +import { Blockchain, Category, ServerSettings } from '../types/databaseTypes'; + +interface CategoriesResponse { + success: boolean; + result: Array; +} +export interface SettingsState extends ServerSettings { + dataStatus: dataStatuses; + blockchainSettings: Array; + categoriesStatus: dataStatuses; + categories: Array; +} + +interface SettingsResponse { + success: boolean; + blockchainSettings: Array; + settings: ServerSettings; +} + +const initialState: SettingsState = { + dataStatus: dataStatuses.Uninitialized, + onlyMintedTokensResult: false, + demoUploadsEnabled: false, + featuredCollection: undefined, + nodeAddress: import.meta.env.VITE_NODE_ADDRESS, + superAdmins: undefined, + superAdminsOnVault: undefined, + databaseResales: undefined, + darkModePrimary: undefined, + darkModeSecondary: undefined, + darkModeText: undefined, + darkModeBannerLogo: undefined, + darkModeMobileLogo: undefined, + lightModeBannerLogo: undefined, + lightModeMobileLogo: undefined, + buttonPrimaryColor: undefined, + buttonFadeColor: undefined, + buttonSecondaryColor: undefined, + iconColor: undefined, + footerLinks: undefined, + legal: undefined, + favicon: undefined, + signupMessage: undefined, + customValues: undefined, + blockchainSettings: [], + categoriesStatus: dataStatuses.Uninitialized, + categories: [] +}; + +export const loadSettings = createAsyncThunk( + 'settings/loadSettings', + async (_, { dispatch }) => { + const response = await axios.get('/api/settings'); + dispatch( + setCustomColors({ + ...response.data.settings + }) + ); + dispatch( + setDarkModeCustomLogos({ + ...response.data.settings + }) + ); + dispatch( + setLightModeCustomLogos({ + ...response.data.settings + }) + ); + return response.data; + } +); + +export const loadCategories = createAsyncThunk( + 'settings/loadCategories', + async () => { + const response = await axios.get('/api/categories'); + return response.data; + } +); + +export const settingsSlice = createSlice({ + name: 'settings', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(loadSettings.pending, (state) => { + state.dataStatus = dataStatuses.Loading; + }) + .addCase( + loadSettings.fulfilled, + (state, action: PayloadAction) => { + return { + ...state, + ...action.payload.settings, + dataStatus: dataStatuses.Complete, + blockchainSettings: action.payload.blockchainSettings + }; + } + ) + .addCase(loadSettings.rejected, (state) => { + state.dataStatus = dataStatuses.Failed; + }) + .addCase(loadCategories.pending, (state) => { + state.categoriesStatus = dataStatuses.Loading; + }) + .addCase( + loadCategories.fulfilled, + (state, action: PayloadAction) => { + return { + ...state, + categories: action.payload.result, + categoriesStatus: dataStatuses.Complete + }; + } + ) + .addCase(loadCategories.rejected, (state) => { + state.categoriesStatus = dataStatuses.Failed; + }); + } +}); + +//export const { updateSetting } = settingsSlice.actions; +export default settingsSlice.reducer; diff --git a/rair-front/src/redux/store.ts b/rair-front/src/redux/store.ts new file mode 100644 index 000000000..b42ca091b --- /dev/null +++ b/rair-front/src/redux/store.ts @@ -0,0 +1,37 @@ +import type { Action, ThunkAction } from '@reduxjs/toolkit'; +import { configureStore } from '@reduxjs/toolkit'; + +import colorSlice from './colorSlice'; +import searchbarSlice from './searchbarSlice'; +import seoSlice from './seoSlice'; +import settingsSlice from './settingsSlice'; +import tokenSlice from './tokenSlice'; +import userSlice from './userSlice'; +import videoSlice from './videoSlice'; +import web3Slice from './web3Slice'; + +export const store = configureStore({ + reducer: { + settings: settingsSlice, + colors: colorSlice, + tokens: tokenSlice, + web3: web3Slice, + seo: seoSlice, + user: userSlice, + videos: videoSlice, + searchbar: searchbarSlice + } +}); + +// Infer the type of `store` +export type AppStore = typeof store; +export type RootState = ReturnType; +// Infer the `AppDispatch` type from the store itself +export type AppDispatch = AppStore['dispatch']; +// Define a reusable type describing thunk functions +export type AppThunk = ThunkAction< + ThunkReturnType, + RootState, + unknown, + Action +>; diff --git a/rair-front/src/redux/tokenSlice.ts b/rair-front/src/redux/tokenSlice.ts new file mode 100644 index 000000000..eba57a752 --- /dev/null +++ b/rair-front/src/redux/tokenSlice.ts @@ -0,0 +1,425 @@ +import type { PayloadAction } from '@reduxjs/toolkit'; +import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; +import axios from 'axios'; +import { Hex } from 'viem'; + +import { dataStatuses } from './commonTypes'; + +import { + SingleContractResponse, + SingleTokenResponse +} from '../types/apiResponseTypes'; +import { ApiCallResponse, PaginatedApiCall } from '../types/commonTypes'; +import { + Contract, + MintedToken, + Offer, + Product, + ResaleData, + TokenMetadata, + User +} from '../types/databaseTypes'; + +interface FactoryResponseProduct extends ApiCallResponse { + result: number; + data?: { + doc?: Array; + }; +} + +interface MetadataForCollection { + contract?: Contract; + product?: Product; +} + +interface ProductAndOffers extends Product { + offers: Array; +} + +export interface CatalogItem extends Contract { + product: ProductAndOffers; + frontToken: { + metadata: Pick< + TokenMetadata, + 'image' | 'image_thumbnail' | 'animation_url' + >; + }; + userData?: User; +} + +interface GetCatalogResponse { + contracts: Array; + success: boolean; + totalNumber: number; + pageNumber: number; + itemsPerPage: number; +} + +interface GetCollectionResponse extends ApiCallResponse { + tokens: Array; + totalCount: number; +} + +interface GetResaleResponse extends ApiCallResponse { + data: Array; +} + +interface CatalogQuery extends PaginatedApiCall { + blockchains?: Array; + categories?: Array; + contractTitle?: string; +} + +interface CollectionQuery { + blockchain: Hex; + contract: Hex; + product: string; + fromToken: string; + toToken: string; + attributes?: { [name: string]: string }; +} + +export interface CollectionTokens + extends Omit { + ownerData?: User; + offer: Offer; + resaleData?: ResaleData; + contract: string; +} + +export interface TokensState { + catalogStatus: dataStatuses; + catalogTotal: number; + catalog: Array; + currentCollectionStatus: dataStatuses; + currentCollectionTotal: number; + currentCollection: { [index: string]: CollectionTokens }; + currentCollectionMetadata: MetadataForCollection; + currentCollectionMetadataStatus: dataStatuses; + itemsPerPage: number; + currentPage: number; + currentCollectionParams?: CollectionQuery; +} + +const initialState: TokensState = { + // Front page catalog data + catalogStatus: dataStatuses.Uninitialized, + catalogTotal: 0, + catalog: [], + // Collection tokens data + currentCollectionStatus: dataStatuses.Uninitialized, + currentCollectionTotal: 0, + currentCollection: {}, + currentCollectionParams: undefined, + // Collection contract data + currentCollectionMetadataStatus: dataStatuses.Uninitialized, + currentCollectionMetadata: {}, + // Catalog search params + itemsPerPage: 20, + currentPage: 1 +}; + +export const loadFrontPageCatalog = createAsyncThunk( + 'tokens/loadCatalog', + async ( + { + itemsPerPage, + pageNum, + blockchains, + categories, + contractTitle + }: CatalogQuery, + { getState } + ) => { + const { tokens } = getState() as { tokens: TokensState }; + const queryParams = new URLSearchParams({ + itemsPerPage: (itemsPerPage || tokens.itemsPerPage).toString(), + pageNum: (pageNum || tokens.currentPage).toString() + }); + if (blockchains) { + blockchains.forEach((chain) => { + queryParams.append('blockchain[]', chain); + }); + } + if (categories) { + categories.forEach((category) => { + queryParams.append('category[]', category); + }); + } + if (contractTitle) { + queryParams.append('contractTitle', contractTitle); + } + const response = await axios.get( + `/api/contracts/full?${queryParams.toString()}` + ); + return { + ...response.data, + pageNumber: pageNum || tokens.currentPage, + itemsPerPage: itemsPerPage || tokens.itemsPerPage + }; + } +); + +export const loadCollectionMetadata = createAsyncThunk( + 'tokens/loadCollectionMetadata', + async ({ + contractId, + productId + }: { + contractId?: string; + productId: string; + }) => { + if (!contractId) { + return; + } + const contractData = await axios.get( + `/api/contracts/${contractId}` + ); + const queryParams = new URLSearchParams({ + contract: contractId, + collectionIndexInContract: productId + }); + const productData = await axios.get( + `/api/products?${queryParams.toString()}` + ); + return { + contract: contractData.data.contract, + product: productData.data.data?.doc?.[0] + }; + } +); + +export const reloadTokenData = createAsyncThunk( + 'tokens/reloadTokenData', + async ({ tokenId }: { tokenId?: string }) => { + if (!tokenId) { + return; + } + const response = await axios.get( + `/api/tokens/id/${tokenId}` + ); + return response.data.tokenData; + } +); + +export const loadCollection = createAsyncThunk( + 'tokens/loadCollection', + async ( + { + blockchain, + contract, + product, + fromToken, + toToken, + attributes + }: CollectionQuery, + { dispatch } + ) => { + const queryParams = new URLSearchParams({ + fromToken: fromToken, + toToken: toToken + }); + if (attributes) { + queryParams.append('metadataFilters', JSON.stringify(attributes)); + } + dispatch(clearCollectionData()); + dispatch( + setCollectionSearchParams({ + blockchain, + contract, + product, + fromToken, + toToken, + attributes + }) + ); + const response = await axios.get( + `/api/nft/network/${blockchain}/${contract}/${product}?${queryParams.toString()}` + ); + dispatch( + loadCollectionMetadata({ + contractId: response.data.tokens.at(0)?.contract, + productId: product + }) + ); + dispatch( + loadResaleDataForCollection({ + contract, + blockchain + }) + ); + + return response.data; + } +); + +export const loadResaleDataForCollection = createAsyncThunk( + 'tokens/loadResaleDataForCollection', + async ({ contract, blockchain }: { contract: Hex; blockchain: Hex }) => { + const resaleData = await axios.get( + `/api/resales/open?contract=${contract}&blockchain=${blockchain}` + ); + if (resaleData.data.success) { + return resaleData.data.data; + } + } +); + +export const loadNextCollectionPage = createAsyncThunk( + 'tokens/loadNextCollectionPage', + async (_, { getState, dispatch }) => { + const { tokens } = getState() as { tokens: TokensState }; + if (!tokens.currentCollectionParams) { + return; + } + const { blockchain, contract, product, fromToken, toToken, attributes } = + tokens.currentCollectionParams; + const startingToken = BigInt(toToken) + BigInt(1); + const queryParams = new URLSearchParams({ + fromToken: startingToken.toString(), + toToken: (startingToken + BigInt(20)).toString() + }); + if (attributes) { + queryParams.append('metadataFilters', JSON.stringify(attributes)); + } + const response = await axios.get( + `/api/nft/network/${blockchain}/${contract}/${product}?${queryParams.toString()}` + ); + if (response.data.success) { + dispatch( + setCollectionSearchParams({ + blockchain, + contract, + product, + fromToken, + toToken: (startingToken + BigInt(20)).toString(), + attributes + }) + ); + } + + return response.data; + } +); + +export const tokenSlice = createSlice({ + name: 'tokens', + initialState, + reducers: { + setCollectionSearchParams: (state, action) => { + state.currentCollectionParams = action.payload; + }, + clearCollectionData: (state) => { + state.currentCollectionStatus = dataStatuses.Uninitialized; + state.currentCollectionTotal = 0; + state.currentCollection = {}; + state.currentCollectionMetadataStatus = dataStatuses.Uninitialized; + state.currentCollectionMetadata = {}; + state.currentCollectionParams = undefined; + } + }, + extraReducers: (builder) => { + builder + // Front page catalog + .addCase(loadFrontPageCatalog.pending, (state) => { + state.catalogStatus = dataStatuses.Loading; + }) + .addCase( + loadFrontPageCatalog.fulfilled, + (state, action: PayloadAction) => { + state.catalogStatus = dataStatuses.Complete; + state.catalogTotal = action.payload.totalNumber; + state.catalog = action.payload.contracts; + state.itemsPerPage = action.payload.itemsPerPage; + state.currentPage = action.payload.pageNumber; + } + ) + .addCase(loadFrontPageCatalog.rejected, (state) => { + state.catalogStatus = dataStatuses.Failed; + }) + + // Collection tokens + .addCase(loadCollection.pending, (state) => { + state.currentCollectionStatus = dataStatuses.Loading; + }) + .addCase( + loadCollection.fulfilled, + (state, action: PayloadAction) => { + const tokenMapping: { [index: string]: CollectionTokens } = {}; + action.payload.tokens.forEach((token) => { + tokenMapping[token.uniqueIndexInContract.toString()] = token; + }); + state.currentCollectionStatus = dataStatuses.Complete; + state.currentCollectionTotal = action.payload.totalCount; + state.currentCollection = tokenMapping; + } + ) + .addCase(loadCollection.rejected, (state) => { + state.currentCollectionStatus = dataStatuses.Failed; + }) + + // Reuse collection data for next page + .addCase( + loadNextCollectionPage.fulfilled, + (state, action: PayloadAction) => { + if (action?.payload?.tokens) { + action.payload.tokens.forEach((token) => { + state.currentCollection[token.uniqueIndexInContract.toString()] = + token; + }); + } + } + ) + + // Load metadata for collection + .addCase(loadCollectionMetadata.pending, (state) => { + state.currentCollectionMetadataStatus = dataStatuses.Loading; + }) + .addCase( + loadCollectionMetadata.fulfilled, + (state, action: PayloadAction) => { + state.currentCollectionMetadataStatus = dataStatuses.Complete; + if (action.payload) { + state.currentCollectionMetadata = action.payload; + } else { + state.currentCollectionMetadata = {}; + } + } + ) + .addCase(loadCollectionMetadata.rejected, (state) => { + state.currentCollectionMetadataStatus = dataStatuses.Failed; + }) + + // Reload data for single token + .addCase( + reloadTokenData.fulfilled, + (state, action: PayloadAction) => { + if ( + action.payload && + state.currentCollection[action.payload.uniqueIndexInContract] && + state.currentCollection[action.payload.uniqueIndexInContract] + ._id === action.payload._id + ) { + state.currentCollection[action.payload.uniqueIndexInContract] = + action.payload; + } + } + ) + + // Load resale data for collection + .addCase( + loadResaleDataForCollection.fulfilled, + (state, action: PayloadAction | undefined>) => { + action.payload?.forEach((resale) => { + if (state.currentCollection[resale.tokenIndex]) { + state.currentCollection[resale.tokenIndex].resaleData = resale; + } + }); + } + ); + } +}); + +export const { clearCollectionData, setCollectionSearchParams } = + tokenSlice.actions; +export default tokenSlice.reducer; diff --git a/rair-front/src/redux/userSlice.ts b/rair-front/src/redux/userSlice.ts new file mode 100644 index 000000000..d0843fde9 --- /dev/null +++ b/rair-front/src/redux/userSlice.ts @@ -0,0 +1,82 @@ +import type { PayloadAction } from '@reduxjs/toolkit'; +import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; +import axios from 'axios'; + +import { dataStatuses } from './commonTypes'; + +import { User } from '../types/databaseTypes'; + +interface WithLoginData extends User { + loginType?: string; + adminRights?: boolean; + superAdmin?: boolean; +} + +interface UserDataResponse { + user: WithLoginData; + success: boolean; +} + +interface UserState extends WithLoginData { + loginStatus: dataStatuses; + isLoggedIn: boolean; +} + +const initialState: UserState = { + loginStatus: dataStatuses.Uninitialized, + isLoggedIn: false, + email: undefined, + avatar: undefined, + firstName: undefined, + lastName: undefined, + publicAddress: undefined, + nickName: undefined, + adminRights: undefined, + superAdmin: undefined, + ageVerified: undefined, + loginType: undefined +}; + +export const loadCurrentUser = createAsyncThunk( + 'user/loadCurrentUser', + async () => { + const response = await axios.get('/api/auth/me'); + return response.data.user; + } +); + +export const userSlice = createSlice({ + name: 'user', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(loadCurrentUser.pending, (state) => { + // eslint-disable-next-line no-console + state.loginStatus = dataStatuses.Loading; + }) + .addCase( + loadCurrentUser.fulfilled, + (state, action: PayloadAction>) => { + state.loginStatus = dataStatuses.Complete; + state.email = action.payload?.email; + state.avatar = action.payload?.avatar; + state.firstName = action.payload?.firstName; + state.lastName = action.payload?.lastName; + state.publicAddress = action.payload?.publicAddress; + state.nickName = action.payload?.nickName; + state.adminRights = action.payload?.adminRights; + state.superAdmin = action.payload?.superAdmin; + state.ageVerified = action.payload?.ageVerified; + state.isLoggedIn = !!action.payload?.publicAddress; + state.loginType = action.payload?.loginType; + } + ) + .addCase(loadCurrentUser.rejected, (state) => { + state.loginStatus = dataStatuses.Failed; + }); + } +}); + +//export const { setSEOInfo, resetSEOInfo } = userSlice.actions; +export default userSlice.reducer; diff --git a/rair-front/src/redux/videoSlice.ts b/rair-front/src/redux/videoSlice.ts new file mode 100644 index 000000000..9731202e2 --- /dev/null +++ b/rair-front/src/redux/videoSlice.ts @@ -0,0 +1,87 @@ +import type { PayloadAction } from '@reduxjs/toolkit'; +import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; +import axios from 'axios'; +import { Hex } from 'viem'; + +import { dataStatuses } from './commonTypes'; + +import { + ApiCallResponse, + CatalogVideoItem, + PaginatedApiCall +} from '../types/commonTypes'; + +interface VideoQueryResponse extends ApiCallResponse { + list: Array; + totalNumber: number; +} + +interface VideoQueryParams extends Partial { + blockchain?: Array; + category?: Array; + userAddress?: Hex; + mediaTitle?: string; +} + +interface VideoState { + videoListStatus: dataStatuses; + videos: Array; + totalVideos: number; +} + +const initialState: VideoState = { + videoListStatus: dataStatuses.Uninitialized, + videos: [], + totalVideos: 0 +}; + +export const loadVideoList = createAsyncThunk( + 'video/loadVideoList', + async (searchParams: VideoQueryParams) => { + const queryParams = new URLSearchParams(); + Object.keys(searchParams).forEach((paramName) => { + const value = searchParams[paramName]; + if (value) { + if (Array.isArray(value)) { + if (!value.length) { + return; + } + value.forEach((internalValue) => { + queryParams.append(`${paramName}[]`, internalValue); + }); + } else { + queryParams.append(paramName, value.toString()); + } + } + }); + const response = await axios.get( + `/api/files/list?${queryParams.toString()}` + ); + return response.data; + } +); + +export const videoSlice = createSlice({ + name: 'video', + initialState, + reducers: {}, + extraReducers: (builder) => { + builder + .addCase(loadVideoList.pending, (state) => { + state.videoListStatus = dataStatuses.Loading; + }) + .addCase( + loadVideoList.fulfilled, + (state, action: PayloadAction) => { + state.videoListStatus = dataStatuses.Complete; + state.totalVideos = action.payload.totalNumber; + state.videos = action.payload.list; + } + ) + .addCase(loadVideoList.rejected, (state) => { + state.videoListStatus = dataStatuses.Failed; + }); + } +}); + +export default videoSlice.reducer; diff --git a/rair-front/src/redux/web3Slice.ts b/rair-front/src/redux/web3Slice.ts new file mode 100644 index 000000000..037a6204e --- /dev/null +++ b/rair-front/src/redux/web3Slice.ts @@ -0,0 +1,176 @@ +import { createModularAccountAlchemyClient } from '@alchemy/aa-alchemy'; +import { SmartContractAccount } from '@alchemy/aa-core'; +import { AccountSigner } from '@alchemy/aa-ethers'; +import { Web3AuthSigner } from '@alchemy/aa-signers/web3auth'; +import { Maybe } from '@metamask/providers/dist/utils'; +import type { PayloadAction } from '@reduxjs/toolkit'; +import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; +import { BrowserProvider } from 'ethers'; +import { Hex } from 'viem'; + +import { dataStatuses } from './commonTypes'; + +import { CombinedBlockchainData } from '../types/commonTypes'; +import { metamaskEventListeners } from '../utils/metamaskUtils'; + +interface ChainData { + connectedChain?: Hex; + currentUserAddress?: Hex; +} +export interface ContractsState extends ChainData { + web3Status: dataStatuses; + connectedChain?: Hex; + currentUserAddress?: Hex; + programmaticProvider?: AccountSigner; + requestedChain?: Hex; + exchangeRates?: any; +} + +const defaultChain: Hex = import.meta.env.VITE_DEFAULT_BLOCKCHAIN; + +const initialState: ContractsState = { + web3Status: dataStatuses.Uninitialized, + connectedChain: defaultChain, + currentUserAddress: undefined, + programmaticProvider: undefined, + requestedChain: undefined, + exchangeRates: undefined +}; + +export const connectChainWeb3Auth = createAsyncThunk( + 'web3/connectChainWeb3Auth', + async (chainData: CombinedBlockchainData) => { + const web3AuthSigner = new Web3AuthSigner({ + clientId: import.meta.env.VITE_WEB3AUTH_CLIENT_ID, + chainConfig: { + chainNamespace: 'eip155', + chainId: chainData.chainId, + rpcTarget: chainData.rpcEndpoint, + displayName: chainData.name, + blockExplorer: chainData.blockExplorerGateway, + ticker: chainData.symbol, + tickerName: chainData.name + }, + web3AuthNetwork: chainData.testnet + ? 'sapphire_devnet' + : 'sapphire_mainnet' + }); + await web3AuthSigner.authenticate({ + init: async () => { + await web3AuthSigner.inner.initModal(); + }, + connect: async () => { + await web3AuthSigner.inner.connect(); + } + }); + + const modularAccount = await createModularAccountAlchemyClient({ + apiKey: chainData.alchemyAppKey, + chain: chainData.viem!, + signer: web3AuthSigner, + gasManagerConfig: chainData.alchemyGasPolicy + ? { + policyId: chainData.alchemyGasPolicy + } + : undefined + }); + return { + connectedChain: chainData.hash, + currentUserAddress: modularAccount.account.address, + userDetails: await web3AuthSigner.getAuthDetails() + }; + } +); + +export const connectChainMetamask = createAsyncThunk( + 'web3/connectChainMetamask', + async () => { + if (!window.ethereum) { + return { + signer: undefined, + currentUserAddress: undefined, + connectedChain: undefined + }; + } + const provider = new BrowserProvider(window.ethereum); + metamaskEventListeners(provider); + const accounts: Maybe = await window.ethereum.request({ + method: 'eth_requestAccounts' + }); + const connectedChain: Maybe = + (await window.ethereum.request({ + method: 'eth_chainId' + })) || undefined; + const currentUserAddress = accounts?.at(0); + return { + currentUserAddress, + connectedChain: connectedChain as Hex + }; + } +); + +export const web3Slice = createSlice({ + name: 'web3', + initialState, + reducers: { + setExchangeRates: (state, action) => { + state.exchangeRates = action.payload; + }, + setRequestedChain: (state, action: PayloadAction) => { + state.requestedChain = action.payload; + }, + setConnectedChain: (state, action: PayloadAction) => { + state.connectedChain = action.payload; + }, + setProgrammaticProvider: (state, action) => { + state.programmaticProvider = action.payload; + }, + setUserAddress: (state, action: PayloadAction) => { + state.currentUserAddress = action.payload.toLowerCase() as Hex; + } + }, + extraReducers: (builder) => { + builder + .addCase(connectChainMetamask.pending, (state) => { + state.web3Status = dataStatuses.Loading; + }) + .addCase(connectChainMetamask.fulfilled, (state, action) => { + state.web3Status = dataStatuses.Complete; + if (action.payload.connectedChain) { + state.connectedChain = action.payload.connectedChain; + } + if (action.payload.currentUserAddress) { + state.currentUserAddress = + action.payload.currentUserAddress.toLowerCase() as Hex; + } + }) + .addCase(connectChainMetamask.rejected, (state) => { + state.web3Status = dataStatuses.Failed; + }) + .addCase(connectChainWeb3Auth.pending, (state) => { + state.web3Status = dataStatuses.Loading; + }) + .addCase(connectChainWeb3Auth.fulfilled, (state, action) => { + state.web3Status = dataStatuses.Complete; + if (action.payload.connectedChain) { + state.connectedChain = action.payload.connectedChain; + } + if (action.payload.currentUserAddress) { + state.currentUserAddress = + action.payload.currentUserAddress.toLowerCase() as Hex; + } + }) + .addCase(connectChainWeb3Auth.rejected, (state) => { + state.web3Status = dataStatuses.Failed; + }); + } +}); + +export const { + setExchangeRates, + setRequestedChain, + setConnectedChain, + setProgrammaticProvider, + setUserAddress +} = web3Slice.actions; +export default web3Slice.reducer; diff --git a/rair-front/src/styled-components/SocialLinkIcons/SocialLinkIcons.tsx b/rair-front/src/styled-components/SocialLinkIcons/SocialLinkIcons.tsx index 64afe63e0..30e918b46 100644 --- a/rair-front/src/styled-components/SocialLinkIcons/SocialLinkIcons.tsx +++ b/rair-front/src/styled-components/SocialLinkIcons/SocialLinkIcons.tsx @@ -1,3 +1,4 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; interface ISocialBox { @@ -15,7 +16,9 @@ interface ISocialBox { hotdrops?: string; } -export const SocialBox = styled.div` +export const SocialBox = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` width: ${(props) => (props.width ? props.width : '32px')}; height: ${(props) => (props.height ? props.height : '32px')}; border-radius: 10.5px; @@ -118,7 +121,9 @@ export const SocialBox = styled.div` } `; -export const SocialBoxSearch = styled.div` +export const SocialBoxSearch = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` width: 40px; height: 40px; border-radius: 10.5px; @@ -165,7 +170,9 @@ export const SocialBoxSearch = styled.div` } `; -export const UserIconMobile = styled.div` +export const UserIconMobile = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` width: 40px; height: 40px; border-radius: 10.5px; @@ -193,7 +200,9 @@ export const UserIconMobile = styled.div` } `; -export const SocialMenuMobile = styled.div` +export const SocialMenuMobile = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` cursor: pointer; background: ${(props) => props.primaryColor === '#dedede' ? '#fff' : '#424242'}; diff --git a/rair-front/src/styled-components/nft/AppContainer.tsx b/rair-front/src/styled-components/nft/AppContainer.tsx index 79d0eb7ee..c849a186c 100644 --- a/rair-front/src/styled-components/nft/AppContainer.tsx +++ b/rair-front/src/styled-components/nft/AppContainer.tsx @@ -1,3 +1,4 @@ +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; import { @@ -5,17 +6,15 @@ import { IMainBlockAppStyled } from './AppContainer.types'; -export const AppContainerFluid = styled.div` +export const AppContainerFluid = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` ${(props) => props.backgroundImageEffect}; background-size: 100vw 100vh; min-height: 100vh; position: relative; - background-color: ${(props) => - props.primaryColor === '#dedede' - ? '#fafafa' - : props.backgroundImage === '' - ? '#000' - : props.primaryColor}; + background-color: ${({ isDarkMode, backgroundImage, primaryColor }) => + !isDarkMode ? '#fafafa' : backgroundImage === '' ? '#000' : primaryColor}; color: ${(props) => props.textColor}; background-image: url(${(props) => props.backgroundImage}); background-position: center top; @@ -31,18 +30,17 @@ export const AppContainerFluid = styled.div` } `; -export const MainBlockApp = styled.div` +export const MainBlockApp = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` margin-top: ${(props) => - props.showAlert && !props.isSplashPage && props.selectedChain - ? '65px' - : '0'}; + props.showAlert && !props.isSplashPage ? '65px' : '0'}; @media screen and (max-width: 1024px) { margin-top: 8vh; } @media screen and (max-width: 845px) { - margin-top: ${(props) => - props.showAlert && props.selectedChain ? '120px' : '100px'}; + margin-top: ${(props) => (props.showAlert ? '120px' : '100px')}; } `; diff --git a/rair-front/src/styled-components/nft/AppContainer.types.tsx b/rair-front/src/styled-components/nft/AppContainer.types.tsx index 2cac63b79..007f1f2ea 100644 --- a/rair-front/src/styled-components/nft/AppContainer.types.tsx +++ b/rair-front/src/styled-components/nft/AppContainer.types.tsx @@ -1,16 +1,14 @@ -import { BackgroundBlendModeType } from '../../ducks/colors/colorStore.types'; - export interface IAppContainerFluidStyled { backgroundImageEffect: { - backgroundBlendMode: BackgroundBlendModeType | undefined; + backgroundBlendMode?: string; }; primaryColor?: string; backgroundImage: string; - textColor: string; + textColor?: string; + isDarkMode: boolean; } export interface IMainBlockAppStyled { showAlert: boolean; - selectedChain: string | null | undefined; isSplashPage: boolean; } diff --git a/rair-front/src/styled-components/nft/Token.styles.ts b/rair-front/src/styled-components/nft/Token.styles.ts index e4e6685fb..80bcff0b0 100644 --- a/rair-front/src/styled-components/nft/Token.styles.ts +++ b/rair-front/src/styled-components/nft/Token.styles.ts @@ -1,7 +1,15 @@ -//@ts-nocheck +import emotionIsPropValid from '@emotion/is-prop-valid'; import styled from 'styled-components'; -export const Col = styled.div` +interface customProps { + width: string; + direction: string; + align: string; +} + +export const Col = styled.div.withConfig({ + shouldForwardProp: (prop) => emotionIsPropValid(prop) +})` width: ${(props) => (props.width ? props.width : '50%')}; display: flex; flex-direction: ${(props) => (props.direction ? props.direction : 'row')}; diff --git a/rair-front/src/temp_unused_components/OldNftDataCommonLink.ts b/rair-front/src/temp_unused_components/OldNftDataCommonLink.ts deleted file mode 100644 index a508d01aa..000000000 --- a/rair-front/src/temp_unused_components/OldNftDataCommonLink.ts +++ /dev/null @@ -1,234 +0,0 @@ -export let nftdatacommonlink; -//----NftDataCommonLink---- -// TODO:for feature - get automatically all blockchains -// const getBlockchains = async () => { -// var res = await (await fetch('/api/blockchains')).json(); -// console.log(res, 'res'); - -// } -// getBlockchains(); - -// import React, { useState, useEffect, useCallback } from "react"; -// import { useParams, useNavigate } from "react-router-dom"; -// import { NftCollectionPage } from "./NftCollectionPage"; -// import NftDataPageTest from "./NftDataPageTest"; - -// const NftDataCommonLink = ({ currentUser, primaryColor, textColor }) => { -// // const [, /*offer*/ setOffer] = useState({}); - -// const [tokenData, setTokenData] = useState([]); -// const [selectedData, setSelectedData] = useState([]); -// const [selectedOfferIndex, setSelectedOfferIndex] = useState(); -// const [selectedToken, setSelectedToken] = useState(); -// const [offerPrice, setOfferPrice] = useState([]); -// const [offerData, setOfferData] = useState([]); -// const [productsFromOffer, setProductsFromOffer] = useState([]); -// const [totalCount, setTotalCount] = useState(); - -// // eslint-disable-next-line no-unused-vars -// const navigate = useNavigate(); -// const params = useParams(); - -// const { contract, product, tokenId, blockchain } = params; - -// const getAllProduct = useCallback(async () => { -// const responseAllProduct = await ( -// await fetch(`/api/nft/network/${blockchain}/${contract}/${product}`, { -// method: "GET", -// }) -// ).json(); - -// setTokenData(responseAllProduct.result.tokens); -// setTotalCount(responseAllProduct.result.totalCount); - -// if (responseAllProduct.result.tokens.length >= Number(tokenId)) { -// setSelectedData(responseAllProduct.result?.tokens[tokenId]?.metadata); -// } - -// setSelectedToken(tokenId); -// }, [product, contract, tokenId, blockchain]); - -// ---- return only offers for particular contract with x-token ---- - -// const getParticularOffer = useCallback(async () => { -// let response = await ( -// await fetch(`/api/contracts/${contract}/products/offers`, { -// // await fetch(`/api/nft/${contract}/${product}/offers`, { -// method: "GET" -// }) -// ).json(); - -// if (response.success) { -// response?.products.map((patOffer) => { -// if (patOffer.collectionIndexInContract === Number(product)) { -// setOffer(patOffer); -// const priceOfData = patOffer?.offers.map((p) => { -// return p.price; -// }); -// setOfferPrice(priceOfData); -// } -// return patOffer; -// }); -// } else if ( -// response?.message === "jwt expired" || -// response?.message === "jwt malformed" -// ) { -// localStorage.removeItem("token"); -// } else { -// console.log(response?.message); -// } -// }, [product, contract]); - -// ---- return only offers for particular contract with x-token END ---- - -// // ---- return only offers for particular contract with x-token ---- - -// // const getParticularOffer = useCallback(async () => { -// // let response = await ( -// // await fetch(`/api/contracts/${contract}/products/offers`, { -// // // await fetch(`/api/nft/${contract}/${product}/offers`, { -// // method: "GET", -// // }) -// // ).json(); - -// // if (response.success) { -// // response?.products.map((patOffer) => { -// // if (patOffer.collectionIndexInContract === Number(product)) { -// // setOffer(patOffer); -// // const priceOfData = patOffer?.offers.map((p) => { -// // return p.price; -// // }); -// // setOfferPrice(priceOfData); -// // } -// // return patOffer; -// // }); -// // } else if ( -// // response?.message === "jwt expired" || -// // response?.message === "jwt malformed" -// // ) { -// // localStorage.removeItem("token"); -// // } else { -// // console.log(response?.message); -// // } -// // }, [product, contract]); - -// // ---- return only offers for particular contract with x-token END ---- - -// const getParticularOffer = useCallback(async () => { -// let response = await ( -// await fetch( -// `/api/nft/network/${blockchain}/${contract}/${product}/offers`, -// { -// method: "GET", -// } -// ) -// ).json(); - -// if (response.success) { -// setOfferData( -// response.product.offers.find( -// (neededOfferIndex) => -// neededOfferIndex.offerIndex === selectedOfferIndex -// ) -// ); - -// setOfferPrice( -// response?.product.offers.map((p) => { -// return p.price; -// }) -// ); -// } else if ( -// response?.message === "jwt expired" || -// response?.message === "jwt malformed" -// ) { -// localStorage.removeItem("token"); -// } else { -// console.log(response?.message); -// } -// }, [product, contract, selectedOfferIndex, blockchain]); - -// const getProductsFromOffer = useCallback(async () => { -// const response = await ( -// await fetch( -// `/api/nft/network/${blockchain}/${contract}/${product}/files/${tokenId}`, -// { -// method: "GET", -// } -// ) -// ).json(); - -// setProductsFromOffer(response.files); -// setSelectedOfferIndex(tokenData[tokenId]?.offer); -// }, [blockchain, contract, product, tokenId, tokenData]); - -// function onSelect(id) { -// tokenData.forEach((p) => { -// if (p._id === id) { -// setSelectedData(p.metadata); -// } -// }); -// } - -// const handleClickToken = async (tokenId) => { -// navigate(`/tokens/${blockchain}/${contract}/${product}/${tokenId}`); - -// if (tokenData.length >= Number(tokenId)) { -// setSelectedData(tokenData[tokenId].metadata); -// } - -// setSelectedToken(tokenId); -// }; - -// useEffect(() => { -// getAllProduct(); -// getParticularOffer(); -// getProductsFromOffer(); - -// // eslint-disable-next-line react-hooks/exhaustive-deps -// }, [getAllProduct, getParticularOffer]); - -// if (params.tokens === "collection") { -// return ( -// -// ); -// } -// return ( -// -// ); -// }; - -// export default NftDataCommonLink; diff --git a/rair-front/src/temp_unused_components/OldNftDataPageMain.tsx b/rair-front/src/temp_unused_components/OldNftDataPageMain.tsx deleted file mode 100644 index 828d20948..000000000 --- a/rair-front/src/temp_unused_components/OldNftDataPageMain.tsx +++ /dev/null @@ -1,772 +0,0 @@ -//unused-component - new NftDataPageMain differs but for future I will keep this old version in project -import { useEffect, useState } from 'react'; -import { - Accordion, - AccordionItem, - AccordionItemButton, - AccordionItemHeading, - AccordionItemPanel -} from 'react-accessible-accordion'; -import ReactPlayer from 'react-player'; -import { useSelector } from 'react-redux'; -import { useDispatch } from 'react-redux'; -import { faKey } from '@fortawesome/free-solid-svg-icons'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { utils } from 'ethers'; - -import useServerSettings from '../components/adminViews/useServerSettings'; -import { BreadcrumbsView } from '../components/MockUpPage/NftList/Breadcrumbs/Breadcrumbs'; -import AuthenticityBlock from '../components/MockUpPage/NftList/NftData/AuthenticityBlock/AuthenticityBlock'; -import CollectionInfo from '../components/MockUpPage/NftList/NftData/CollectionInfo/CollectionInfo'; -import NftListUnlockablesVideos from '../components/MockUpPage/NftList/NftData/NftListUnlockablesVideos'; -import TitleCollection from '../components/MockUpPage/NftList/NftData/TitleCollection/TitleCollection'; -import { gettingPrice } from '../components/MockUpPage/NftList/utils/gettingPrice'; -import ItemRank from '../components/MockUpPage/SelectBox/ItemRank'; -import SelectNumber from '../components/MockUpPage/SelectBox/SelectNumber/SelectNumber'; -import { RootState } from '../ducks'; -import { ColorStoreType } from '../ducks/colors/colorStore.types'; -import { ContractsInitialType } from '../ducks/contracts/contracts.types'; -// import CustomButton from '../components/MockUpPage/utils/button/CustomButton'; -import { setShowSidebarTrue } from '../ducks/metadata/actions'; -import useSwal from '../hooks/useSwal'; -import useWeb3Tx from '../hooks/useWeb3Tx'; -import setDocumentTitle from '../utils/setTitle'; - -const NftDataPageMain = ({ - // setTokenData, - blockchain, - contract, - currentUser, - data, - handleClickToken, - product, - productsFromOffer, - selectedData, - selectedToken, - setSelectedToken, - tokenData, - totalCount, - offerData, - offerDataInfo, - offerPrice, - userData, - someUsersData, - ownerInfo -}) => { - const { minterInstance } = useSelector( - (state) => state.contractStore - ); - const { getBlockchainData } = useServerSettings(); - const { primaryColor, textColor, primaryButtonColor } = useSelector< - RootState, - ColorStoreType - >((store) => store.colorStore); - const [playing, setPlaying] = useState(false); - const [offersIndexesData, setOffersIndexesData] = useState(); - - const { web3TxHandler, correctBlockchain, web3Switch } = useWeb3Tx(); - const reactSwal = useSwal(); - - const handlePlaying = () => { - setPlaying((prev) => !prev); - }; - const dispatch = useDispatch(); - - function randomInteger(min, max) { - const rand = min + Math.random() * (max + 1 - min); - return Math.floor(rand); - } - - function percentToRGB(percent) { - if (percent) { - if (percent < 15) { - return '#95F619'; - } else if (15 <= percent && percent < 35) { - return '#F6ED19'; - } else { - return '#F63419'; - } - } - } - - function toUpper(string) { - if (string) { - return string[0].toUpperCase() + string.slice(1); - } - } - - function checkPrice() { - if (offerPrice.length > 0) { - const { maxPrice, minPrice } = gettingPrice(offerPrice); - - if (maxPrice === minPrice) { - const samePrice = maxPrice; - return `${samePrice} `; - } - return `${minPrice} – ${maxPrice}`; - } - } - - // function showLink() { - // // checks if you are the owner and shows only to the owner - - // // if (currentUser === tokenData[selectedToken]?.ownerAddress) { - // // return ( - // //
- // // {tokenData[selectedToken]?.authenticityLink !== "none" ? ( - // // - // // {tokenData[selectedToken]?.authenticityLink} - // // - // // ) : ( - // // "Not minted yet" - // // )} - // //
- // // ); - // // } else { - // // return Not minted yet; - // // } - - // // shows everyone - // // v1 - // // return ( - // //
- // // {tokenData[selectedToken]?.authenticityLink ? ( - // // - // // {tokenData[selectedToken]?.authenticityLink} - // // - // // ) : ( - // // "Not minted yet" - // // )} - // //
- // // ); - - // // v2 - // // eslint-disable-next-line array-callback-return - // return tokenData.map((el, index) => { - // if (Number(el.token) === Number(selectedToken)) { - // return ( - // - // {el?.authenticityLink} - // - // ); - // } - // // // else { - // // return Not minted yet; - // // // } - // }); - - // // if (tokenData[selectedToken]) { - // // eslint-disable-next-line array-callback-return - // // return tokenData.map((el, index) => { - // // if (Number(el.token) === Number(selectedToken)) { - // // return ( - // // - // // {el?.authenticityLink} - // // - // // ); - // // } - // // }); - // // } else { - // // return Not minted yet; - // // } - // } - - const buyContract = async () => { - reactSwal.fire({ - title: 'Buying token', - html: 'Awaiting transaction completion', - icon: 'info', - showConfirmButton: false - }); - if (!minterInstance) { - return; - } - if ( - await web3TxHandler( - minterInstance, - 'buyToken', - [ - offerData.offerPool, - offerData.offerIndex, - selectedToken, - { - value: offerData.price - } - ], - { - intendedBlockchain: blockchain, - failureMessage: - 'Sorry your transaction failed! When several people try to buy at once - only one transaction can get to the blockchain first. Please try again!' - } - ) - ) { - reactSwal.fire( - 'Success', - 'Now, you are the owner of this token', - 'success' - ); - } - }; - - function checkOwner() { - const price = offerData?.price; - // let price = offerData?.price || minPrice; - if ( - currentUser === tokenData[selectedToken]?.ownerAddress && - tokenData[selectedToken]?.isMinted - ) { - return ( - - ); - } else if (tokenData[selectedToken]?.isMinted) { - return ( - - ); - } - return ( - - ); - } - // function checkDataOfProperty() { - // if ( selectedData === 'object' && selectedData !== null) { - // if(selectedData.length){ - // return selectedData?.attributes.map((item, index) => { - // if (item.trait_type === "External URL") { - // return ( - //
- // {item?.trait_type}: - //
- // - // {item?.value} - // - //
- // ); - // } - // const percent = randomInteger(1, 40); - // return ( - //
- //
- // {item?.trait_type}: - // - // {item?.value} - // - //
- //
- // - // {percent}% - // - //
- //
- // ); - // }) - // } - // } else { - // if (Object.keys(selectedData).length) { - // return selectedData?.attributes.map((item, index) => { - // if (item.trait_type === "External URL") { - // return ( - //
- // {item?.trait_type}: - //
- // - // {item?.value} - // - //
- // ); - // } - // const percent = randomInteger(1, 40); - // return ( - //
- //
- // {item?.trait_type}: - // {item?.value} - //
- //
- // - // {percent}% - // - //
- //
- // ); - // }); - // } - // } - // } - - useEffect(() => { - window.scroll(0, 0); - }, []); - - useEffect(() => { - setDocumentTitle('Single Token'); - dispatch(setShowSidebarTrue()); - }, [dispatch]); - - useEffect(() => { - if (offerDataInfo !== undefined && offerDataInfo.length) { - const first = offerDataInfo.map((r) => { - return { - copies: r.copies, - soldCopies: r.soldCopies, - offerIndex: r.offerIndex, - range: r.range - }; - }); - setOffersIndexesData( - first.map((e, index) => { - return { - pkey: - e.offerIndex === '0' ? ( - - ) : e.offerIndex === '1' ? ( - '🔑' - ) : ( - - ), - value: - e.offerIndex === '0' - ? 'Ultra Rair' - : e.offerIndex === '1' - ? 'Rair' - : 'Common', - id: index, - copies: e.copies, - soldCopies: e.soldCopies, - range: e.range - }; - }) - ); - } - }, [offerDataInfo]); - - return ( -
- -
- -
-
- {selectedData?.animation_url ? ( -
- -
- ) : ( -
- )} -
-
-
-
Price range
-
- Blockchain network - - {offerPrice && `${checkPrice()}`} - - - {data - ? getBlockchainData(data?.contract.blockchain)?.symbol - : getBlockchainData(blockchain)?.symbol} - -
-
-
-
Item rank
-
- -
-
-
-
Serial number
-
- {tokenData.length ? ( - { - return { - value: p.metadata.name, - id: p._id, - token: p.token, - sold: p.isMinted - }; - }) - } - /> - ) : ( - <> - )} -
-
-
- {checkOwner()} -
-
- - - - Description - - - {selectedData?.artist === 'none' && - selectedData?.description === 'none' && - selectedData?.external_url === 'none' ? ( -
- {/*
*/} - Created by - - {someUsersData !== null - ? someUsersData?.nickName - : ownerInfo?.owner} - - {/*
*/} -
- ) : ( -
- {/*
*/} -

- {/* {selectedData?.artist? `${toUpper(selectedData?.artist)}#` :'' } */} - {selectedData?.description} -

- {/*
*/} - {/*
*/} - {/*
*/} - {/* */} -
- )} -
-
- - - - Properties - - -
- {/* {checkDataOfProperty()} */} - {selectedData ? ( - Object.keys(selectedData).length && - // ? selectedData.length && - selectedData?.attributes.length > 0 ? ( - selectedData?.attributes.map((item, index) => { - if ( - item.trait_type === 'External URL' || - item.trait_type === 'external_url' - ) { - return null; - // - } - if ( - item.trait_type === 'image' || - item.trait_type === 'animation_url' - ) { - return ( - - ); - } - const percent = randomInteger(1, 40); - return ( -
-
- - {`${item?.trait_type.toUpperCase()} `} - -
-
- {/* */} - {/* */} - - - {percent}% - - : - {`${toUpper( - item?.value.toString().toLowerCase() - )} `} - - - {/* */} - {/* */} -
-
- ); - }) - ) : ( -
{"You don't have any properties"}
- ) - ) : null} -
-
-
- - - - This NFT unlocks - - - - {/* {productsFromOffer && productsFromOffer.length !== 0 ? ( - - navigate( - `/unlockables/${blockchain}/${contract}/${product}/${selectedToken}` - ) - } - text="More Unlockables" - width="288px" - height="48px" - textColor={textColor} - primaryColor={primaryColor} - margin={'0 auto'} - /> - ) : null} */} - - - - - - Collection info - - - - - - - - - Authenticity - - - {/*
{showLink()}
*/} - -
-
-
-
-
- {/* More by {tokenData[selectedToken]?.ownerAddress ? tokenData[selectedToken]?.ownerAddress : "User" } */} -
-
-
- ); -}; - -export default NftDataPageMain; diff --git a/rair-front/src/types/apiResponseTypes.ts b/rair-front/src/types/apiResponseTypes.ts new file mode 100644 index 000000000..1d3f90120 --- /dev/null +++ b/rair-front/src/types/apiResponseTypes.ts @@ -0,0 +1,19 @@ +import { ApiCallResponse, tokenNumberData } from './commonTypes'; +import { Contract } from './databaseTypes'; + +import { CollectionTokens } from '../redux/tokenSlice'; + +// api/nft/network/:network/:contract/:product/numbers +export interface tokenNumbersResponse extends ApiCallResponse { + tokens: Array; +} + +// api/tokens/id/:id +export interface SingleTokenResponse extends ApiCallResponse { + tokenData: CollectionTokens; +} + +// api/contract/:id +export interface SingleContractResponse extends ApiCallResponse { + contract?: Contract; +} diff --git a/rair-front/src/types/commonTypes.ts b/rair-front/src/types/commonTypes.ts new file mode 100644 index 000000000..6d0ac52a6 --- /dev/null +++ b/rair-front/src/types/commonTypes.ts @@ -0,0 +1,65 @@ +import { + Blockchain, + Contract, + MediaFile, + MintedToken, + Offer, + ResaleData +} from './databaseTypes'; + +import { TChainItemData } from '../utils/utils.types'; + +export interface ApiCallResponse { + success: boolean; + message?: string; +} + +export interface PaginatedApiCall { + itemsPerPage?: number; + pageNum?: number; +} + +export interface CustomModalStyle { + overlay: React.CSSProperties; + content: React.CSSProperties; +} + +export interface SelectOption { + label: string; + value: string; + disabled?: boolean; +} + +export interface SplashPageProps { + setIsSplashPage: React.Dispatch>; +} + +export interface UploadMediaFile { + offer: string; + category: string; + title: string; + file: File; + description: string; + preview: string; + contractAddress: string; + productIndex: string; + storage: string; + demo: boolean; +} + +export interface CatalogVideoItem extends MediaFile { + isUnlocked: boolean; + unlockData: { offers: Array }; +} + +export interface tokenNumberData { + token: string; + sold: boolean; +} + +export interface CombinedBlockchainData extends Blockchain, TChainItemData {} + +export interface NftItemToken extends Omit { + resaleData?: ResaleData; + contract: Contract; +} diff --git a/rair-front/src/types/databaseTypes.ts b/rair-front/src/types/databaseTypes.ts new file mode 100644 index 000000000..e16414b15 --- /dev/null +++ b/rair-front/src/types/databaseTypes.ts @@ -0,0 +1,211 @@ +import { Hex } from 'viem'; + +export interface MongoDocument { + _id?: string; + _v?: number; + createdAt?: Date; + updatedAt?: Date; +} + +export interface MediaFile extends MongoDocument { + uploader: Hex; + hidden: boolean; + ageRestricted?: boolean; + title: string; + description: string; + duration: string; + type: string; + extension: string; + meetingId: string; + encryptionType: string; + // mainManifest: string; + storage?: string; + storagePath?: string; + staticThumbnail: string; + animatedThumbnail?: string; + category?: string; + demo: boolean; + views?: number; + totalEncryptedFiles?: number; +} + +export interface Contract extends MongoDocument { + title: string; + user: string; + blockchain: Hex; + contractAddress: string; + diamond: boolean; + creationDate: string; + transactionHash?: string; + lastSyncedBlock: string; + external: boolean; + singleMetadata: boolean; + metadataURI: string; + importedBy: Hex; + blockView: boolean; + blockSync: boolean; +} + +export interface Blockchain extends MongoDocument { + hash: Hex; + name: string; + display?: boolean; + sync?: boolean; + + diamondFactoryAddress?: string; + classicFactoryAddress?: string; + diamondMarketplaceAddress?: string; + mainTokenAddress?: string; + licenseExchangeAddress?: string; + + rpcEndpoint?: string; + blockExplorerGateway?: string; + alchemySupport: boolean; + + numericalId?: number; + testnet?: boolean; + symbol?: string; +} + +export interface Category extends MongoDocument { + name: string; + files: number; +} + +export interface FavoriteToken extends MongoDocument { + userAddress: Hex; + token: string; +} + +export interface Product extends MongoDocument { + name: string; + collectionIndexInContract: string; + contract: string; + copies: number; + soldCopies: number; + sold: boolean; + royalty: number; + firstTokenIndex: string; + cover: string; + creationDate: string; + transactionHash?: string; + diamond: boolean; + singleMetadata: boolean; + metadataURI: string; + bannerImage?: string; +} + +export interface User extends MongoDocument { + email?: string; + nickName?: string; + avatar?: string; + background?: String; + firstName?: string; + lastName?: string; + ageVerified?: boolean; + publicAddress?: Hex; + creationDate?: string; + blocked?: boolean; +} + +export interface MetadataAttribute { + display_type?: string; + trait_type?: string; + value?: string; + percentage?: string; +} + +export interface TokenMetadata { + image: string; + image_thumbnail?: string; + image_data?: string; + artist?: string; + external_url?: string; + description: string; + name: string; + attributes?: Array; + background_color?: string; + animation_url?: string; + youtube_url?: string; +} + +export interface MintedToken extends MongoDocument { + token: string; + uniqueIndexInContract: string; + ownerAddress: string; + offerPool?: string; + offer: string; + contract: string; + metadata: TokenMetadata; + metadataURI: string; + authenticityLink: string; + isMinted: boolean; + isMetadataPinned: boolean; + isURIStoredToBlockchain: boolean; + creationDate: string; + product: string; +} + +export interface Offer extends MongoDocument { + offerIndex?: string; + contract: string; + product: string; + offerPool?: string; + copies?: number; + allowedCopies?: number; + lockedCopies?: number; + soldCopies?: number; + sold?: boolean; + price: string; + range: Array; + offerName?: string; + creationDate?: string; + diamond: boolean; + diamondRangeIndex?: string; + transactionHash?: string; + hidden?: boolean; + sponsored?: boolean; +} + +export interface CustomValue { + name: string; + value: string; +} +export interface FooterLink { + label: string; + url: string; +} +export interface ServerSettings extends MongoDocument { + onlyMintedTokensResult: boolean; + demoUploadsEnabled: boolean; + featuredCollection?: { _id: string; contract: string }; + nodeAddress: string; + superAdmins?: Array; + superAdminsOnVault?: boolean; + databaseResales?: boolean; + darkModePrimary?: string; + darkModeSecondary?: string; + darkModeText?: string; + darkModeBannerLogo?: string; + darkModeMobileLogo?: string; + lightModeBannerLogo?: string; + lightModeMobileLogo?: string; + buttonPrimaryColor?: string; + buttonFadeColor?: string; + buttonSecondaryColor?: string; + iconColor?: string; + footerLinks?: Array; + legal?: string; + favicon?: string; + signupMessage?: string; + customValues?: Array; +} + +export interface ResaleData extends MongoDocument { + tokenContract: string; + tokenIndex: string; + price: string; + buyer?: Hex; + seller: Hex; + blockchainOfferId?: string; +} diff --git a/rair-front/src/typescript-global-types/index.d.ts b/rair-front/src/typescript-global-types/index.d.ts index 0172d4884..2c67fc3b8 100644 --- a/rair-front/src/typescript-global-types/index.d.ts +++ b/rair-front/src/typescript-global-types/index.d.ts @@ -1,6 +1,5 @@ -import { BaseProvider } from '@metamask/providers'; +import { MetaMaskInpageProvider } from '@metamask/providers'; import { Maybe } from '@metamask/providers/dist/utils'; -import { Hex } from 'viem'; declare module '@metamask/providers/dist/BaseProvider' { interface RequestArguments { @@ -10,17 +9,7 @@ declare module '@metamask/providers/dist/BaseProvider' { declare global { interface Window { - ethereum: BaseProvider; + ethereum: MetaMaskInpageProvider; dataLayer: Array; } - - // BinanceMainnet = '0x38', - // BinanceTestnet = '0x61', - // MaticPolygonTestnet = '0x13881', - // TEthereumMainnet = '0x1', - // TMaticPolygonMainnet = '0x89' - // KlaytnBaobab = '0x3e9' - // 'Ropsten (Ethereum)' = '0x3' - // Sepolia = 0xaa36a7 - type BlockchainType = Hex; } diff --git a/rair-front/src/utils/blockchainData.ts b/rair-front/src/utils/blockchainData.ts index 4b298098d..9967db2a0 100644 --- a/rair-front/src/utils/blockchainData.ts +++ b/rair-front/src/utils/blockchainData.ts @@ -1,9 +1,17 @@ import { base, mainnet, polygon, sepolia } from '@alchemy/aa-core'; import { Network } from 'alchemy-sdk'; +import { Hex } from 'viem'; import { TChainData } from './utils.types'; -import { AstarLogo, BaseLogo, EthereumLogo, MaticLogo } from '../images'; +import { + AstarLogo, + BaseLogo, + EthereumLogo, + CoreIdLogo, + MaticLogo, + SoniumLogo +} from '../images'; const chainData: TChainData = { // '0x38': { @@ -11,17 +19,6 @@ const chainData: TChainData = { // name: 'Binance Mainnet', // chainId: '0x38', // symbol: 'BNB', - // addChainData: { - // chainId: '0x38', - // chainName: 'Binance Smart Chain Mainnet', - // nativeCurrency: { - // name: 'BNB', - // symbol: 'BNB', - // decimals: 18 - // }, - // rpcUrls: ['https://bsc-dataseed1.binance.org'], - // blockExplorerUrls: ['https://www.bscscan.com/'] - // }, // disabled: true, // viem: undefined, // alchemy: undefined, @@ -33,17 +30,6 @@ const chainData: TChainData = { // name: 'Binance Testnet', // chainId: '0x61', // symbol: 'BNB', - // addChainData: { - // chainId: '0x61', - // chainName: 'Binance Testnet', - // nativeCurrency: { - // name: 'BNB', - // symbol: 'BNB', - // decimals: 18 - // }, - // rpcUrls: ['https://data-seed-prebsc-1-s1.binance.org:8545/'], - // blockExplorerUrls: ['https://testnet.bscscan.com/'] - // }, // disabled: true, // viem: undefined, // alchemy: undefined, @@ -54,18 +40,6 @@ const chainData: TChainData = { image: AstarLogo, name: 'Astar Mainnet', chainId: '0x250', - symbol: 'ASTR', - addChainData: { - chainId: '0x250', - chainName: 'Astar Mainnet', - nativeCurrency: { - name: 'ASTR', - symbol: 'ASTR', - decimals: 18 - }, - rpcUrls: ['https://evm.astar.network'], - blockExplorerUrls: ['https://astar.blockscout.com/'] - }, viem: undefined, alchemy: Network.ASTAR_MAINNET, coingecko: 'astar', @@ -76,18 +50,6 @@ const chainData: TChainData = { image: MaticLogo, name: 'Matic(Polygon) Mainnet', chainId: '0x89', - symbol: 'MATIC', - addChainData: { - chainId: '0x89', - chainName: 'Matic(Polygon) Mainnet', - nativeCurrency: { - name: 'Matic Token', - symbol: 'MATIC', - decimals: 18 - }, - rpcUrls: ['https://polygon-rpc.com/'], - blockExplorerUrls: ['https://polygonscan.com/'] - }, viem: polygon, alchemy: Network.MATIC_MAINNET, coingecko: 'matic-network', @@ -100,17 +62,6 @@ const chainData: TChainData = { // name: 'Matic(Polygon) Testnet', // chainId: '0x13881', // symbol: 'tMATIC', - // addChainData: { - // chainId: '0x13881', - // chainName: 'Matic Testnet Mumbai', - // nativeCurrency: { - // name: 'Matic token', - // symbol: 'tMATIC', - // decimals: 18 - // }, - // rpcUrls: ['https://rpc-mumbai.polygon.technology/'], - // blockExplorerUrls: ['https://mumbai.polygonscan.com/'] - // }, // viem: polygonMumbai, // alchemy: Network.MATIC_MUMBAI, // coingecko: undefined @@ -119,13 +70,6 @@ const chainData: TChainData = { image: EthereumLogo, name: 'Ethereum Mainnet', chainId: '0x1', - symbol: 'ETH', - addChainData: { - chainId: '0x1', - chainName: 'Mainnet (Ethereum)', - rpcUrls: ['https://eth.llamarpc.com'], - blockExplorerUrls: ['https://etherscan.io/'] - }, viem: mainnet, alchemy: Network.ETH_MAINNET, coingecko: 'ethereum', @@ -137,13 +81,6 @@ const chainData: TChainData = { image: EthereumLogo, name: 'Ethereum Sepolia', chainId: '0xaa36a7', - symbol: 'Sepolia ETH', - addChainData: { - chainId: '0xaa36a7', - chainName: 'Sepolia (Ethereum)', - blockExplorerUrls: ['https://sepolia.etherscan.io/'], - rpcUrls: ['https://ethereum-sepolia-rpc.publicnode.com'] - }, viem: sepolia, alchemy: Network.ETH_SEPOLIA, coingecko: undefined, @@ -156,12 +93,6 @@ const chainData: TChainData = { // name: 'Ethereum Goerli', // chainId: '0x5', // symbol: 'Goerli ETH', - // addChainData: { - // chainId: '0x5', - // chainName: 'Goerli (Ethereum)', - // rpcUrls: ['https://ethereum-sepolia-rpc.publicnode.com'], - // blockExplorerUrls: ['https://sepolia.etherscan.io/'] - // }, // viem: mainnet, // alchemy: Network.ETH_SEPOLIA, // coingecko: undefined @@ -172,42 +103,59 @@ const chainData: TChainData = { image: BaseLogo, name: 'Base Mainnet', chainId: '0x2105', - symbol: 'bETH', - addChainData: { - chainId: '0x2105', - chainName: 'Base', - rpcUrls: ['https://mainnet.base.org'], - blockExplorerUrls: ['https://basescan.org/'] - }, viem: base, alchemy: Network.BASE_MAINNET, coingecko: 'base', alchemyAppKey: import.meta.env.VITE_BASE_MAINNET_ALCHEMY_KEY, alchemyGasPolicy: import.meta.env.VITE_BASE_MAINNET_GAS_POLICY + }, + '0x79a': { + // Sonium Minato Testnet + testnet: true, + image: SoniumLogo, + name: 'Minato', + chainId: '0x79a', + viem: undefined, + alchemy: undefined, + coingecko: undefined, + alchemyAppKey: undefined, + alchemyGasPolicy: undefined + }, + '0x45c': { + // Core Blockchain Mainnet + testnet: false, + image: CoreIdLogo, + name: 'Core Chain MainNet', + chainId: '0x45c', + viem: undefined, + alchemy: undefined, + coingecko: undefined, + alchemyAppKey: undefined, + alchemyGasPolicy: undefined } -}; +} export default chainData; export const detectBlockchain = ( - currentChain: BlockchainType | undefined, - realChain: BlockchainType | undefined + connectedChain: Hex | undefined, + realChain: Hex | undefined ) => { if ( realChain !== undefined && - currentChain && + connectedChain && chainData && - chainData[currentChain]?.chainId !== realChain + chainData[connectedChain]?.chainId !== realChain ) { return { - selectedChain: chainData[currentChain]?.name, + selectedChain: chainData[connectedChain]?.name, realNameChain: chainData[realChain]?.name, selectedChainId: chainData[realChain]?.chainId }; } else { return { - selectedChain: null, - realNameChain: null + selectedChain: undefined, + realNameChain: undefined }; } }; diff --git a/rair-front/src/utils/determineColorRange.ts b/rair-front/src/utils/determineColorRange.ts index 8cc4e8bd9..1d8de08a8 100644 --- a/rair-front/src/utils/determineColorRange.ts +++ b/rair-front/src/utils/determineColorRange.ts @@ -1,5 +1,3 @@ -import { BigNumber } from 'ethers'; - export function getRGBValue( diamond: boolean, offer: string | undefined, @@ -12,23 +10,23 @@ export function getRGBValue( if ( offerData && offerData[0] && - BigNumber.from(indexId).gte(offerData[0].range[0]) && - BigNumber.from(indexId).lte(offerData[0].range[1]) + BigInt(indexId) >= BigInt(offerData[0].range[0]) && + BigInt(indexId) <= BigInt(offerData[0].range[1]) ) { rgbValue = 'rgba(232,130,213, 1)'; } else if ( offerData && offerData[1] && - BigNumber.from(indexId).gte(offerData[1].range[0]) && - BigNumber.from(indexId).lte(offerData[1].range[1]) + BigInt(indexId) >= BigInt(offerData[1].range[0]) && + BigInt(indexId) <= BigInt(offerData[1].range[1]) ) { rgbValue = 'rgba(114,91,219, 1)'; } else if ( offerData && offerData.length > 1 && offerData[2] && - BigNumber.from(indexId).gte(offerData[2].range[0]) && - BigNumber.from(indexId).lte(offerData[2].range[1]) + BigInt(indexId) >= BigInt(offerData[2].range[0]) && + BigInt(indexId) <= BigInt(offerData[2].range[1]) ) { rgbValue = 'rgba(25,167,246, 1)'; } diff --git a/rair-front/src/utils/infoSplashData/nftnyc.tsx b/rair-front/src/utils/infoSplashData/nftnyc.tsx index afffe1657..7cbc512ee 100644 --- a/rair-front/src/utils/infoSplashData/nftnyc.tsx +++ b/rair-front/src/utils/infoSplashData/nftnyc.tsx @@ -1,16 +1,11 @@ -import { useSelector } from 'react-redux'; - import { NFTNYC_TITLE } from '../../components/SplashPage/images/NFTNYC/nftnyc'; import { TSplashDataType } from '../../components/SplashPage/splashPage.types'; import { hyperlink } from '../../components/SplashPage/SplashPageConfig/utils/hyperLink'; -import { RootState } from '../../ducks'; -import { ContractsInitialType } from '../../ducks/contracts/contracts.types'; +import { useAppSelector } from '../../hooks/useReduxHooks'; import { metaMaskIcon } from '../../images'; export const useNFTNYC = (connectUserData) => { - const { currentUserAddress } = useSelector( - (store) => store.contractStore - ); + const { currentUserAddress } = useAppSelector((store) => store.web3); const splashData: TSplashDataType = { NFTName: 'NFT', title: 'NFTNYC X RAIR', @@ -49,7 +44,7 @@ export const useNFTNYC = (connectUserData) => { titleColor: 'rgb(3, 91, 188)' }, videoData: { - video: null, + video: undefined, videoTitle: '', videoModuleDescription: 'NFT owners can learn more about the project by signing with metamask to unlock an encrypted stream ', diff --git a/rair-front/src/utils/infoSplashData/rairGenesis.tsx b/rair-front/src/utils/infoSplashData/rairGenesis.tsx index 6b0251039..d7e748327 100644 --- a/rair-front/src/utils/infoSplashData/rairGenesis.tsx +++ b/rair-front/src/utils/infoSplashData/rairGenesis.tsx @@ -1,13 +1,11 @@ -import { useSelector } from 'react-redux'; +import { Hex } from 'viem'; import { Genesis_TV } from '../../components/SplashPage/images/rairGenesis/rairGenesis'; -import { RootState } from '../../ducks'; +import { useAppSelector } from '../../hooks/useReduxHooks'; import { metaMaskIcon } from '../../images'; export const useSplashData = (connectUserData) => { - const currentUserAddress = useSelector( - (store) => store.contractStore.currentUserAddress - ); + const { currentUserAddress } = useAppSelector((store) => store.web3); const splashData = { NFTName: 'Genesis Pass artwork', @@ -18,31 +16,34 @@ export const useSplashData = (connectUserData) => { ? { paddingTop: '3vw' } : undefined, videoPlayerParams: { - contract: '0x09926100eeab8ca2d636d0d77d1ccef323631a73', + contract: '0x09926100eeab8ca2d636d0d77d1ccef323631a73' as Hex, product: '0', - blockchain: '0x5' + blockchain: '0x5' as Hex }, marketplaceDemoParams: { - contract: '0x09926100eeab8ca2d636d0d77d1ccef323631a73', + contract: '0x09926100eeab8ca2d636d0d77d1ccef323631a73' as Hex, product: '0', - blockchain: '0x5' + blockchain: '0x5' as Hex }, purchaseButton: { - requiredBlockchain: '0x38', - contractAddress: '0x03041d4fd727eae0337529e11287f6b499d48a4f' + requiredBlockchain: '0x38' as Hex, + contractAddress: '0x03041d4fd727eae0337529e11287f6b499d48a4f' as Hex }, /* this block needs to be changed */ buttonLabel: 'Connect Wallet', buttonBackgroundHelp: 'rgb(3, 91, 188)', backgroundImage: Genesis_TV, - button1: currentUserAddress === undefined && { - buttonLabel: 'Connect wallet', - buttonImg: metaMaskIcon, - buttonAction: connectUserData - }, + button1: + currentUserAddress === undefined + ? { + buttonLabel: 'Connect wallet', + buttonImg: metaMaskIcon, + buttonAction: connectUserData + } + : undefined, button2: { - buttonMarginTop: currentUserAddress === undefined ? 0 : '2vw', - buttonMarginBottom: currentUserAddress === undefined ? 0 : '6vw', + buttonMarginTop: currentUserAddress === undefined ? '0' : '2vw', + buttonMarginBottom: currentUserAddress === undefined ? '0' : '6vw', buttonBorder: '3px solid #77B9F3', buttonTextColor: '#000000', buttonColor: '#FFFFFF', diff --git a/rair-front/src/utils/infoSplashData/slideLock.tsx b/rair-front/src/utils/infoSplashData/slideLock.tsx index 2c36285e2..3481bce67 100644 --- a/rair-front/src/utils/infoSplashData/slideLock.tsx +++ b/rair-front/src/utils/infoSplashData/slideLock.tsx @@ -116,7 +116,7 @@ export const splashData: TSplashDataType = { // }, // ], videoData: { - video: null + video: undefined // videoTitle: "Watch the Transformation", // videoModuleDescription: "NFT owners can learn more about the project by signing with metamask to unlock an encrypted document", // videoModuleTitle: "Only NFT owners can see these slides", diff --git a/rair-front/src/utils/infoSplashData/ukraineSplashPage.tsx b/rair-front/src/utils/infoSplashData/ukraineSplashPage.tsx index 1a775e306..9694d2fe2 100644 --- a/rair-front/src/utils/infoSplashData/ukraineSplashPage.tsx +++ b/rair-front/src/utils/infoSplashData/ukraineSplashPage.tsx @@ -112,7 +112,7 @@ export const splashData: TSplashDataType = { } ], videoData: { - video: null, + video: undefined, videoTitle: 'Watch the Transformation', videoModuleDescription: 'Flag owners sign in with metamask to watch', videoModuleTitle: 'For Supporters Only', diff --git a/rair-front/src/utils/infoSplashData/vapoverseSplashPage.tsx b/rair-front/src/utils/infoSplashData/vapoverseSplashPage.tsx index d67a582d3..56ee6819d 100644 --- a/rair-front/src/utils/infoSplashData/vapoverseSplashPage.tsx +++ b/rair-front/src/utils/infoSplashData/vapoverseSplashPage.tsx @@ -31,7 +31,7 @@ export const splashData: TSplashDataType = { buttonLink: 'https://twitter.com/rairtech' }, videoDataDemo: { - video: null, + video: undefined, // 'https://storage.googleapis.com/rair-videos/tx2cV7kzqFXF9lTC5iy1VCYoXBwonyG-HcjunEI5j1rqfX/2596768157', videoTitle: '', videoModuleDescription: null, @@ -41,7 +41,7 @@ export const splashData: TSplashDataType = { // demo: true }, videoData: { - video: null, + video: undefined, videoTitle: '', videoModuleDescription: null, videoModuleTitle: 'loading...', diff --git a/rair-front/src/utils/metamaskUtils.ts b/rair-front/src/utils/metamaskUtils.ts index 513b205b8..71c93871c 100644 --- a/rair-front/src/utils/metamaskUtils.ts +++ b/rair-front/src/utils/metamaskUtils.ts @@ -1,25 +1,4 @@ -import { BigNumber, ethers } from 'ethers'; - -import { rFetch } from './rFetch'; - -const handleReceipt = async ( - transactionReceipt: ethers.ContractReceipt, - gotoNextStep?: (() => void) | undefined -) => { - //console.log('Handling Receipt', transactionReceipt); - // Use window.ethereum.chainId because switching networks on Metamask cancels all transactions - try { - await rFetch( - `/api/transaction/${window.ethereum.chainId}/${transactionReceipt.transactionHash}`, - { - method: 'POST' - } - ); - gotoNextStep && gotoNextStep(); - } catch (error) { - console.error(error); - } -}; +import { Provider } from 'ethers'; const validateInteger = (number: string | number) => { if ( @@ -30,11 +9,50 @@ const validateInteger = (number: string | number) => { return false; } try { - BigNumber.from(number); + BigInt(number); } catch (err) { return false; } return true; }; -export { handleReceipt, validateInteger }; +const metamaskEventListeners = (provider: Provider) => { + provider.on( + 'debug', + ({ + // action, + request, + response + // provider + }) => { + if (import.meta.env.VITE_LOG_WEB3 === 'true') { + console.info( + response ? 'Receiving response to' : 'Sending request', + request.method + ); + } + } + ); + provider.on('network', (newNetwork, oldNetwork) => { + // When a Provider makes its initial connection, it emits a "network" + // event with a null oldNetwork along with the newNetwork. So, if the + // oldNetwork exists, it represents a changing network + /* + Example of a network object: + { + "name": "goerli", + "chainId": 5, + "ensAddress": "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e" + } + */ + if (oldNetwork) { + console.info( + `Detected a network change, from ${oldNetwork.name} to ${newNetwork.name}` + ); + } else { + console.info(`Connected to ${newNetwork.name}`); + } + }); +}; + +export { metamaskEventListeners, validateInteger }; diff --git a/rair-front/src/utils/rFetch.ts b/rair-front/src/utils/rFetch.ts index d249f94ca..569151130 100644 --- a/rair-front/src/utils/rFetch.ts +++ b/rair-front/src/utils/rFetch.ts @@ -1,164 +1,120 @@ -/* eslint-disable no-case-declarations */ +import { Web3AuthSigner } from '@alchemy/aa-signers/web3auth'; import axios from 'axios'; -import { providers } from 'ethers'; +import { BrowserProvider, Provider } from 'ethers'; import Swal from 'sweetalert2'; +import { Hex } from 'viem'; import { TAuthGetChallengeResponse, TUserResponse } from '../axios.responseTypes'; -const signIn = async (provider: providers.StaticJsonRpcProvider) => { - let currentUser = provider?.getSigner()._address; +const signIn = async (provider: Provider) => { + //let currentUser = await (provider as JsonRpcProvider).getSigner(0); if (!provider && window.ethereum) { - provider = new providers.Web3Provider(window.ethereum); + provider = new BrowserProvider(window.ethereum); } - if (window.ethereum) { - const accounts = await window.ethereum.request({ - method: 'eth_requestAccounts' - }); - currentUser = accounts && accounts[0]; - } - if (!currentUser) { - console.error('No address'); - return; - } - const responseData = await axios.get( - `/api/users/${currentUser}` - ); + const responseData = await axios.get(`/api/users/me`); const { success } = responseData.data; + return false; + //const loginResponse = await signWeb3Message(currentUser.address); + //return loginResponse?.success; +}; + +const getChallenge = async (userAddress: Hex, ownerAddress?: Hex) => { + const responseData = await axios.post( + `/api/auth/get_challenge/`, + { + userAddress, + intent: 'login', + ownerAddress: ownerAddress || userAddress + } + ); + const { response } = responseData.data; + return response; +}; + +const respondChallenge = async (challenge, signedChallenge) => { + const loginResponse = await rFetch('/api/auth/login', { + method: 'POST', + body: JSON.stringify({ + MetaMessage: JSON.parse(challenge).message.challenge, + MetaSignature: signedChallenge + }), + headers: { + 'Content-Type': 'application/json' + } + }); + + const { success, user } = loginResponse; + if (!success) { + Swal.fire('Error', `Login failed`, 'error'); return; } - const loginResponse = await signWeb3Message(currentUser); - return loginResponse?.success; + return { success, user }; }; -const signWeb3Message = async ( - userAddress?: string, - method: 'programmatic' | 'metamask' | 'web3auth' = 'metamask', - signTypedData?: any, - ownerAddress?: string -) => { - try { - const responseData = await axios.post( - `/api/auth/get_challenge/`, - { - userAddress, - intent: 'login', - ownerAddress - } - ); - const { response } = responseData.data; - - // Prepare signed message response - let ethResponse; +const signWeb3MessageMetamask = async (userAddress: Hex) => { + const challenge = await getChallenge(userAddress); + if (window.ethereum) { + const ethRequest = { + method: 'eth_signTypedData_v4', + params: [userAddress, challenge], + from: userAddress + }; + const signedChallenge = await window?.ethereum?.request(ethRequest); + if (signedChallenge) { + return await respondChallenge(challenge, signedChallenge); + } + } +}; - switch (method) { - case 'programmatic': - if (signTypedData) { - const parsedResponse = JSON.parse(response); - ethResponse = await signTypedData( - parsedResponse.domain, - parsedResponse.types, - parsedResponse.message - ); - } - break; - case 'metamask': - if (window.ethereum) { - const ethRequest = { - method: 'eth_signTypedData_v4', - params: [userAddress, response], - from: userAddress - }; - ethResponse = await window?.ethereum?.request(ethRequest); - } - break; - case 'web3auth': - if (signTypedData) { - const parsedResponse = JSON.parse(response); - ethResponse = await signTypedData(parsedResponse); - } - const loginResponse = await rFetch('/api/auth/loginSmartAccount', { - method: 'POST', - body: JSON.stringify({ - MetaMessage: JSON.parse(response).message.challenge, - MetaSignature: ethResponse, - userAddress - }), - headers: { - 'Content-Type': 'application/json' - } - }); - const { success, user } = loginResponse; - if (!success) { - Swal.fire('Error', `Web3Login failed`, 'error'); - return; - } - return { success, user }; - default: - await Swal.fire('Error', "Can't sign messages", 'error'); - return; +const signWeb3MessageWeb3Auth = async (userAddress: Hex) => { + const web3AuthSigner = new Web3AuthSigner({ + clientId: import.meta.env.VITE_WEB3AUTH_CLIENT_ID, + chainConfig: { + chainNamespace: 'eip155' } + }); - if (ethResponse) { - const loginResponse = await rFetch('/api/auth/login', { - method: 'POST', - body: JSON.stringify({ - MetaMessage: JSON.parse(response).message.challenge, - MetaSignature: ethResponse - }), - headers: { - 'Content-Type': 'application/json' - } - }); + await web3AuthSigner.authenticate({ + init: async () => { + await web3AuthSigner.inner.initModal(); + }, + connect: async () => { + await web3AuthSigner.inner.connect(); + } + }); - const { success, user } = loginResponse; + const challenge = await getChallenge( + userAddress, + await web3AuthSigner.getAddress() + ); - if (!success) { - Swal.fire('Error', `Login failed`, 'error'); - return; - } - return { success, user }; + const parsedResponse = JSON.parse(challenge); + const signedChallenge = await web3AuthSigner.signTypedData(parsedResponse); + const loginResponse = await rFetch('/api/auth/loginSmartAccount', { + method: 'POST', + body: JSON.stringify({ + MetaMessage: parsedResponse.message.challenge, + MetaSignature: signedChallenge, + userAddress + }), + headers: { + 'Content-Type': 'application/json' } - } catch (e) { - console.error(e); - return { success: false }; + }); + // eslint-disable-next-line no-case-declarations + const { success, user } = loginResponse; + if (!success) { + Swal.fire('Error', `Web3Login failed`, 'error'); + return; } + return { success, user }; }; -// Custom hook for taking jwt token from redux -// const useRfetch = () => { -// const { token } = useSelector(store => store.accessStore); -// return async (route, options, retryOptions = undefined) => { -// const request = await fetch(route, { -// headers: { -// ...options?.headers -// }, -// ...options -// }); -// try { -// let parsing = await request.json() -// if (!parsing.success) { -// if (['jwt malformed', 'jwt expired'].includes(parsing.message) && (window.ethereum || retryOptions?.provider)) { -// localStorage.removeItem('token'); -// let retry = await signIn(retryOptions?.provider); -// if (retry) { -// return rFetch(route, options); -// } -// } -// Swal.fire('Error', parsing?.message, 'error'); -// } -// return parsing; -// } catch (err) { -// console.error(request, err); -// } -// return request; -// } -// } - const rFetch = async ( route: string, options?: RequestInit, @@ -200,4 +156,4 @@ const rFetch = async ( return request; }; -export { /* useRfetch */ rFetch, signIn, signWeb3Message }; +export { rFetch, signIn, signWeb3MessageMetamask, signWeb3MessageWeb3Auth }; diff --git a/rair-front/src/utils/utils.types.ts b/rair-front/src/utils/utils.types.ts index e49ef31dd..c06a08385 100644 --- a/rair-front/src/utils/utils.types.ts +++ b/rair-front/src/utils/utils.types.ts @@ -1,5 +1,6 @@ import { chains } from '@alchemy/aa-core'; import { Network } from 'alchemy-sdk'; +import { Hex } from 'viem'; export type TNativeCurrency = { name: string; @@ -7,20 +8,11 @@ export type TNativeCurrency = { decimals: number; }; -export type TAddChainData = { - chainId: BlockchainType; - chainName: string; - nativeCurrency?: TNativeCurrency; - rpcUrls: Array; - blockExplorerUrls: Array; -}; export type TChainItemData = { testnet?: boolean; image: string; name: string; - chainId: BlockchainType; - symbol: string; - addChainData: TAddChainData; + chainId: Hex; disabled?: boolean; viem?: chains.Chain; alchemy?: Network; @@ -29,5 +21,5 @@ export type TChainItemData = { alchemyGasPolicy?: string; }; export type TChainData = { - [key in BlockchainType]?: TChainItemData; + [key in Hex]?: TChainItemData; }; diff --git a/rair-front/src/views/ErrorFallback/ErrorFallback.tsx b/rair-front/src/views/ErrorFallback/ErrorFallback.tsx index 31e4b8cf7..131a12c84 100644 --- a/rair-front/src/views/ErrorFallback/ErrorFallback.tsx +++ b/rair-front/src/views/ErrorFallback/ErrorFallback.tsx @@ -1,17 +1,16 @@ -import React from 'react'; -import { useSelector } from 'react-redux'; +import { FC } from 'react'; -import { RootState } from '../../ducks'; -import { ColorStoreType } from '../../ducks/colors/colorStore.types'; +import { useAppSelector } from '../../hooks/useReduxHooks'; -const ErrorFallback: React.FC = () => { - const { primaryColor, secondaryColor, textColor, primaryButtonColor } = - useSelector((store) => store.colorStore); +const ErrorFallback: FC = () => { + const { primaryColor, textColor, primaryButtonColor } = useAppSelector( + (store) => store.colors + ); return (
diff --git a/rair-front/tsconfig.json b/rair-front/tsconfig.json index 45934ea97..da5f04414 100644 --- a/rair-front/tsconfig.json +++ b/rair-front/tsconfig.json @@ -5,7 +5,7 @@ "lib": [ "dom", "dom.iterable", - "esnext" + "ESNext", ], "noImplicitAny": false, "allowJs": true, @@ -15,8 +15,8 @@ "strict": true, "forceConsistentCasingInFileNames": true, "noFallthroughCasesInSwitch": true, - "module": "esnext", - "moduleResolution": "node", + "module": "ESNext", + "moduleResolution": "Bundler", "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, diff --git a/rair-front/yarn.lock b/rair-front/yarn.lock index a3d10a45b..4b8011283 100644 --- a/rair-front/yarn.lock +++ b/rair-front/yarn.lock @@ -12,6 +12,11 @@ resolved "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz" integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q== +"@adraffy/ens-normalize@1.10.1": + version "1.10.1" + resolved "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz" + integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw== + "@adraffy/ens-normalize@1.9.0": version "1.9.0" resolved "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.9.0.tgz" @@ -22,20 +27,20 @@ resolved "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.9.2.tgz" integrity sha512-0h+FrQDqe2Wn+IIGFkTCd4aAwTJ+7834Ek1COohCyV26AXhwQ7WQaz+4F/nLOeVl/3BtWHOHLPsq46V8YB46Eg== -"@alchemy/aa-accounts@^3.18.2": - version "3.18.2" - resolved "https://registry.npmjs.org/@alchemy/aa-accounts/-/aa-accounts-3.18.2.tgz" - integrity sha512-QrynT78kcVMKkCLmGFsxRNQpW2Caz1yNEwbIMOVR+vVOC41WKRqPTnqgoGmIi0XLcsO7OWCXymTt/muiOt1w1A== +"@alchemy/aa-accounts@^3.19.0": + version "3.19.0" + resolved "https://registry.npmjs.org/@alchemy/aa-accounts/-/aa-accounts-3.19.0.tgz" + integrity sha512-cdR8H9LveeUyBWFkmoqU7hZnFoqmdyPQDYZRtFr9aF+3zWAQYYJ/13Vz7aoVQ4lZ57+JQj7fN5vSVn2gFI47yA== dependencies: "@alchemy/aa-core" "^3.18.2" viem "2.8.6" -"@alchemy/aa-alchemy@^3.18.2": - version "3.18.2" - resolved "https://registry.npmjs.org/@alchemy/aa-alchemy/-/aa-alchemy-3.18.2.tgz" - integrity sha512-XetelHTNWbzK3ZzcxqfU86zFR6ng1q3ij6vJ4MkazusSoyT8ZS22chhCN0NhtvANf4G/5Ivaggxs4+dTWGMKDA== +"@alchemy/aa-alchemy@^3.19.0": + version "3.19.0" + resolved "https://registry.npmjs.org/@alchemy/aa-alchemy/-/aa-alchemy-3.19.0.tgz" + integrity sha512-18MGo0jzp6JkSOuzZHLuy4dIR1BC0P623pqdbsASMKLCoyTMKPtPR1yfgiIf8KJ8jTun6dfwwN0h7eCU1aHYcA== dependencies: - "@alchemy/aa-core" "^3.18.2" + "@alchemy/aa-core" "^3.19.0" "@tanstack/react-form" "^0.19.4" "@tanstack/zod-form-adapter" "^0.19.4" "@turnkey/http" "^2.6.2" @@ -52,25 +57,25 @@ zod "^3.22.4" zustand "^4.5.2" optionalDependencies: - "@alchemy/aa-accounts" "^3.18.2" + "@alchemy/aa-accounts" "^3.19.0" alchemy-sdk "^3.0.0" -"@alchemy/aa-core@^3.18.2": - version "3.18.2" - resolved "https://registry.npmjs.org/@alchemy/aa-core/-/aa-core-3.18.2.tgz" - integrity sha512-uXVpPz5tpBiARC4QCj/MAK45J09Pt3pJQpmFDiHSj4ZEcQB7ZraP2z8Bi6jLMkMDyHPjUiTeJf+aRV3Gqyeunw== +"@alchemy/aa-core@^3.18.2", "@alchemy/aa-core@^3.19.0": + version "3.19.0" + resolved "https://registry.npmjs.org/@alchemy/aa-core/-/aa-core-3.19.0.tgz" + integrity sha512-gVSesLsXORMuiA3w/w+4eQikzrikpj1XN2Sbrcik0v25AKH5QrHn0HddhyrN1aCFW2NoXjyhwxlySiTDVfTgxQ== dependencies: abitype "^0.8.3" eventemitter3 "^5.0.1" viem "2.8.6" zod "^3.22.4" -"@alchemy/aa-ethers@^3.18.2": - version "3.18.2" - resolved "https://registry.npmjs.org/@alchemy/aa-ethers/-/aa-ethers-3.18.2.tgz" - integrity sha512-Ky+shMoYfMWnEK+6SoHOKkxheV06hr4QlHH/u9KaASzCgXW2InkhkmZ6/Fy3lxsQZcmNrSCxu13WjWJ6GJlHEQ== +"@alchemy/aa-ethers@^3.19.0": + version "3.19.0" + resolved "https://registry.npmjs.org/@alchemy/aa-ethers/-/aa-ethers-3.19.0.tgz" + integrity sha512-kdlWQNG2FqpId9HNQ94FIMHhp8bPWV+U4C9WSORqP19f7nM5ukSJAspAGMd0T1u1Ca0xCf/5KWW1EoxO1S2B0A== dependencies: - "@alchemy/aa-core" "^3.18.2" + "@alchemy/aa-core" "^3.19.0" "@ethersproject/abi" "^5.7.0" "@ethersproject/abstract-signer" "^5.7.0" "@ethersproject/bytes" "^5.7.0" @@ -81,12 +86,12 @@ "@ethersproject/wallet" "^5.7.0" viem "2.8.6" -"@alchemy/aa-signers@^3.18.2": - version "3.18.2" - resolved "https://registry.npmjs.org/@alchemy/aa-signers/-/aa-signers-3.18.2.tgz" - integrity sha512-A8vvINNHpfXk9YTPeDW/Xc/wWBTxm0aKw4td2MPVxHX3E3LEhJYRwccB49UibP1Of8kPQLpRjH1uIhUjuZFnug== +"@alchemy/aa-signers@^3.19.0": + version "3.19.0" + resolved "https://registry.npmjs.org/@alchemy/aa-signers/-/aa-signers-3.19.0.tgz" + integrity sha512-alnaD5KG6HwCk+wRCEI8Qf+I7lofK6qvHA7LMY+GLnNfnT/vCo5G9PlUfYTOpl/ebxP3faj0RGuJzj8PbGmQ0w== dependencies: - "@alchemy/aa-core" "^3.18.2" + "@alchemy/aa-core" "^3.19.0" viem "2.8.6" optionalDependencies: "@arcana/auth" "^1.0.8" @@ -126,10 +131,10 @@ dependencies: "@analytics/global-storage-utils" "^0.1.7" -"@analytics/core@^0.12.7": - version "0.12.7" - resolved "https://registry.npmjs.org/@analytics/core/-/core-0.12.7.tgz" - integrity sha512-etmIPCoxWLoUZ/o1o2zvIk4cdVHa8I1xUQtTuLA+YXQ4SsFbm75ZoMXJBqWrNSENpqCJgoL6hizl5uTbkNN+1Q== +"@analytics/core@^0.12.15": + version "0.12.15" + resolved "https://registry.npmjs.org/@analytics/core/-/core-0.12.15.tgz" + integrity sha512-Y+zxTNIbONXKxeEUOtcXs4b3uuiGjF5sy1zHl8ZNkIBwrOpTM8ZGNhi0xGL8ZhaQLGbi03BrT6DaoNNG3sBQOg== dependencies: "@analytics/global-storage-utils" "^0.1.7" "@analytics/type-utils" "^0.6.2" @@ -192,7 +197,7 @@ resolved "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.9.4.tgz" integrity sha512-HazVq9zwTVwGmqdwYzu7WyQ6FQVZ7SwET0KKQuKm55jD0IfUpZgN0OPIiZG3zV1iSrVYcN0bdwLRXI/VNCYsUA== -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.7": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.24.7": version "7.24.7" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz" integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== @@ -200,43 +205,43 @@ "@babel/highlight" "^7.24.7" picocolors "^1.0.0" -"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz" - integrity sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw== +"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.24.7", "@babel/compat-data@^7.25.2": + version "7.25.2" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz" + integrity sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ== -"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.0.0-0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.12.0", "@babel/core@^7.13.0", "@babel/core@^7.13.16", "@babel/core@^7.20.0", "@babel/core@^7.21.3", "@babel/core@^7.23.5", "@babel/core@^7.4.0 || ^8.0.0-0 <8.0.0": - version "7.23.7" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz" - integrity sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw== +"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.0.0-0 || ^8.0.0-0 <8.0.0", "@babel/core@^7.12.0", "@babel/core@^7.13.0", "@babel/core@^7.13.16", "@babel/core@^7.20.0", "@babel/core@^7.21.3", "@babel/core@^7.24.5", "@babel/core@^7.4.0 || ^8.0.0-0 <8.0.0": + version "7.25.2" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz" + integrity sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA== dependencies: "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.23.5" - "@babel/generator" "^7.23.6" - "@babel/helper-compilation-targets" "^7.23.6" - "@babel/helper-module-transforms" "^7.23.3" - "@babel/helpers" "^7.23.7" - "@babel/parser" "^7.23.6" - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.7" - "@babel/types" "^7.23.6" + "@babel/code-frame" "^7.24.7" + "@babel/generator" "^7.25.0" + "@babel/helper-compilation-targets" "^7.25.2" + "@babel/helper-module-transforms" "^7.25.2" + "@babel/helpers" "^7.25.0" + "@babel/parser" "^7.25.0" + "@babel/template" "^7.25.0" + "@babel/traverse" "^7.25.2" + "@babel/types" "^7.25.2" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.20.0", "@babel/generator@^7.23.6", "@babel/generator@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz" - integrity sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA== +"@babel/generator@^7.20.0", "@babel/generator@^7.25.0": + version "7.25.0" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz" + integrity sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw== dependencies: - "@babel/types" "^7.24.7" + "@babel/types" "^7.25.0" "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" jsesc "^2.5.1" -"@babel/helper-annotate-as-pure@^7.22.5", "@babel/helper-annotate-as-pure@^7.24.7": +"@babel/helper-annotate-as-pure@^7.24.7": version "7.24.7" resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz" integrity sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg== @@ -251,14 +256,14 @@ "@babel/traverse" "^7.24.7" "@babel/types" "^7.24.7" -"@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.23.6", "@babel/helper-compilation-targets@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz" - integrity sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg== +"@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.24.7", "@babel/helper-compilation-targets@^7.25.2": + version "7.25.2" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz" + integrity sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw== dependencies: - "@babel/compat-data" "^7.24.7" - "@babel/helper-validator-option" "^7.24.7" - browserslist "^4.22.2" + "@babel/compat-data" "^7.25.2" + "@babel/helper-validator-option" "^7.24.8" + browserslist "^4.23.1" lru-cache "^5.1.1" semver "^6.3.1" @@ -327,7 +332,7 @@ "@babel/traverse" "^7.24.7" "@babel/types" "^7.24.7" -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.5", "@babel/helper-module-imports@^7.24.7": +"@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.24.7": version "7.24.7" resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz" integrity sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA== @@ -335,16 +340,15 @@ "@babel/traverse" "^7.24.7" "@babel/types" "^7.24.7" -"@babel/helper-module-transforms@^7.23.3", "@babel/helper-module-transforms@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz" - integrity sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ== +"@babel/helper-module-transforms@^7.24.7", "@babel/helper-module-transforms@^7.25.2": + version "7.25.2" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz" + integrity sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ== dependencies: - "@babel/helper-environment-visitor" "^7.24.7" "@babel/helper-module-imports" "^7.24.7" "@babel/helper-simple-access" "^7.24.7" - "@babel/helper-split-export-declaration" "^7.24.7" "@babel/helper-validator-identifier" "^7.24.7" + "@babel/traverse" "^7.25.2" "@babel/helper-optimise-call-expression@^7.24.7": version "7.24.7" @@ -399,20 +403,20 @@ dependencies: "@babel/types" "^7.24.7" -"@babel/helper-string-parser@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz" - integrity sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg== +"@babel/helper-string-parser@^7.24.8": + version "7.24.8" + resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz" + integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ== "@babel/helper-validator-identifier@^7.24.7": version "7.24.7" resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz" integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== -"@babel/helper-validator-option@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz" - integrity sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw== +"@babel/helper-validator-option@^7.24.7", "@babel/helper-validator-option@^7.24.8": + version "7.24.8" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz" + integrity sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q== "@babel/helper-wrap-function@^7.24.7": version "7.24.7" @@ -424,14 +428,13 @@ "@babel/traverse" "^7.24.7" "@babel/types" "^7.24.7" -"@babel/helpers@^7.23.7": - version "7.23.7" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.7.tgz" - integrity sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ== +"@babel/helpers@^7.25.0": + version "7.25.0" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz" + integrity sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw== dependencies: - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.7" - "@babel/types" "^7.23.6" + "@babel/template" "^7.25.0" + "@babel/types" "^7.25.0" "@babel/highlight@^7.24.7": version "7.24.7" @@ -443,10 +446,12 @@ js-tokens "^4.0.0" picocolors "^1.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.13.16", "@babel/parser@^7.20.0", "@babel/parser@^7.20.7", "@babel/parser@^7.23.6", "@babel/parser@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz" - integrity sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw== +"@babel/parser@^7.1.0", "@babel/parser@^7.13.16", "@babel/parser@^7.20.0", "@babel/parser@^7.20.7", "@babel/parser@^7.25.0", "@babel/parser@^7.25.3": + version "7.25.3" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz" + integrity sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw== + dependencies: + "@babel/types" "^7.25.2" "@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.24.7": version "7.24.7" @@ -640,7 +645,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.22.5", "@babel/plugin-syntax-jsx@^7.24.7": +"@babel/plugin-syntax-jsx@^7.24.7": version "7.24.7" resolved "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz" integrity sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ== @@ -1038,19 +1043,19 @@ dependencies: "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-react-jsx-self@^7.0.0", "@babel/plugin-transform-react-jsx-self@^7.23.3": - version "7.23.3" - resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz" - integrity sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ== +"@babel/plugin-transform-react-jsx-self@^7.0.0", "@babel/plugin-transform-react-jsx-self@^7.24.5": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.7.tgz" + integrity sha512-fOPQYbGSgH0HUp4UJO4sMBFjY6DuWq+2i8rixyUMb3CdGixs/gccURvYOAhajBdKDoGajFr3mUq5rH3phtkGzw== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.7" -"@babel/plugin-transform-react-jsx-source@^7.0.0", "@babel/plugin-transform-react-jsx-source@^7.23.3": - version "7.23.3" - resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.23.3.tgz" - integrity sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g== +"@babel/plugin-transform-react-jsx-source@^7.0.0", "@babel/plugin-transform-react-jsx-source@^7.24.1": + version "7.24.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.7.tgz" + integrity sha512-J2z+MWzZHVOemyLweMqngXrgGC42jQ//R0KdxqkIz/OrbVIIlhFI3WigZ5fO+nwFvBlncr4MGapd8vTyc7RPNQ== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.7" "@babel/plugin-transform-react-jsx@^7.0.0": version "7.24.7" @@ -1299,44 +1304,41 @@ resolved "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.19.4", "@babel/runtime@^7.20.13", "@babel/runtime@^7.20.6", "@babel/runtime@^7.21.0", "@babel/runtime@^7.22.10", "@babel/runtime@^7.22.5", "@babel/runtime@^7.23.2", "@babel/runtime@^7.23.6", "@babel/runtime@^7.23.9", "@babel/runtime@^7.24.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2", "@babel/runtime@^7.x", "@babel/runtime@7.x": - version "7.24.0" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.0.tgz" - integrity sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw== +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.19.4", "@babel/runtime@^7.20.13", "@babel/runtime@^7.20.6", "@babel/runtime@^7.21.0", "@babel/runtime@^7.22.10", "@babel/runtime@^7.22.5", "@babel/runtime@^7.23.2", "@babel/runtime@^7.23.9", "@babel/runtime@^7.24.0", "@babel/runtime@^7.24.8", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.x", "@babel/runtime@7.x": + version "7.25.0" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.0.tgz" + integrity sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw== dependencies: regenerator-runtime "^0.14.0" -"@babel/template@^7.0.0", "@babel/template@^7.22.15", "@babel/template@^7.24.7": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz" - integrity sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig== +"@babel/template@^7.0.0", "@babel/template@^7.24.7", "@babel/template@^7.25.0": + version "7.25.0" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz" + integrity sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q== dependencies: "@babel/code-frame" "^7.24.7" - "@babel/parser" "^7.24.7" - "@babel/types" "^7.24.7" + "@babel/parser" "^7.25.0" + "@babel/types" "^7.25.0" -"@babel/traverse@^7.20.0", "@babel/traverse@^7.23.7", "@babel/traverse@^7.24.7", "@babel/traverse@^7.4.5": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz" - integrity sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA== +"@babel/traverse@^7.20.0", "@babel/traverse@^7.24.7", "@babel/traverse@^7.25.2": + version "7.25.3" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz" + integrity sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ== dependencies: "@babel/code-frame" "^7.24.7" - "@babel/generator" "^7.24.7" - "@babel/helper-environment-visitor" "^7.24.7" - "@babel/helper-function-name" "^7.24.7" - "@babel/helper-hoist-variables" "^7.24.7" - "@babel/helper-split-export-declaration" "^7.24.7" - "@babel/parser" "^7.24.7" - "@babel/types" "^7.24.7" + "@babel/generator" "^7.25.0" + "@babel/parser" "^7.25.3" + "@babel/template" "^7.25.0" + "@babel/types" "^7.25.2" debug "^4.3.1" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.21.3", "@babel/types@^7.23.6", "@babel/types@^7.24.7", "@babel/types@^7.3.0", "@babel/types@^7.4.4": - version "7.24.7" - resolved "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz" - integrity sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q== +"@babel/types@^7.0.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.21.3", "@babel/types@^7.24.7", "@babel/types@^7.25.0", "@babel/types@^7.25.2", "@babel/types@^7.3.0", "@babel/types@^7.4.4": + version "7.25.2" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz" + integrity sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q== dependencies: - "@babel/helper-string-parser" "^7.24.7" + "@babel/helper-string-parser" "^7.24.8" "@babel/helper-validator-identifier" "^7.24.7" to-fast-properties "^2.0.0" @@ -2144,16 +2146,16 @@ resolved "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz" integrity sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA== -"@emotion/babel-plugin@^11.11.0": - version "11.11.0" - resolved "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz" - integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ== +"@emotion/babel-plugin@^11.12.0": + version "11.12.0" + resolved "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz" + integrity sha512-y2WQb+oP8Jqvvclh8Q55gLUyb7UFvgv7eJfsj7td5TToBrIUtPay2kMrZi4xjq9qw2vD0ZR5fSho0yqoFgX7Rw== dependencies: "@babel/helper-module-imports" "^7.16.7" "@babel/runtime" "^7.18.3" - "@emotion/hash" "^0.9.1" - "@emotion/memoize" "^0.8.1" - "@emotion/serialize" "^1.1.2" + "@emotion/hash" "^0.9.2" + "@emotion/memoize" "^0.9.0" + "@emotion/serialize" "^1.2.0" babel-plugin-macros "^3.1.0" convert-source-map "^1.5.0" escape-string-regexp "^4.0.0" @@ -2161,21 +2163,21 @@ source-map "^0.5.7" stylis "4.2.0" -"@emotion/cache@^11.11.0": - version "11.11.0" - resolved "https://registry.npmjs.org/@emotion/cache/-/cache-11.11.0.tgz" - integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ== +"@emotion/cache@^11.11.0", "@emotion/cache@^11.13.0": + version "11.13.1" + resolved "https://registry.npmjs.org/@emotion/cache/-/cache-11.13.1.tgz" + integrity sha512-iqouYkuEblRcXmylXIwwOodiEK5Ifl7JcX7o6V4jI3iW4mLXX3dmt5xwBtIkJiQEXFAI+pC8X0i67yiPkH9Ucw== dependencies: - "@emotion/memoize" "^0.8.1" - "@emotion/sheet" "^1.2.2" - "@emotion/utils" "^1.2.1" - "@emotion/weak-memoize" "^0.3.1" + "@emotion/memoize" "^0.9.0" + "@emotion/sheet" "^1.4.0" + "@emotion/utils" "^1.4.0" + "@emotion/weak-memoize" "^0.4.0" stylis "4.2.0" -"@emotion/hash@^0.9.1": - version "0.9.1" - resolved "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.1.tgz" - integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== +"@emotion/hash@^0.9.2": + version "0.9.2" + resolved "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz" + integrity sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g== "@emotion/is-prop-valid@^0.8.2": version "0.8.8" @@ -2184,10 +2186,17 @@ dependencies: "@emotion/memoize" "0.7.4" -"@emotion/is-prop-valid@^1.1.0", "@emotion/is-prop-valid@^1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz" - integrity sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw== +"@emotion/is-prop-valid@^1.3.0": + version "1.3.0" + resolved "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.3.0.tgz" + integrity sha512-SHetuSLvJDzuNbOdtPVbq6yMMMlLoW5Q94uDqJZqy50gcmAjxFkVqmzqSGEFq9gT2iMuIeKV1PXVWmvUhuZLlQ== + dependencies: + "@emotion/memoize" "^0.9.0" + +"@emotion/is-prop-valid@1.2.2": + version "1.2.2" + resolved "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz" + integrity sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw== dependencies: "@emotion/memoize" "^0.8.1" @@ -2196,82 +2205,82 @@ resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz" integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== +"@emotion/memoize@^0.9.0": + version "0.9.0" + resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz" + integrity sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ== + "@emotion/memoize@0.7.4": version "0.7.4" resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz" integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== -"@emotion/react@^11.0.0", "@emotion/react@^11.0.0-rc.0", "@emotion/react@^11.10.8", "@emotion/react@^11.11.4", "@emotion/react@^11.4.1", "@emotion/react@^11.5.0", "@emotion/react@>=10.0.35": - version "11.11.4" - resolved "https://registry.npmjs.org/@emotion/react/-/react-11.11.4.tgz" - integrity sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw== +"@emotion/react@^11.0.0", "@emotion/react@^11.0.0-rc.0", "@emotion/react@^11.10.8", "@emotion/react@^11.13.3", "@emotion/react@^11.4.1", "@emotion/react@^11.5.0", "@emotion/react@>=10.0.35": + version "11.13.3" + resolved "https://registry.npmjs.org/@emotion/react/-/react-11.13.3.tgz" + integrity sha512-lIsdU6JNrmYfJ5EbUCf4xW1ovy5wKQ2CkPRM4xogziOxH1nXxBSjpC9YqbFAP7circxMfYp+6x676BqWcEiixg== dependencies: "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.11.0" - "@emotion/cache" "^11.11.0" - "@emotion/serialize" "^1.1.3" - "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" - "@emotion/utils" "^1.2.1" - "@emotion/weak-memoize" "^0.3.1" + "@emotion/babel-plugin" "^11.12.0" + "@emotion/cache" "^11.13.0" + "@emotion/serialize" "^1.3.1" + "@emotion/use-insertion-effect-with-fallbacks" "^1.1.0" + "@emotion/utils" "^1.4.0" + "@emotion/weak-memoize" "^0.4.0" hoist-non-react-statics "^3.3.1" -"@emotion/serialize@^1.1.2", "@emotion/serialize@^1.1.3": - version "1.1.3" - resolved "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.3.tgz" - integrity sha512-iD4D6QVZFDhcbH0RAG1uVu1CwVLMWUkCvAqqlewO/rxf8+87yIBAlt4+AxMiiKPLs5hFc0owNk/sLLAOROw3cA== +"@emotion/serialize@^1.2.0", "@emotion/serialize@^1.3.0", "@emotion/serialize@^1.3.1": + version "1.3.1" + resolved "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.1.tgz" + integrity sha512-dEPNKzBPU+vFPGa+z3axPRn8XVDetYORmDC0wAiej+TNcOZE70ZMJa0X7JdeoM6q/nWTMZeLpN/fTnD9o8MQBA== dependencies: - "@emotion/hash" "^0.9.1" - "@emotion/memoize" "^0.8.1" - "@emotion/unitless" "^0.8.1" - "@emotion/utils" "^1.2.1" + "@emotion/hash" "^0.9.2" + "@emotion/memoize" "^0.9.0" + "@emotion/unitless" "^0.10.0" + "@emotion/utils" "^1.4.0" csstype "^3.0.2" -"@emotion/sheet@^1.2.2": - version "1.2.2" - resolved "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.2.tgz" - integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== +"@emotion/sheet@^1.4.0": + version "1.4.0" + resolved "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz" + integrity sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg== -"@emotion/styled@^11.0.0", "@emotion/styled@^11.10.8", "@emotion/styled@^11.11.0", "@emotion/styled@^11.3.0": - version "11.11.0" - resolved "https://registry.npmjs.org/@emotion/styled/-/styled-11.11.0.tgz" - integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng== +"@emotion/styled@^11.0.0", "@emotion/styled@^11.10.8", "@emotion/styled@^11.13.0", "@emotion/styled@^11.3.0": + version "11.13.0" + resolved "https://registry.npmjs.org/@emotion/styled/-/styled-11.13.0.tgz" + integrity sha512-tkzkY7nQhW/zC4hztlwucpT8QEZ6eUzpXDRhww/Eej4tFfO0FxQYWRyg/c5CCXa4d/f174kqeXYjuQRnhzf6dA== dependencies: "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.11.0" - "@emotion/is-prop-valid" "^1.2.1" - "@emotion/serialize" "^1.1.2" - "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" - "@emotion/utils" "^1.2.1" - -"@emotion/stylis@^0.8.4": - version "0.8.5" - resolved "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz" - integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ== - -"@emotion/unitless@^0.7.4": - version "0.7.5" - resolved "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz" - integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== - -"@emotion/unitless@^0.8.1": + "@emotion/babel-plugin" "^11.12.0" + "@emotion/is-prop-valid" "^1.3.0" + "@emotion/serialize" "^1.3.0" + "@emotion/use-insertion-effect-with-fallbacks" "^1.1.0" + "@emotion/utils" "^1.4.0" + +"@emotion/unitless@^0.10.0": + version "0.10.0" + resolved "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz" + integrity sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg== + +"@emotion/unitless@0.8.1": version "0.8.1" resolved "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz" integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ== -"@emotion/use-insertion-effect-with-fallbacks@^1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz" - integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw== +"@emotion/use-insertion-effect-with-fallbacks@^1.1.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.1.0.tgz" + integrity sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw== -"@emotion/utils@^1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.1.tgz" - integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg== +"@emotion/utils@^1.4.0": + version "1.4.0" + resolved "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.0.tgz" + integrity sha512-spEnrA1b6hDR/C68lC2M7m6ALPUHZC0lIY7jAS/B/9DuuO1ZP04eov8SMv/6fwRd8pzmsn2AuJEznRREWlQrlQ== -"@emotion/weak-memoize@^0.3.1": - version "0.3.1" - resolved "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz" - integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww== +"@emotion/weak-memoize@^0.4.0": + version "0.4.0" + resolved "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz" + integrity sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg== "@esbuild/darwin-arm64@0.21.5": version "0.21.5" @@ -2381,12 +2390,12 @@ ethereum-cryptography "^2.1.3" "@ethereumjs/util@^9.0.3": - version "9.0.3" - resolved "https://registry.npmjs.org/@ethereumjs/util/-/util-9.0.3.tgz" - integrity sha512-PmwzWDflky+7jlZIFqiGsBPap12tk9zK5SVH9YW2OEnDN7OEhCjUOMzbOqwuClrbkSIkM2ERivd7sXZ48Rh/vg== + version "9.1.0" + resolved "https://registry.npmjs.org/@ethereumjs/util/-/util-9.1.0.tgz" + integrity sha512-XBEKsYqLGXLah9PNJbgdkigthkG7TAGvlD/sH12beMXEyHDyigfcbdvHhmLyDWgDyOJn4QwiQUaF7yeuhnjdog== dependencies: "@ethereumjs/rlp" "^5.0.2" - ethereum-cryptography "^2.1.3" + ethereum-cryptography "^2.2.1" "@ethersproject/abi@^5.7.0", "@ethersproject/abi@5.7.0": version "5.7.0" @@ -2758,33 +2767,6 @@ https-proxy-agent "^7.0.2" web3-providers-http "1.8.0" -"@floating-ui/core@^1.4.2": - version "1.5.2" - resolved "https://registry.npmjs.org/@floating-ui/core/-/core-1.5.2.tgz" - integrity sha512-Ii3MrfY/GAIN3OhXNzpCKaLxHQfJF9qvwq/kEJYdqDxeIHa01K8sldugal6TmeeXl+WMvhv9cnVzUTaFFJF09A== - dependencies: - "@floating-ui/utils" "^0.1.3" - -"@floating-ui/dom@^1.5.1": - version "1.5.3" - resolved "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.3.tgz" - integrity sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA== - dependencies: - "@floating-ui/core" "^1.4.2" - "@floating-ui/utils" "^0.1.3" - -"@floating-ui/react-dom@^2.0.4": - version "2.0.4" - resolved "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.4.tgz" - integrity sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ== - dependencies: - "@floating-ui/dom" "^1.5.1" - -"@floating-ui/utils@^0.1.3": - version "0.1.6" - resolved "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.6.tgz" - integrity sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A== - "@fordefi/web3-provider@^0.2.0": version "0.2.0" resolved "https://registry.npmjs.org/@fordefi/web3-provider/-/web3-provider-0.2.0.tgz" @@ -2792,31 +2774,31 @@ dependencies: viem "^2.8.6" -"@fortawesome/fontawesome-common-types@6.5.2": - version "6.5.2" - resolved "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.5.2.tgz" - integrity sha512-gBxPg3aVO6J0kpfHNILc+NMhXnqHumFxOmjYCFfOiLZfwhnnfhtsdA2hfJlDnj+8PjAs6kKQPenOTKj3Rf7zHw== +"@fortawesome/fontawesome-common-types@6.6.0": + version "6.6.0" + resolved "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.6.0.tgz" + integrity sha512-xyX0X9mc0kyz9plIyryrRbl7ngsA9jz77mCZJsUkLl+ZKs0KWObgaEBoSgQiYWAsSmjz/yjl0F++Got0Mdp4Rw== -"@fortawesome/fontawesome-svg-core@^6.5.2", "@fortawesome/fontawesome-svg-core@~1 || ~6": - version "6.5.2" - resolved "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.5.2.tgz" - integrity sha512-5CdaCBGl8Rh9ohNdxeeTMxIj8oc3KNBgIeLMvJosBMdslK/UnEB8rzyDRrbKdL1kDweqBPo4GT9wvnakHWucZw== +"@fortawesome/fontawesome-svg-core@^6.6.0", "@fortawesome/fontawesome-svg-core@~1 || ~6": + version "6.6.0" + resolved "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.6.0.tgz" + integrity sha512-KHwPkCk6oRT4HADE7smhfsKudt9N/9lm6EJ5BVg0tD1yPA5hht837fB87F8pn15D8JfTqQOjhKTktwmLMiD7Kg== dependencies: - "@fortawesome/fontawesome-common-types" "6.5.2" + "@fortawesome/fontawesome-common-types" "6.6.0" -"@fortawesome/free-brands-svg-icons@^6.5.2": - version "6.5.2" - resolved "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.5.2.tgz" - integrity sha512-zi5FNYdmKLnEc0jc0uuHH17kz/hfYTg4Uei0wMGzcoCL/4d3WM3u1VMc0iGGa31HuhV5i7ZK8ZlTCQrHqRHSGQ== +"@fortawesome/free-brands-svg-icons@^6.6.0": + version "6.6.0" + resolved "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.6.0.tgz" + integrity sha512-1MPD8lMNW/earme4OQi1IFHtmHUwAKgghXlNwWi9GO7QkTfD+IIaYpIai4m2YJEzqfEji3jFHX1DZI5pbY/biQ== dependencies: - "@fortawesome/fontawesome-common-types" "6.5.2" + "@fortawesome/fontawesome-common-types" "6.6.0" -"@fortawesome/free-solid-svg-icons@^6.5.2": - version "6.5.2" - resolved "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.5.2.tgz" - integrity sha512-QWFZYXFE7O1Gr1dTIp+D6UcFUF0qElOnZptpi7PBUMylJh+vFmIedVe1Ir6RM1t2tEQLLSV1k7bR4o92M+uqlw== +"@fortawesome/free-solid-svg-icons@^6.6.0": + version "6.6.0" + resolved "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.6.0.tgz" + integrity sha512-IYv/2skhEDFc2WGUcqvFJkeK39Q+HyPf5GHUrT/l2pKbtgEIv1al1TKd6qStR5OIwQdN1GZP54ci3y4mroJWjA== dependencies: - "@fortawesome/fontawesome-common-types" "6.5.2" + "@fortawesome/fontawesome-common-types" "6.6.0" "@fortawesome/react-fontawesome@^0.2.2": version "0.2.2" @@ -2825,14 +2807,14 @@ dependencies: prop-types "^15.8.1" -"@getyoti/react-face-capture@^2.0.0": - version "2.0.0" - resolved "https://registry.npmjs.org/@getyoti/react-face-capture/-/react-face-capture-2.0.0.tgz" - integrity sha512-rxFsHERGjhxJVhz6KXSRy0d5zHpNm4QZiw1kQ9ZIqkEnzlHWgkY2a02dBAzCWutBxAx+Hfuo1NKiq94OTpAbUQ== +"@getyoti/react-face-capture@^2.3.1": + version "2.3.1" + resolved "https://registry.npmjs.org/@getyoti/react-face-capture/-/react-face-capture-2.3.1.tgz" + integrity sha512-PZIrz11FVV8Xw/MKhSQ0nqWhOXaxsfHnNo/dozesvDx7jru4yf8WPL7TZbpZAG1DBWiGqBGh40p+cg/5KWOs3g== dependencies: "@lingui/react" "4.1.2" "@xstate/react" "3.2.2" - axios "1.6.2" + axios "1.6.5" classnames "2.2.6" face-api.js "0.22.0" prop-types "15.7.2" @@ -3785,96 +3767,85 @@ "@motionone/dom" "^10.16.4" tslib "^2.3.1" -"@mui/base@5.0.0-beta.30": - version "5.0.0-beta.30" - resolved "https://registry.npmjs.org/@mui/base/-/base-5.0.0-beta.30.tgz" - integrity sha512-dc38W4W3K42atE9nSaOeoJ7/x9wGIfawdwC/UmMxMLlZ1iSsITQ8dQJaTATCbn98YvYPINK/EH541YA5enQIPQ== +"@mui/core-downloads-tracker@^5.16.7": + version "5.16.7" + resolved "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.7.tgz" + integrity sha512-RtsCt4Geed2/v74sbihWzzRs+HsIQCfclHeORh5Ynu2fS4icIKozcSubwuG7vtzq2uW3fOR1zITSP84TNt2GoQ== + +"@mui/icons-material@^5.16.7": + version "5.16.7" + resolved "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.7.tgz" + integrity sha512-UrGwDJCXEszbDI7yV047BYU5A28eGJ79keTCP4cc74WyncuVrnurlmIRxaHL8YK+LI1Kzq+/JM52IAkNnv4u+Q== dependencies: - "@babel/runtime" "^7.23.6" - "@floating-ui/react-dom" "^2.0.4" - "@mui/types" "^7.2.12" - "@mui/utils" "^5.15.3" - "@popperjs/core" "^2.11.8" - clsx "^2.0.0" - prop-types "^15.8.1" + "@babel/runtime" "^7.23.9" -"@mui/core-downloads-tracker@^5.15.3": - version "5.15.3" - resolved "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.15.3.tgz" - integrity sha512-sWeihiVyxdJjpLkp8SHkTy9kt2M/o11M60G1MzwljGL2BXdM3Ktzqv5QaQHdi00y7Y1ulvtI3GOSxP2xU8mQJw== - -"@mui/icons-material@^5.14.18": - version "5.15.3" - resolved "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.15.3.tgz" - integrity sha512-7LEs8AnO2Se/XYH+CcJndRsGAE+M8KAExiiQHf0V11poqmPVGcbbY82Ry2IUYf9+rOilCVnWI18ErghZ625BPQ== - dependencies: - "@babel/runtime" "^7.23.6" - -"@mui/material@^5.0.0", "@mui/material@^5.14.18": - version "5.15.3" - resolved "https://registry.npmjs.org/@mui/material/-/material-5.15.3.tgz" - integrity sha512-DODBBMouyq1B5f3YkEWL9vO8pGCxuEGqtfpltF6peMJzz/78tJFyLQsDas9MNLC/8AdFu2BQdkK7wox5UBPTAA== - dependencies: - "@babel/runtime" "^7.23.6" - "@mui/base" "5.0.0-beta.30" - "@mui/core-downloads-tracker" "^5.15.3" - "@mui/system" "^5.15.3" - "@mui/types" "^7.2.12" - "@mui/utils" "^5.15.3" +"@mui/material@^5.0.0", "@mui/material@^5.16.7": + version "5.16.7" + resolved "https://registry.npmjs.org/@mui/material/-/material-5.16.7.tgz" + integrity sha512-cwwVQxBhK60OIOqZOVLFt55t01zmarKJiJUWbk0+8s/Ix5IaUzAShqlJchxsIQ4mSrWqgcKCCXKtIlG5H+/Jmg== + dependencies: + "@babel/runtime" "^7.23.9" + "@mui/core-downloads-tracker" "^5.16.7" + "@mui/system" "^5.16.7" + "@mui/types" "^7.2.15" + "@mui/utils" "^5.16.6" + "@popperjs/core" "^2.11.8" "@types/react-transition-group" "^4.4.10" - clsx "^2.0.0" - csstype "^3.1.2" + clsx "^2.1.0" + csstype "^3.1.3" prop-types "^15.8.1" - react-is "^18.2.0" + react-is "^18.3.1" react-transition-group "^4.4.5" -"@mui/private-theming@^5.15.3": - version "5.15.3" - resolved "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.15.3.tgz" - integrity sha512-Q79MhVMmywC1l5bMsMZq5PsIudr1MNPJnx9/EqdMP0vpz5iNvFpnLmxsD7d8/hqTWgFAljI+LH3jX8MxlZH9Gw== +"@mui/private-theming@^5.16.6": + version "5.16.6" + resolved "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.16.6.tgz" + integrity sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw== dependencies: - "@babel/runtime" "^7.23.6" - "@mui/utils" "^5.15.3" + "@babel/runtime" "^7.23.9" + "@mui/utils" "^5.16.6" prop-types "^15.8.1" -"@mui/styled-engine@^5.15.3": - version "5.15.3" - resolved "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.15.3.tgz" - integrity sha512-+d5XZCTeemOO/vBfWGEeHgTm8fjU1Psdgm+xAw+uegycO2EnoA/EfGSaG5UwZ6g3b66y48Mkxi35AggShMr88w== +"@mui/styled-engine@^5.16.6": + version "5.16.6" + resolved "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.16.6.tgz" + integrity sha512-zaThmS67ZmtHSWToTiHslbI8jwrmITcN93LQaR2lKArbvS7Z3iLkwRoiikNWutx9MBs8Q6okKvbZq1RQYB3v7g== dependencies: - "@babel/runtime" "^7.23.6" + "@babel/runtime" "^7.23.9" "@emotion/cache" "^11.11.0" - csstype "^3.1.2" + csstype "^3.1.3" prop-types "^15.8.1" -"@mui/system@^5.15.3": - version "5.15.3" - resolved "https://registry.npmjs.org/@mui/system/-/system-5.15.3.tgz" - integrity sha512-ewVU4eRgo4VfNMGpO61cKlfWmH7l9s6rA8EknRzuMX3DbSLfmtW2WJJg6qPwragvpPIir0Pp/AdWVSDhyNy5Tw== +"@mui/system@^5.16.7": + version "5.16.7" + resolved "https://registry.npmjs.org/@mui/system/-/system-5.16.7.tgz" + integrity sha512-Jncvs/r/d/itkxh7O7opOunTqbbSSzMTHzZkNLM+FjAOg+cYAZHrPDlYe1ZGKUYORwwb2XexlWnpZp0kZ4AHuA== dependencies: - "@babel/runtime" "^7.23.6" - "@mui/private-theming" "^5.15.3" - "@mui/styled-engine" "^5.15.3" - "@mui/types" "^7.2.12" - "@mui/utils" "^5.15.3" - clsx "^2.0.0" - csstype "^3.1.2" + "@babel/runtime" "^7.23.9" + "@mui/private-theming" "^5.16.6" + "@mui/styled-engine" "^5.16.6" + "@mui/types" "^7.2.15" + "@mui/utils" "^5.16.6" + clsx "^2.1.0" + csstype "^3.1.3" prop-types "^15.8.1" -"@mui/types@^7.2.12": - version "7.2.12" - resolved "https://registry.npmjs.org/@mui/types/-/types-7.2.12.tgz" - integrity sha512-3kaHiNm9khCAo0pVe0RenketDSFoZGAlVZ4zDjB/QNZV0XiCj+sh1zkX0VVhQPgYJDlBEzAag+MHJ1tU3vf0Zw== +"@mui/types@^7.2.15": + version "7.2.15" + resolved "https://registry.npmjs.org/@mui/types/-/types-7.2.15.tgz" + integrity sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q== -"@mui/utils@^5.15.3": - version "5.15.3" - resolved "https://registry.npmjs.org/@mui/utils/-/utils-5.15.3.tgz" - integrity sha512-mT3LiSt9tZWCdx1pl7q4Q5tNo6gdZbvJel286ZHGuj6LQQXjWNAh8qiF9d+LogvNUI+D7eLkTnj605d1zoazfg== +"@mui/utils@^5.16.6": + version "5.16.6" + resolved "https://registry.npmjs.org/@mui/utils/-/utils-5.16.6.tgz" + integrity sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA== dependencies: - "@babel/runtime" "^7.23.6" - "@types/prop-types" "^15.7.11" + "@babel/runtime" "^7.23.9" + "@mui/types" "^7.2.15" + "@types/prop-types" "^15.7.12" + clsx "^2.1.1" prop-types "^15.8.1" - react-is "^18.2.0" + react-is "^18.3.1" "@multiformats/murmur3@^2.0.0": version "2.1.8" @@ -3891,6 +3862,13 @@ dependencies: "@noble/hashes" "1.3.3" +"@noble/curves@^1.4.0": + version "1.5.0" + resolved "https://registry.npmjs.org/@noble/curves/-/curves-1.5.0.tgz" + integrity sha512-J5EKamIHnKPyClwVrzmaf5wSdQXgdHcPZIZLu3bwnbeCx8/7NPK5q2ZBWF+5FvYGByjiQQsJYX6jfgB2wDPn3A== + dependencies: + "@noble/hashes" "1.4.0" + "@noble/curves@~1.0.0", "@noble/curves@1.0.0": version "1.0.0" resolved "https://registry.npmjs.org/@noble/curves/-/curves-1.0.0.tgz" @@ -3905,7 +3883,14 @@ dependencies: "@noble/hashes" "1.3.2" -"@noble/curves@~1.4.0", "@noble/curves@1.4.0": +"@noble/curves@~1.4.0", "@noble/curves@1.4.2": + version "1.4.2" + resolved "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz" + integrity sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw== + dependencies: + "@noble/hashes" "1.4.0" + +"@noble/curves@1.4.0": version "1.4.0" resolved "https://registry.npmjs.org/@noble/curves/-/curves-1.4.0.tgz" integrity sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg== @@ -3917,6 +3902,11 @@ resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.3.tgz" integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== +"@noble/hashes@^1.4.0", "@noble/hashes@~1.4.0", "@noble/hashes@1.4.0": + version "1.4.0" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz" + integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== + "@noble/hashes@~1.2.0": version "1.2.0" resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz" @@ -3927,11 +3917,6 @@ resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz" integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== -"@noble/hashes@~1.4.0", "@noble/hashes@1.4.0": - version "1.4.0" - resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz" - integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== - "@noble/hashes@1.1.2": version "1.1.2" resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.1.2.tgz" @@ -4057,9 +4042,9 @@ integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== "@pkgr/core@^0.1.0": - version "0.1.0" - resolved "https://registry.npmjs.org/@pkgr/core/-/core-0.1.0.tgz" - integrity sha512-Zwq5OCzuwJC2jwqmpEQt7Ds1DTi6BWSwoGkbb1n9pO3hzb35BoJELx7c0T23iDkBGkh2e7tvOtjF3tr3OaQHDQ== + version "0.1.1" + resolved "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz" + integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== "@popperjs/core@^2.11.8", "@popperjs/core@^2.9.3": version "2.11.8" @@ -4462,53 +4447,20 @@ invariant "^2.2.4" nullthrows "^1.1.1" -"@redux-saga/core@^1.3.0": - version "1.3.0" - resolved "https://registry.npmjs.org/@redux-saga/core/-/core-1.3.0.tgz" - integrity sha512-L+i+qIGuyWn7CIg7k1MteHGfttKPmxwZR5E7OsGikCL2LzYA0RERlaUY00Y3P3ZV2EYgrsYlBrGs6cJP5OKKqA== - dependencies: - "@babel/runtime" "^7.6.3" - "@redux-saga/deferred" "^1.2.1" - "@redux-saga/delay-p" "^1.2.1" - "@redux-saga/is" "^1.1.3" - "@redux-saga/symbols" "^1.1.3" - "@redux-saga/types" "^1.2.1" - typescript-tuple "^2.2.1" - -"@redux-saga/deferred@^1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@redux-saga/deferred/-/deferred-1.2.1.tgz" - integrity sha512-cmin3IuuzMdfQjA0lG4B+jX+9HdTgHZZ+6u3jRAOwGUxy77GSlTi4Qp2d6PM1PUoTmQUR5aijlA39scWWPF31g== - -"@redux-saga/delay-p@^1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@redux-saga/delay-p/-/delay-p-1.2.1.tgz" - integrity sha512-MdiDxZdvb1m+Y0s4/hgdcAXntpUytr9g0hpcOO1XFVyyzkrDu3SKPgBFOtHn7lhu7n24ZKIAT1qtKyQjHqRd+w== - dependencies: - "@redux-saga/symbols" "^1.1.3" - -"@redux-saga/is@^1.1.3": - version "1.1.3" - resolved "https://registry.npmjs.org/@redux-saga/is/-/is-1.1.3.tgz" - integrity sha512-naXrkETG1jLRfVfhOx/ZdLj0EyAzHYbgJWkXbB3qFliPcHKiWbv/ULQryOAEKyjrhiclmr6AMdgsXFyx7/yE6Q== +"@reduxjs/toolkit@^2.2.7": + version "2.2.7" + resolved "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.7.tgz" + integrity sha512-faI3cZbSdFb8yv9dhDTmGwclW0vk0z5o1cia+kf7gCbaCwHI5e+7tP57mJUv22pNcNbeA62GSrPpfrUfdXcQ6g== dependencies: - "@redux-saga/symbols" "^1.1.3" - "@redux-saga/types" "^1.2.1" - -"@redux-saga/symbols@^1.1.3": - version "1.1.3" - resolved "https://registry.npmjs.org/@redux-saga/symbols/-/symbols-1.1.3.tgz" - integrity sha512-hCx6ZvU4QAEUojETnX8EVg4ubNLBFl1Lps4j2tX7o45x/2qg37m3c6v+kSp8xjDJY+2tJw4QB3j8o8dsl1FDXg== - -"@redux-saga/types@^1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@redux-saga/types/-/types-1.2.1.tgz" - integrity sha512-1dgmkh+3so0+LlBWRhGA33ua4MYr7tUOj+a9Si28vUi0IUFNbff1T3sgpeDJI/LaC75bBYnQ0A3wXjn0OrRNBA== + immer "^10.0.3" + redux "^5.0.1" + redux-thunk "^3.1.0" + reselect "^5.1.0" -"@remix-run/router@1.15.3": - version "1.15.3" - resolved "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz" - integrity sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w== +"@remix-run/router@1.19.1": + version "1.19.1" + resolved "https://registry.npmjs.org/@remix-run/router/-/router-1.19.1.tgz" + integrity sha512-S45oynt/WH19bHbIXjtli6QmwNYvaz+vtnubvNpNDvUOoA/OWh6j1OikIP3G+v5GHdxyC6EXoChG3HgYGEUfcg== "@rnx-kit/chromium-edge-launcher@^1.0.0": version "1.0.0" @@ -4540,10 +4492,10 @@ estree-walker "^2.0.2" picomatch "^2.3.1" -"@rollup/rollup-darwin-arm64@4.17.2": - version "4.17.2" - resolved "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz" - integrity sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw== +"@rollup/rollup-darwin-arm64@4.21.0": + version "4.21.0" + resolved "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.0.tgz" + integrity sha512-zOnKWLgDld/svhKO5PD9ozmL6roy5OQ5T4ThvdYZLpiOhEGY+dp2NwUmxK0Ld91LrbjrvtNAE0ERBwjqhZTRAA== "@safe-global/safe-apps-provider@^0.18.1", "@safe-global/safe-apps-provider@0.18.1": version "0.18.1" @@ -5036,6 +4988,11 @@ resolved "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.36.1.tgz" integrity sha512-DJSilV5+ytBP1FbFcEJovv4rnnm/CokuVvrBEtW/Va9DvuJ3HksbXUJEpI0aV1KtuL4ZoO9AVE6PyNLzF7tLeA== +"@tanstack/query-core@5.28.9": + version "5.28.9" + resolved "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.28.9.tgz" + integrity sha512-hNlfCiqZevr3GRVPXS3MhaGW5hjcxvCsIQ4q6ff7EPlvFwYZaS+0d9EIIgofnegDaU2BbCDlyURoYfRl5rmzow== + "@tanstack/query-persist-client-core@4.36.1": version "4.36.1" resolved "https://registry.npmjs.org/@tanstack/query-persist-client-core/-/query-persist-client-core-4.36.1.tgz" @@ -5067,7 +5024,7 @@ dependencies: "@tanstack/query-persist-client-core" "4.36.1" -"@tanstack/react-query@^4.28.0", "@tanstack/react-query@^4.36.1", "@tanstack/react-query@^5.28.9", "@tanstack/react-query@>=5.0.0": +"@tanstack/react-query@^4.28.0", "@tanstack/react-query@^4.36.1": version "4.36.1" resolved "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.36.1.tgz" integrity sha512-y7ySVHFyyQblPl3J3eQBWpXZkliroki3ARnBKsdJchlgt7yJLRDUcf4B8soufgiYt3pEQIkBWBx1N9/ZPIeUWw== @@ -5075,6 +5032,13 @@ "@tanstack/query-core" "4.36.1" use-sync-external-store "^1.2.0" +"@tanstack/react-query@^5.28.9", "@tanstack/react-query@>=5.0.0": + version "5.28.9" + resolved "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.28.9.tgz" + integrity sha512-vwifBkGXsydsLxFOBMe3+f8kvtDoqDRDwUNjPHVDDt+FoBetCbOWAUHgZn4k+CVeZgLmy7bx6aKeDbe3e8koOQ== + dependencies: + "@tanstack/query-core" "5.28.9" + "@tanstack/react-store@^0.3.1": version "0.3.1" resolved "https://registry.npmjs.org/@tanstack/react-store/-/react-store-0.3.1.tgz" @@ -5139,22 +5103,20 @@ lodash "^4.17.21" loglevel "^1.8.1" -"@toruslabs/base-controllers@^5.7.0": - version "5.8.1" - resolved "https://registry.npmjs.org/@toruslabs/base-controllers/-/base-controllers-5.8.1.tgz" - integrity sha512-9xH0HoNhXsB1egPOAgBf2W2MLFRUyvNcK8ZbBUOdaiKHQ+0Fu3oFMJAY7fPSaPEm0l8m6bIzoob8z4loRTnQlA== +"@toruslabs/base-controllers@^5.10.0": + version "5.11.0" + resolved "https://registry.npmjs.org/@toruslabs/base-controllers/-/base-controllers-5.11.0.tgz" + integrity sha512-5AsGOlpf3DRIsd6PzEemBoRq+o2OhgSFXj5LZD6gXcBlfe0OpF+ydJb7Q8rIt5wwpQLNJCs8psBUbqIv7ukD2w== dependencies: "@ethereumjs/util" "^9.0.3" - "@metamask/rpc-errors" "^6.2.1" "@toruslabs/broadcast-channel" "^10.0.2" "@toruslabs/http-helpers" "^6.1.1" - "@toruslabs/openlogin-jrpc" "^8.1.1" - "@toruslabs/openlogin-utils" "^8.1.2" + "@toruslabs/openlogin-jrpc" "^8.3.0" + "@toruslabs/openlogin-utils" "^8.2.1" async-mutex "^0.5.0" bignumber.js "^9.1.2" bowser "^2.11.0" jwt-decode "^4.0.0" - lodash "^4.17.21" loglevel "^1.9.1" "@toruslabs/base-session-manager@^3.1.1": @@ -5265,12 +5227,11 @@ pump "^3.0.0" readable-stream "^4.5.2" -"@toruslabs/openlogin-jrpc@^8.1.1": - version "8.1.1" - resolved "https://registry.npmjs.org/@toruslabs/openlogin-jrpc/-/openlogin-jrpc-8.1.1.tgz" - integrity sha512-SGuFHWLPDbnfexe/t2dcwZT06N8k8NNkWJF+Y8eHqK4k0jgVNauIrs3wK0dshlLtgQKDQFFsqdQlWNVa7cLz6w== +"@toruslabs/openlogin-jrpc@^8.3.0": + version "8.3.0" + resolved "https://registry.npmjs.org/@toruslabs/openlogin-jrpc/-/openlogin-jrpc-8.3.0.tgz" + integrity sha512-1OdSkUXGXJobkkMIJHuf+XzwmUB4ROy6uQfPEJ3NXvNj84+N4hNpvC4JPg7VoWBHdfCba9cv6QnQsVArlwai4A== dependencies: - "@metamask/rpc-errors" "^6.2.1" end-of-stream "^1.4.4" events "^3.3.0" fast-safe-stringify "^2.1.1" @@ -5303,10 +5264,10 @@ "@toruslabs/constants" "^13.1.0" base64url "^3.0.1" -"@toruslabs/openlogin-utils@^8.1.2": - version "8.1.2" - resolved "https://registry.npmjs.org/@toruslabs/openlogin-utils/-/openlogin-utils-8.1.2.tgz" - integrity sha512-UpSb/ubgmu6N8O0wq06ZnUP3NOju8ZBMbVQK/CmbCP2Tba3S5eqvLaHE+7/FBWFeb+szEYX4FTgshEviUvlHjg== +"@toruslabs/openlogin-utils@^8.2.1": + version "8.2.1" + resolved "https://registry.npmjs.org/@toruslabs/openlogin-utils/-/openlogin-utils-8.2.1.tgz" + integrity sha512-NSOtj61NZe7w9qbd92cYwMlE/1UwPGtDH02NfUjoEEc3p1yD5U2cLZjdSwsnAgjGNgRqVomXpND4hii12lI/ew== dependencies: "@toruslabs/constants" "^13.2.0" base64url "^3.0.1" @@ -5327,16 +5288,16 @@ loglevel "^1.8.1" ts-custom-error "^3.3.1" -"@toruslabs/openlogin@^8.1.2": - version "8.1.2" - resolved "https://registry.npmjs.org/@toruslabs/openlogin/-/openlogin-8.1.2.tgz" - integrity sha512-EHdbs4o4i4xu87IdLgd+EwZz9P6+VrxEF28z1cHE/4yq8toqr+Mdbv65Ab8RKMvJ2EFYL3XgRB+aEQQfFbGOPA== +"@toruslabs/openlogin@^8.2.1": + version "8.2.1" + resolved "https://registry.npmjs.org/@toruslabs/openlogin/-/openlogin-8.2.1.tgz" + integrity sha512-2X1s6dg8PhF/eXjKChkEHhKNO27gx7pjdUD7moMwu+YNm3+SJWJtt+bJWNbHIvWKHcCsms7nC8Pn3RZ8arOEQg== dependencies: "@toruslabs/constants" "^13.2.0" "@toruslabs/eccrypto" "^4.0.0" "@toruslabs/metadata-helpers" "^5.1.0" "@toruslabs/openlogin-session-manager" "^3.1.1" - "@toruslabs/openlogin-utils" "^8.1.2" + "@toruslabs/openlogin-utils" "^8.2.1" "@toruslabs/secure-pub-sub" "^0.2.0" bowser "^2.11.0" events "^3.3.0" @@ -5532,7 +5493,7 @@ resolved "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz" integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA== -"@types/hoist-non-react-statics@*", "@types/hoist-non-react-statics@^3.3.1": +"@types/hoist-non-react-statics@*": version "3.3.1" resolved "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz" integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== @@ -5650,9 +5611,9 @@ integrity sha512-esIJx9bQg+QYF0ra8GnvfianIY8qWB0GBx54PK5Eps6m+xTj86KLavHv6qDhzKcu5UUOgNfJ2pWaIIV7TRUd9Q== "@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + version "4.0.2" + resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz" + integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== "@types/pbkdf2@^3.0.0": version "3.1.2" @@ -5661,19 +5622,35 @@ dependencies: "@types/node" "*" -"@types/prop-types@*", "@types/prop-types@^15.7.11": - version "15.7.11" - resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz" - integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng== +"@types/prop-types@*", "@types/prop-types@^15.7.12": + version "15.7.12" + resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz" + integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q== + +"@types/react-dom@^18.3.0": + version "18.3.0" + resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz" + integrity sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg== + dependencies: + "@types/react" "*" + +"@types/react-modal@^3.16.3": + version "3.16.3" + resolved "https://registry.npmjs.org/@types/react-modal/-/react-modal-3.16.3.tgz" + integrity sha512-xXuGavyEGaFQDgBv4UVm8/ZsG+qxeQ7f77yNrW3n+1J6XAstUy5rYHeIHPh1KzsGc6IkCIdu6lQ2xWzu1jBTLg== + dependencies: + "@types/react" "*" -"@types/react-dom@^16.8 || ^17.0 || ^18.0", "@types/react-dom@^18.2.15": - version "18.2.18" - resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.18.tgz" - integrity sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw== +"@types/react-router-dom@^5.3.3": + version "5.3.3" + resolved "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz" + integrity sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw== dependencies: + "@types/history" "^4.7.11" "@types/react" "*" + "@types/react-router" "*" -"@types/react-router@^5.1.20": +"@types/react-router@*": version "5.1.20" resolved "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz" integrity sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q== @@ -5681,7 +5658,7 @@ "@types/history" "^4.7.11" "@types/react" "*" -"@types/react-slick@^0.23.12": +"@types/react-slick@^0.23.13": version "0.23.13" resolved "https://registry.npmjs.org/@types/react-slick/-/react-slick-0.23.13.tgz" integrity sha512-bNZfDhe/L8t5OQzIyhrRhBr/61pfBcWaYJoq6UDqFtv5LMwfg4NsVDD2J8N01JqdAdxLjOt66OZEp6PX+dGs/A== @@ -5695,16 +5672,24 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^16.8 || ^17.0 || ^18.0", "@types/react@^16.8.0 || ^17.0.0", "@types/react@^16.8.0 || ^17.0.0 || ^18.0.0", "@types/react@^16.9.0 || ^17.0.0 || ^18.0.0", "@types/react@^17.0.0 || ^18.0.0", "@types/react@^18.2.43", "@types/react@^18.2.6", "@types/react@>=16.8": - version "18.2.46" - resolved "https://registry.npmjs.org/@types/react/-/react-18.2.46.tgz" - integrity sha512-nNCvVBcZlvX4NU1nRRNV/mFl1nNRuTuslAJglQsq+8ldXe5Xv0Wd2f7WTE3jOxhLH2BFfiZGC6GCp+kHQbgG+w== +"@types/react@*", "@types/react@^16.8.0 || ^17.0.0 || ^18.0.0", "@types/react@^16.9.0 || ^17.0.0 || ^18.0.0", "@types/react@^17.0.0 || ^18.0.0", "@types/react@^18.2.25", "@types/react@^18.2.6", "@types/react@^18.3.4", "@types/react@>=16.8": + version "18.3.4" + resolved "https://registry.npmjs.org/@types/react/-/react-18.3.4.tgz" + integrity sha512-J7W30FTdfCxDDjmfRM+/JqLHBIyl7xUIp9kwK637FGmY7+mkSFSe6L4jpZzhj5QMfLssSDP4/i75AKkrdC7/Jw== + dependencies: + "@types/prop-types" "*" + csstype "^3.0.2" + +"@types/react@^16.8.0 || ^17.0.0": + version "17.0.80" + resolved "https://registry.npmjs.org/@types/react/-/react-17.0.80.tgz" + integrity sha512-LrgHIu2lEtIo8M7d1FcI3BdwXWoRQwMoXOZ7+dPTW0lYREjmlHl3P0U1VD0i/9tppOuv8/sam7sOjx34TxSFbA== dependencies: "@types/prop-types" "*" - "@types/scheduler" "*" + "@types/scheduler" "^0.16" csstype "^3.0.2" -"@types/scheduler@*": +"@types/scheduler@^0.16": version "0.16.2" resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz" integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== @@ -5743,7 +5728,7 @@ resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz" integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== -"@types/styled-components@^5.1.32": +"@types/styled-components@^5.1.34": version "5.1.34" resolved "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.34.tgz" integrity sha512-mmiVvwpYklFIv9E8qfxuPyIt/OuyIrn6gMOAMOFUO3WJfSrSE+sGUoa4PiZj77Ut7bKZpaa6o1fBKS/4TOEvnA== @@ -5752,6 +5737,11 @@ "@types/react" "*" csstype "^3.0.2" +"@types/stylis@4.2.5": + version "4.2.5" + resolved "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz" + integrity sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw== + "@types/trusted-types@^2.0.2": version "2.0.7" resolved "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz" @@ -5762,10 +5752,10 @@ resolved "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz" integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA== -"@types/uuid@^9.0.7": - version "9.0.7" - resolved "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz" - integrity sha512-WUtIVRUZ9i5dYXefDEAI7sh9/O7jGvHg7Df/5O/gtH3Yabe5odI3UWopVR1qbPXQtvOxWu3mM4XxlYeZtMWF4g== +"@types/uuid@^10.0.0": + version "10.0.0" + resolved "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz" + integrity sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ== "@types/uuid@8.3.4": version "8.3.4" @@ -5970,10 +5960,10 @@ mux.js "6.0.1" video.js "^6 || ^7" -"@videojs/http-streaming@3.10.0": - version "3.10.0" - resolved "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.10.0.tgz" - integrity sha512-Lf1rmhTalV4Gw0bJqHmH4lfk/FlepUDs9smuMtorblAYnqDlE2tbUOb7sBXVYoXGdbWbdTW8jH2cnS+6HWYJ4Q== +"@videojs/http-streaming@3.13.2": + version "3.13.2" + resolved "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-3.13.2.tgz" + integrity sha512-eCfQp61w00hg7Y9npmLnsJ6UvDF+SsFYzu7mQJgVXxWpVm9AthYWA3KQEKA7F7Sy6yzlm/Sps8BHs5ItelNZgQ== dependencies: "@babel/runtime" "^7.12.5" "@videojs/vhs-utils" "4.0.0" @@ -5981,7 +5971,7 @@ global "^4.4.0" m3u8-parser "^7.1.0" mpd-parser "^1.3.0" - mux.js "7.0.2" + mux.js "7.0.3" video.js "^7 || ^8" "@videojs/vhs-utils@^3.0.4", "@videojs/vhs-utils@^3.0.5", "@videojs/vhs-utils@3.0.5": @@ -6002,6 +5992,14 @@ global "^4.4.0" url-toolkit "^2.2.1" +"@videojs/vhs-utils@^4.1.1": + version "4.1.1" + resolved "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-4.1.1.tgz" + integrity sha512-5iLX6sR2ownbv4Mtejw6Ax+naosGvoT9kY+gcuHzANyUZZ+4NpeNdKMUhb6ag0acYej1Y7cmr/F2+4PrggMiVA== + dependencies: + "@babel/runtime" "^7.12.5" + global "^4.4.0" + "@videojs/xhr@2.6.0": version "2.6.0" resolved "https://registry.npmjs.org/@videojs/xhr/-/xhr-2.6.0.tgz" @@ -6011,16 +6009,25 @@ global "~4.4.0" is-function "^1.0.1" -"@vitejs/plugin-react@^4.2.0": - version "4.2.1" - resolved "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.2.1.tgz" - integrity sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ== +"@videojs/xhr@2.7.0": + version "2.7.0" + resolved "https://registry.npmjs.org/@videojs/xhr/-/xhr-2.7.0.tgz" + integrity sha512-giab+EVRanChIupZK7gXjHy90y3nncA2phIOyG3Ne5fvpiMJzvqYwiTOnEVW2S4CoYcuKJkomat7bMXA/UoUZQ== + dependencies: + "@babel/runtime" "^7.5.5" + global "~4.4.0" + is-function "^1.0.1" + +"@vitejs/plugin-react@^4.3.1": + version "4.3.1" + resolved "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.1.tgz" + integrity sha512-m/V2syj5CuVnaxcUJOQRel/Wr31FFXRFlnOoq1TVtkCxsY5veGMTEmpWHndrhB2U8ScHtCQB1e+4hWYExQc6Lg== dependencies: - "@babel/core" "^7.23.5" - "@babel/plugin-transform-react-jsx-self" "^7.23.3" - "@babel/plugin-transform-react-jsx-source" "^7.23.3" + "@babel/core" "^7.24.5" + "@babel/plugin-transform-react-jsx-self" "^7.24.5" + "@babel/plugin-transform-react-jsx-source" "^7.24.1" "@types/babel__core" "^7.20.5" - react-refresh "^0.14.0" + react-refresh "^0.14.2" "@wagmi/chains@^1.8.0": version "1.8.0" @@ -6146,6 +6153,29 @@ lodash.isequal "4.5.0" uint8arrays "3.1.0" +"@walletconnect/core@2.14.0": + version "2.14.0" + resolved "https://registry.npmjs.org/@walletconnect/core/-/core-2.14.0.tgz" + integrity sha512-E/dgBM9q3judXnTfZQ5ILvDpeSdDpabBLsXtYXa3Nyc26cfNplfLJ2nXm9FgtTdhM1nZ7yx4+zDPiXawBRZl2g== + dependencies: + "@walletconnect/heartbeat" "1.2.2" + "@walletconnect/jsonrpc-provider" "1.0.14" + "@walletconnect/jsonrpc-types" "1.0.4" + "@walletconnect/jsonrpc-utils" "1.0.8" + "@walletconnect/jsonrpc-ws-connection" "1.0.14" + "@walletconnect/keyvaluestorage" "1.1.1" + "@walletconnect/logger" "2.1.2" + "@walletconnect/relay-api" "1.0.10" + "@walletconnect/relay-auth" "1.0.4" + "@walletconnect/safe-json" "1.0.2" + "@walletconnect/time" "1.0.2" + "@walletconnect/types" "2.14.0" + "@walletconnect/utils" "2.14.0" + events "3.3.0" + isomorphic-unfetch "3.1.0" + lodash.isequal "4.5.0" + uint8arrays "3.1.0" + "@walletconnect/core@2.9.2": version "2.9.2" resolved "https://registry.npmjs.org/@walletconnect/core/-/core-2.9.2.tgz" @@ -6506,7 +6536,22 @@ dependencies: tslib "1.14.1" -"@walletconnect/sign-client@^2.10.6", "@walletconnect/sign-client@^2.x", "@walletconnect/sign-client@2.11.0": +"@walletconnect/sign-client@^2.14.0", "@walletconnect/sign-client@^2.x": + version "2.14.0" + resolved "https://registry.npmjs.org/@walletconnect/sign-client/-/sign-client-2.14.0.tgz" + integrity sha512-UrB3S3eLjPYfBLCN3WJ5u7+WcZ8kFMe/QIDqLf76Jk6TaLwkSUy563LvnSw4KW/kA+/cY1KBSdUDfX1tzYJJXg== + dependencies: + "@walletconnect/core" "2.14.0" + "@walletconnect/events" "1.0.1" + "@walletconnect/heartbeat" "1.2.2" + "@walletconnect/jsonrpc-utils" "1.0.8" + "@walletconnect/logger" "2.1.2" + "@walletconnect/time" "1.0.2" + "@walletconnect/types" "2.14.0" + "@walletconnect/utils" "2.14.0" + events "3.3.0" + +"@walletconnect/sign-client@2.11.0": version "2.11.0" resolved "https://registry.npmjs.org/@walletconnect/sign-client/-/sign-client-2.11.0.tgz" integrity sha512-H2ukscibBS+6WrzQWh+WyVBqO5z4F5et12JcwobdwgHnJSlqIoZxqnUYYWNCI5rUR5UKsKWaUyto4AE9N5dw4Q== @@ -6594,6 +6639,18 @@ "@walletconnect/logger" "2.1.2" events "3.3.0" +"@walletconnect/types@2.14.0": + version "2.14.0" + resolved "https://registry.npmjs.org/@walletconnect/types/-/types-2.14.0.tgz" + integrity sha512-vevMi4jZLJ55vLuFOicQFmBBbLyb+S0sZS4IsaBdZkQflfGIq34HkN13c/KPl4Ye0aoR4/cUcUSitmGIzEQM5g== + dependencies: + "@walletconnect/events" "1.0.1" + "@walletconnect/heartbeat" "1.2.2" + "@walletconnect/jsonrpc-types" "1.0.4" + "@walletconnect/keyvaluestorage" "1.1.1" + "@walletconnect/logger" "2.1.2" + events "3.3.0" + "@walletconnect/universal-provider@2.11.0": version "2.11.0" resolved "https://registry.npmjs.org/@walletconnect/universal-provider/-/universal-provider-2.11.0.tgz" @@ -6639,7 +6696,27 @@ "@walletconnect/utils" "2.9.2" events "^3.3.0" -"@walletconnect/utils@^2.11.0", "@walletconnect/utils@^2.x", "@walletconnect/utils@2.11.0": +"@walletconnect/utils@^2.11.0", "@walletconnect/utils@^2.14.0", "@walletconnect/utils@^2.x", "@walletconnect/utils@2.14.0": + version "2.14.0" + resolved "https://registry.npmjs.org/@walletconnect/utils/-/utils-2.14.0.tgz" + integrity sha512-vRVomYQEtEAyCK2c5bzzEvtgxaGGITF8mWuIL+WYSAMyEJLY97mirP2urDucNwcUczwxUgI+no9RiNFbUHreQQ== + dependencies: + "@stablelib/chacha20poly1305" "1.0.1" + "@stablelib/hkdf" "1.0.1" + "@stablelib/random" "1.0.2" + "@stablelib/sha256" "1.0.1" + "@stablelib/x25519" "1.0.3" + "@walletconnect/relay-api" "1.0.10" + "@walletconnect/safe-json" "1.0.2" + "@walletconnect/time" "1.0.2" + "@walletconnect/types" "2.14.0" + "@walletconnect/window-getters" "1.0.1" + "@walletconnect/window-metadata" "1.0.1" + detect-browser "5.3.0" + query-string "7.1.3" + uint8arrays "3.1.0" + +"@walletconnect/utils@2.11.0": version "2.11.0" resolved "https://registry.npmjs.org/@walletconnect/utils/-/utils-2.11.0.tgz" integrity sha512-hxkHPlTlDQILHfIKXlmzgNJau/YcSBC3XHUSuZuKZbNEw3duFT6h6pm3HT/1+j1a22IG05WDsNBuTCRkwss+BQ== @@ -6739,15 +6816,14 @@ "@web3auth/base" "^7.3.2" json-rpc-random-id "^1.0.1" -"@web3auth/base-provider@^8.6.2": - version "8.6.2" - resolved "https://registry.npmjs.org/@web3auth/base-provider/-/base-provider-8.6.2.tgz" - integrity sha512-uphrD/sBBVVO4mhDFAXnDlXIjHAwysohqXrqh9lnoynLBH06/nIuG2TFGPKnonCcaS3SVe06F/h0jZdeQACJOQ== +"@web3auth/base-provider@^8.12.4": + version "8.12.4" + resolved "https://registry.npmjs.org/@web3auth/base-provider/-/base-provider-8.12.4.tgz" + integrity sha512-LXhc0h/EG9FWGg86+CiLOi2XyZl9rm/fzJmuX8aP7bQbGz+TfbtSIX+0hZvYTAXJnj7vcHCMUj+hwh8hKn6W0A== dependencies: - "@metamask/rpc-errors" "^6.2.1" - "@toruslabs/base-controllers" "^5.7.0" - "@toruslabs/openlogin-jrpc" "^8.1.1" - "@web3auth/base" "^8.6.2" + "@toruslabs/base-controllers" "^5.10.0" + "@toruslabs/openlogin-jrpc" "^8.3.0" + "@web3auth/base" "^8.12.4" json-rpc-random-id "^1.0.1" "@web3auth/base-solana-adapter@^7.3.2": @@ -6771,16 +6847,16 @@ loglevel "^1.8.1" ts-custom-error "^3.3.1" -"@web3auth/base@^8.6.2": - version "8.6.2" - resolved "https://registry.npmjs.org/@web3auth/base/-/base-8.6.2.tgz" - integrity sha512-aB/yjkQIWAUg1nge+Mq2lP32hlLjJ+NmIDwWU9VIW5kSs3Ngf3W0I9iK1rV8+tPh/1T5gwMpGXG8flYPulMWdw== +"@web3auth/base@^8.12.4": + version "8.12.4" + resolved "https://registry.npmjs.org/@web3auth/base/-/base-8.12.4.tgz" + integrity sha512-RyHF3KZ0SwTglj1CSPo1tp3s9dZKqaDwvmCN48wgJsC288tAFGvZyqFTqeM10WX56OwUcLBrRl4w7oHpYJ8uXg== dependencies: "@toruslabs/constants" "^13.4.0" "@toruslabs/http-helpers" "^6.1.1" - "@toruslabs/openlogin" "^8.1.2" - "@toruslabs/openlogin-jrpc" "^8.1.1" - "@toruslabs/openlogin-utils" "^8.1.2" + "@toruslabs/openlogin" "^8.2.1" + "@toruslabs/openlogin-jrpc" "^8.3.0" + "@toruslabs/openlogin-utils" "^8.2.1" jwt-decode "^4.0.0" loglevel "^1.9.1" ts-custom-error "^3.3.1" @@ -6833,16 +6909,16 @@ "@web3auth/ui" "^7.3.2" "@web3auth/wallet-connect-v2-adapter" "^7.3.2" -"@web3auth/modal@^8.6.2": - version "8.6.2" - resolved "https://registry.npmjs.org/@web3auth/modal/-/modal-8.6.2.tgz" - integrity sha512-pMBu7QH+6CPiL0IuV26ewhU0Enjv/V8fiZxGSAFkG+OUUQNsSlQ+bhHsyg7YblXalh50WRGj68s7Bh9GyT1LjA== +"@web3auth/modal@^8.12.4": + version "8.12.4" + resolved "https://registry.npmjs.org/@web3auth/modal/-/modal-8.12.4.tgz" + integrity sha512-t8ULe0I4O12M2QfysKnTkE+AoAwqJ4J4rVRb+3SElmTv2N6vJF51pPgyaKZaDqZrooG6ApcuNdHvWGacECNmYg== dependencies: - "@web3auth/base" "^8.6.2" - "@web3auth/base-provider" "^8.6.2" - "@web3auth/no-modal" "^8.6.2" - "@web3auth/openlogin-adapter" "^8.6.2" - "@web3auth/ui" "^8.6.2" + "@web3auth/base" "^8.12.4" + "@web3auth/base-provider" "^8.12.4" + "@web3auth/no-modal" "^8.12.4" + "@web3auth/openlogin-adapter" "^8.12.4" + "@web3auth/ui" "^8.12.4" lodash.clonedeep "^4.5.0" lodash.merge "^4.6.2" @@ -6858,16 +6934,16 @@ "@web3auth/base-plugin" "^7.3.2" "@web3auth/base-provider" "^7.3.2" -"@web3auth/no-modal@^8.6.2": - version "8.6.2" - resolved "https://registry.npmjs.org/@web3auth/no-modal/-/no-modal-8.6.2.tgz" - integrity sha512-6CzDQ6gEvNL8pRLTgLFOEDtM0dLc83cSF5f8Ic0jzhtuU4TqDr1G3vexRp8YoPKjMOnttCY6viPWKXug8/fzAQ== +"@web3auth/no-modal@^8.12.4": + version "8.12.4" + resolved "https://registry.npmjs.org/@web3auth/no-modal/-/no-modal-8.12.4.tgz" + integrity sha512-iJj3qXGB1exnOSaJ+8iSNbvfsvubefu+1G+vt1iiiinX0zKX0OGJM1zR5XQsdtwPpgzZHYiA57RLxiSGxKtB1g== dependencies: - "@toruslabs/openlogin" "^8.1.2" - "@toruslabs/openlogin-jrpc" "^8.1.1" - "@toruslabs/openlogin-utils" "^8.1.2" - "@web3auth/base" "^8.6.2" - "@web3auth/base-provider" "^8.6.2" + "@toruslabs/openlogin" "^8.2.1" + "@toruslabs/openlogin-jrpc" "^8.3.0" + "@toruslabs/openlogin-utils" "^8.2.1" + "@web3auth/base" "^8.12.4" + "@web3auth/base-provider" "^8.12.4" lodash.clonedeep "^4.5.0" lodash.merge "^4.6.2" @@ -6882,15 +6958,15 @@ "@web3auth/base-provider" "^7.3.2" lodash.merge "^4.6.2" -"@web3auth/openlogin-adapter@^8.6.2", "@web3auth/openlogin-adapter@^8.x": - version "8.6.2" - resolved "https://registry.npmjs.org/@web3auth/openlogin-adapter/-/openlogin-adapter-8.6.2.tgz" - integrity sha512-Nv3fJfk3Pby4fLcrKnfZKn9sMT7S5wlWgnIvOJl7JqiGfjentCeFIrqNry4fpQVdWIHrYxqFuOG2xP/TTpIj5w== +"@web3auth/openlogin-adapter@^8.12.4", "@web3auth/openlogin-adapter@^8.x": + version "8.12.4" + resolved "https://registry.npmjs.org/@web3auth/openlogin-adapter/-/openlogin-adapter-8.12.4.tgz" + integrity sha512-bxvq6hwzbgkaYOXxzJPJmhPrBoQTxBhVdgMqPLGkvQT2Izg8IV+uic+xOfjp4Ng663N3l2HV4yx0qCqdYCHj/w== dependencies: - "@toruslabs/openlogin" "^8.1.2" - "@toruslabs/openlogin-utils" "^8.1.2" - "@web3auth/base" "^8.6.2" - "@web3auth/base-provider" "^8.6.2" + "@toruslabs/openlogin" "^8.2.1" + "@toruslabs/openlogin-utils" "^8.2.1" + "@web3auth/base" "^8.12.4" + "@web3auth/base-provider" "^8.12.4" lodash.merge "^4.6.2" "@web3auth/phantom-adapter@^7.3.2": @@ -6959,24 +7035,24 @@ react-i18next "^13.5.0" react-qrcode-logo "^2.9.0" -"@web3auth/ui@^8.6.2": - version "8.6.2" - resolved "https://registry.npmjs.org/@web3auth/ui/-/ui-8.6.2.tgz" - integrity sha512-tizk/Kg9BV2ffOMZ/XF+Ya85LIl1mtKIAYnxcVXaDR8KqlxF8CExqBExvTBqVgy0x7QVydBkSBfmZi1KDQ9CUg== +"@web3auth/ui@^8.12.4": + version "8.12.4" + resolved "https://registry.npmjs.org/@web3auth/ui/-/ui-8.12.4.tgz" + integrity sha512-j06lpgGbCocMQI1cGop+h417lBPFE4RZDfNaX/uu2P/TF6g5BlH2Rz3Id24ubka3nVzOH/T4oLJLWQM/DYDs0w== dependencies: "@toruslabs/http-helpers" "^6.1.1" - "@toruslabs/openlogin" "^8.1.2" - "@toruslabs/openlogin-jrpc" "^8.1.1" - "@toruslabs/openlogin-utils" "^8.1.2" - "@web3auth/base" "^8.6.2" + "@toruslabs/openlogin" "^8.2.1" + "@toruslabs/openlogin-jrpc" "^8.3.0" + "@toruslabs/openlogin-utils" "^8.2.1" + "@web3auth/base" "^8.12.4" bowser "^2.11.0" classnames "^2.5.1" copy-to-clipboard "^3.3.3" - i18next "^23.11.5" + i18next "^23.12.2" lodash.clonedeep "^4.5.0" lodash.merge "^4.6.2" - react-i18next "^14.1.2" - react-qrcode-logo "^2.10.0" + react-i18next "^15.0.1" + react-qrcode-logo "^3.0.0" "@web3auth/wallet-connect-v2-adapter@^7.3.2": version "7.3.2" @@ -7031,6 +7107,11 @@ abitype@1.0.0: resolved "https://registry.npmjs.org/abitype/-/abitype-1.0.0.tgz" integrity sha512-NMeMah//6bJ56H5XRj8QCV4AwuW6hB6zqz2LnhhLdcWVQOsXki6/Pn3APeqxCma62nXIcmZWdu1DlHWS74umVQ== +abitype@1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/abitype/-/abitype-1.0.5.tgz" + integrity sha512-YzDhti7cjlfaBhHutMaboYB21Ha3rXR9QTkNJFzYC4kC8YclaiwPBBBJY8ejFdu2wnJeZCVZSMlQJ7fi8S6hsw== + abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz" @@ -7061,13 +7142,13 @@ acorn-jsx@^5.3.2: resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz" integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== -aes-decrypter@^4.0.1, aes-decrypter@4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/aes-decrypter/-/aes-decrypter-4.0.1.tgz" - integrity sha512-H1nh/P9VZXUf17AA5NQfJML88CFjVBDuGkp5zDHa7oEhYN9TTpNLJknRY1ie0iSKWlDf6JRnJKaZVDSQdPy6Cg== +aes-decrypter@^4.0.1: + version "4.0.2" + resolved "https://registry.npmjs.org/aes-decrypter/-/aes-decrypter-4.0.2.tgz" + integrity sha512-lc+/9s6iJvuaRe5qDlMTpCFjnwpkeOXp8qP3oiZ5jsj1MRg+SBVUmmICrhxHvc8OELSmc+fEyyxAuppY6hrWzw== dependencies: "@babel/runtime" "^7.12.5" - "@videojs/vhs-utils" "^3.0.5" + "@videojs/vhs-utils" "^4.1.1" global "^4.4.0" pkcs7 "^1.0.4" @@ -7081,6 +7162,16 @@ aes-decrypter@3.1.3: global "^4.4.0" pkcs7 "^1.0.4" +aes-decrypter@4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/aes-decrypter/-/aes-decrypter-4.0.1.tgz" + integrity sha512-H1nh/P9VZXUf17AA5NQfJML88CFjVBDuGkp5zDHa7oEhYN9TTpNLJknRY1ie0iSKWlDf6JRnJKaZVDSQdPy6Cg== + dependencies: + "@babel/runtime" "^7.12.5" + "@videojs/vhs-utils" "^3.0.5" + global "^4.4.0" + pkcs7 "^1.0.4" + aes-js@^3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz" @@ -7120,10 +7211,10 @@ ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -alchemy-sdk@^3.0.0, alchemy-sdk@^3.2.0: - version "3.2.0" - resolved "https://registry.npmjs.org/alchemy-sdk/-/alchemy-sdk-3.2.0.tgz" - integrity sha512-evhxyEnRGQo2Il88vTA4ENvebUbmuk9KzjE2GkF/pwzDnhMv1QIEV6BxU9GCerV8wlHwjohZ0pLS7AkS7QdvBw== +alchemy-sdk@^3.0.0, alchemy-sdk@^3.4.1: + version "3.4.1" + resolved "https://registry.npmjs.org/alchemy-sdk/-/alchemy-sdk-3.4.1.tgz" + integrity sha512-GeL8J6VIiE7tIgXevkcm0VqdZnhO0EpOXQQCzUMsoMrj92hBKj9ZmUjyPxXF8tUdsHYixQApng2eJXoRWmv5lw== dependencies: "@ethersproject/abi" "^5.7.0" "@ethersproject/abstract-provider" "^5.7.0" @@ -7136,7 +7227,7 @@ alchemy-sdk@^3.0.0, alchemy-sdk@^3.2.0: "@ethersproject/units" "^5.7.0" "@ethersproject/wallet" "^5.7.0" "@ethersproject/web" "^5.7.0" - axios "^1.6.5" + axios "^1.7.4" sturdy-websocket "^0.2.1" websocket "^1.0.34" @@ -7148,12 +7239,12 @@ analytics-utils@^1.0.12: "@analytics/type-utils" "^0.6.2" dlv "^1.1.3" -analytics@^0.8.9: - version "0.8.9" - resolved "https://registry.npmjs.org/analytics/-/analytics-0.8.9.tgz" - integrity sha512-oTbUzQpncMTslakqfK70GgB6bopk5hY+uuekwnadMkDyqNLgcD02KRzteTnO7q5Ko6wDECVtT8xi/6OuAMZykA== +analytics@^0.8.14: + version "0.8.14" + resolved "https://registry.npmjs.org/analytics/-/analytics-0.8.14.tgz" + integrity sha512-ZKpqWHEHBrN0lvIsrUKmt0fcXNyQuKa0JUWDRAz7LgJ+Sf4ZX+a66/ai28W4H8kJJlLeItCrhIi/xvdbV08RlA== dependencies: - "@analytics/core" "^0.12.7" + "@analytics/core" "^0.12.15" "@analytics/storage-utils" "^0.4.2" anser@^1.4.9: @@ -7266,23 +7357,24 @@ aria-hidden@^1.1.1: dependencies: tslib "^2.0.0" -array-buffer-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz" - integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== +array-buffer-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz" + integrity sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg== dependencies: - call-bind "^1.0.2" - is-array-buffer "^3.0.1" + call-bind "^1.0.5" + is-array-buffer "^3.0.4" -array-includes@^3.1.5, array-includes@^3.1.6: - version "3.1.7" - resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz" - integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== +array-includes@^3.1.5, array-includes@^3.1.8: + version "3.1.8" + resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz" + integrity sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" + get-intrinsic "^1.2.4" is-string "^1.0.7" array-union@^2.1.0: @@ -7290,7 +7382,19 @@ array-union@^2.1.0: resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -array.prototype.flatmap@^1.3.1: +array.prototype.findlast@^1.2.5: + version "1.2.5" + resolved "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz" + integrity sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + es-shim-unscopables "^1.0.2" + +array.prototype.flatmap@^1.3.2: version "1.3.2" resolved "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz" integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== @@ -7300,29 +7404,30 @@ array.prototype.flatmap@^1.3.1: es-abstract "^1.22.1" es-shim-unscopables "^1.0.0" -array.prototype.tosorted@^1.1.1: - version "1.1.2" - resolved "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz" - integrity sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg== +array.prototype.tosorted@^1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz" + integrity sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - get-intrinsic "^1.2.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.3" + es-errors "^1.3.0" + es-shim-unscopables "^1.0.2" -arraybuffer.prototype.slice@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz" - integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== +arraybuffer.prototype.slice@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz" + integrity sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A== dependencies: - array-buffer-byte-length "^1.0.0" - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - is-array-buffer "^3.0.2" - is-shared-array-buffer "^1.0.2" + array-buffer-byte-length "^1.0.1" + call-bind "^1.0.5" + define-properties "^1.2.1" + es-abstract "^1.22.3" + es-errors "^1.2.1" + get-intrinsic "^1.2.3" + is-array-buffer "^3.0.4" + is-shared-array-buffer "^1.0.2" asap@~2.0.6: version "2.0.6" @@ -7388,13 +7493,6 @@ async-mutex@^0.5.0: dependencies: tslib "^2.4.0" -asynciterator.prototype@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz" - integrity sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg== - dependencies: - has-symbols "^1.0.3" - asynckit@^0.4.0: version "0.4.0" resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" @@ -7410,10 +7508,12 @@ attr-accept@^2.2.2: resolved "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz" integrity sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg== -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== +available-typed-arrays@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz" + integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== + dependencies: + possible-typed-array-names "^1.0.0" axios@^0.21.2: version "0.21.4" @@ -7430,12 +7530,12 @@ axios@^0.27.2: follow-redirects "^1.14.9" form-data "^4.0.0" -axios@^1.3.6, axios@^1.6.2, axios@^1.6.5: - version "1.6.7" - resolved "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz" - integrity sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA== +axios@^1.3.6, axios@^1.6.2, axios@^1.7.4, axios@^1.7.5: + version "1.7.5" + resolved "https://registry.npmjs.org/axios/-/axios-1.7.5.tgz" + integrity sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw== dependencies: - follow-redirects "^1.15.4" + follow-redirects "^1.15.6" form-data "^4.0.0" proxy-from-env "^1.1.0" @@ -7448,12 +7548,12 @@ axios@1.4.0: form-data "^4.0.0" proxy-from-env "^1.1.0" -axios@1.6.2: - version "1.6.2" - resolved "https://registry.npmjs.org/axios/-/axios-1.6.2.tgz" - integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A== +axios@1.6.5: + version "1.6.5" + resolved "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz" + integrity sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg== dependencies: - follow-redirects "^1.15.0" + follow-redirects "^1.15.4" form-data "^4.0.0" proxy-from-env "^1.1.0" @@ -7495,17 +7595,6 @@ babel-plugin-polyfill-regenerator@^0.6.1: dependencies: "@babel/helper-define-polyfill-provider" "^0.6.2" -"babel-plugin-styled-components@>= 1.12.0": - version "2.1.4" - resolved "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.1.4.tgz" - integrity sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-module-imports" "^7.22.5" - "@babel/plugin-syntax-jsx" "^7.22.5" - lodash "^4.17.21" - picomatch "^2.3.1" - babel-plugin-transform-flow-enums@^0.0.2: version "0.0.2" resolved "https://registry.npmjs.org/babel-plugin-transform-flow-enums/-/babel-plugin-transform-flow-enums-0.0.2.tgz" @@ -7777,7 +7866,7 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^4.22.2, browserslist@^4.23.0, "browserslist@>= 4.21.0": +browserslist@^4.23.0, browserslist@^4.23.1, "browserslist@>= 4.21.0": version "4.23.1" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz" integrity sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw== @@ -7878,14 +7967,16 @@ bytes@3.0.0: resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz" integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== -call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz" - integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz" + integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== dependencies: + es-define-property "^1.0.0" + es-errors "^1.3.0" function-bind "^1.1.2" - get-intrinsic "^1.2.1" - set-function-length "^1.1.1" + get-intrinsic "^1.2.4" + set-function-length "^1.2.1" caller-callsite@^2.0.0: version "2.0.0" @@ -7927,9 +8018,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== camelize@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz" - integrity sha512-W2lPwkBkMZwFlPCXhIlYgxu+7gC/NUlCtdK652DAJ1JdgV0sTrvuPFshNPrFa1TY2JOkLhgdeEBplB4ezEa+xg== + version "1.0.1" + resolved "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz" + integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ== caniuse-lite@^1.0.30001629: version "1.0.30001636" @@ -8122,10 +8213,10 @@ clsx@^1.2.1: resolved "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz" integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== -clsx@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz" - integrity sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg== +clsx@^2.0.0, clsx@^2.1.0, clsx@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz" + integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== cluster-key-slot@^1.1.0: version "1.1.2" @@ -8265,11 +8356,9 @@ constants-browserify@^1.0.0: integrity sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ== convert-source-map@^1.5.0: - version "1.8.0" - resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz" - integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== - dependencies: - safe-buffer "~5.1.1" + version "1.9.0" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== convert-source-map@^2.0.0: version "2.0.0" @@ -8333,9 +8422,9 @@ cosmiconfig@^5.1.0: parse-json "^4.0.0" cosmiconfig@^7.0.0: - version "7.0.1" - resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz" - integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== + version "7.1.0" + resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz" + integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== dependencies: "@types/parse-json" "^4.0.0" import-fresh "^3.2.1" @@ -8474,10 +8563,10 @@ css-in-js-utils@^3.1.0: dependencies: hyphenate-style-name "^1.0.3" -css-to-react-native@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz" - integrity sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ== +css-to-react-native@3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz" + integrity sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ== dependencies: camelize "^1.0.0" css-color-keywords "^1.0.0" @@ -8496,7 +8585,7 @@ cssesc@^3.0.0: resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -csstype@^3.0.10, csstype@^3.0.2, csstype@^3.1.2: +csstype@^3.0.10, csstype@^3.0.2, csstype@^3.1.2, csstype@^3.1.3, csstype@3.1.3: version "3.1.3" resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== @@ -8522,6 +8611,33 @@ dag-jose@^1.0.0: "@ipld/dag-cbor" "^6.0.3" multiformats "^9.0.2" +data-view-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz" + integrity sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +data-view-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz" + integrity sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +data-view-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz" + integrity sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-data-view "^1.0.1" + date-fns@^2.29.3: version "2.30.0" resolved "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz" @@ -8608,21 +8724,21 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" -define-data-property@^1.0.1, define-data-property@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz" - integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== +define-data-property@^1.0.1, define-data-property@^1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz" + integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== dependencies: - get-intrinsic "^1.2.1" + es-define-property "^1.0.0" + es-errors "^1.3.0" gopd "^1.0.1" - has-property-descriptors "^1.0.0" define-lazy-prop@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== -define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0, define-properties@^1.2.1: +define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz" integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== @@ -8948,86 +9064,112 @@ errorhandler@^1.5.1: accepts "~1.3.7" escape-html "~1.0.3" -es-abstract@^1.22.1: - version "1.22.3" - resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz" - integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== - dependencies: - array-buffer-byte-length "^1.0.0" - arraybuffer.prototype.slice "^1.0.2" - available-typed-arrays "^1.0.5" - call-bind "^1.0.5" - es-set-tostringtag "^2.0.1" +es-abstract@^1.17.5, es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.1, es-abstract@^1.23.2, es-abstract@^1.23.3: + version "1.23.3" + resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz" + integrity sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A== + dependencies: + array-buffer-byte-length "^1.0.1" + arraybuffer.prototype.slice "^1.0.3" + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + data-view-buffer "^1.0.1" + data-view-byte-length "^1.0.1" + data-view-byte-offset "^1.0.0" + es-define-property "^1.0.0" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + es-set-tostringtag "^2.0.3" es-to-primitive "^1.2.1" function.prototype.name "^1.1.6" - get-intrinsic "^1.2.2" - get-symbol-description "^1.0.0" + get-intrinsic "^1.2.4" + get-symbol-description "^1.0.2" globalthis "^1.0.3" gopd "^1.0.1" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" + has-property-descriptors "^1.0.2" + has-proto "^1.0.3" has-symbols "^1.0.3" - hasown "^2.0.0" - internal-slot "^1.0.5" - is-array-buffer "^3.0.2" + hasown "^2.0.2" + internal-slot "^1.0.7" + is-array-buffer "^3.0.4" is-callable "^1.2.7" - is-negative-zero "^2.0.2" + is-data-view "^1.0.1" + is-negative-zero "^2.0.3" is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" + is-shared-array-buffer "^1.0.3" is-string "^1.0.7" - is-typed-array "^1.1.12" + is-typed-array "^1.1.13" is-weakref "^1.0.2" object-inspect "^1.13.1" object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.5.1" - safe-array-concat "^1.0.1" - safe-regex-test "^1.0.0" - string.prototype.trim "^1.2.8" - string.prototype.trimend "^1.0.7" - string.prototype.trimstart "^1.0.7" - typed-array-buffer "^1.0.0" - typed-array-byte-length "^1.0.0" - typed-array-byte-offset "^1.0.0" - typed-array-length "^1.0.4" + object.assign "^4.1.5" + regexp.prototype.flags "^1.5.2" + safe-array-concat "^1.1.2" + safe-regex-test "^1.0.3" + string.prototype.trim "^1.2.9" + string.prototype.trimend "^1.0.8" + string.prototype.trimstart "^1.0.8" + typed-array-buffer "^1.0.2" + typed-array-byte-length "^1.0.1" + typed-array-byte-offset "^1.0.2" + typed-array-length "^1.0.6" unbox-primitive "^1.0.2" - which-typed-array "^1.1.13" + which-typed-array "^1.1.15" -es-iterator-helpers@^1.0.12: - version "1.0.15" - resolved "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz" - integrity sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g== +es-define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz" + integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== dependencies: - asynciterator.prototype "^1.0.0" - call-bind "^1.0.2" + get-intrinsic "^1.2.4" + +es-errors@^1.2.1, es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +es-iterator-helpers@^1.0.19: + version "1.0.19" + resolved "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz" + integrity sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw== + dependencies: + call-bind "^1.0.7" define-properties "^1.2.1" - es-abstract "^1.22.1" - es-set-tostringtag "^2.0.1" - function-bind "^1.1.1" - get-intrinsic "^1.2.1" + es-abstract "^1.23.3" + es-errors "^1.3.0" + es-set-tostringtag "^2.0.3" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" globalthis "^1.0.3" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" + has-property-descriptors "^1.0.2" + has-proto "^1.0.3" has-symbols "^1.0.3" - internal-slot "^1.0.5" + internal-slot "^1.0.7" iterator.prototype "^1.1.2" - safe-array-concat "^1.0.1" + safe-array-concat "^1.1.2" -es-set-tostringtag@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz" - integrity sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q== +es-object-atoms@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz" + integrity sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw== dependencies: - get-intrinsic "^1.2.2" - has-tostringtag "^1.0.0" - hasown "^2.0.0" + es-errors "^1.3.0" -es-shim-unscopables@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz" - integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== +es-set-tostringtag@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz" + integrity sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ== dependencies: - has "^1.0.3" + get-intrinsic "^1.2.4" + has-tostringtag "^1.0.2" + hasown "^2.0.1" + +es-shim-unscopables@^1.0.0, es-shim-unscopables@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz" + integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== + dependencies: + hasown "^2.0.0" es-to-primitive@^1.2.1: version "1.2.1" @@ -9140,50 +9282,52 @@ eslint-config-prettier@*, eslint-config-prettier@^9.1.0: resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz" integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== -eslint-plugin-prettier@^5.0.1: - version "5.1.2" - resolved "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.2.tgz" - integrity sha512-dhlpWc9vOwohcWmClFcA+HjlvUpuyynYs0Rf+L/P6/0iQE6vlHW9l5bkfzN62/Stm9fbq8ku46qzde76T1xlSg== +eslint-plugin-prettier@^5.2.1: + version "5.2.1" + resolved "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz" + integrity sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw== dependencies: prettier-linter-helpers "^1.0.0" - synckit "^0.8.6" - -eslint-plugin-react-hooks@^4.6.0: - version "4.6.0" - resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz" - integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== - -eslint-plugin-react-refresh@^0.4.4: - version "0.4.5" - resolved "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.5.tgz" - integrity sha512-D53FYKJa+fDmZMtriODxvhwrO+IOqrxoEo21gMA0sjHdU6dPVH4OhyFip9ypl8HOF5RV5KdTo+rBQLvnY2cO8w== - -eslint-plugin-react@^7.33.2: - version "7.33.2" - resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz" - integrity sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw== - dependencies: - array-includes "^3.1.6" - array.prototype.flatmap "^1.3.1" - array.prototype.tosorted "^1.1.1" + synckit "^0.9.1" + +eslint-plugin-react-hooks@^4.6.2: + version "4.6.2" + resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz" + integrity sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ== + +eslint-plugin-react-refresh@^0.4.9: + version "0.4.9" + resolved "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.9.tgz" + integrity sha512-QK49YrBAo5CLNLseZ7sZgvgTy21E6NEw22eZqc4teZfH8pxV3yXc9XXOYfUI6JNpw7mfHNkAeWtBxrTyykB6HA== + +eslint-plugin-react@^7.35.0: + version "7.35.0" + resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.0.tgz" + integrity sha512-v501SSMOWv8gerHkk+IIQBkcGRGrO2nfybfj5pLxuJNFTPxxA3PSryhXTK+9pNbtkggheDdsC0E9Q8CuPk6JKA== + dependencies: + array-includes "^3.1.8" + array.prototype.findlast "^1.2.5" + array.prototype.flatmap "^1.3.2" + array.prototype.tosorted "^1.1.4" doctrine "^2.1.0" - es-iterator-helpers "^1.0.12" + es-iterator-helpers "^1.0.19" estraverse "^5.3.0" + hasown "^2.0.2" jsx-ast-utils "^2.4.1 || ^3.0.0" minimatch "^3.1.2" - object.entries "^1.1.6" - object.fromentries "^2.0.6" - object.hasown "^1.1.2" - object.values "^1.1.6" + object.entries "^1.1.8" + object.fromentries "^2.0.8" + object.values "^1.2.0" prop-types "^15.8.1" - resolve "^2.0.0-next.4" + resolve "^2.0.0-next.5" semver "^6.3.1" - string.prototype.matchall "^4.0.8" + string.prototype.matchall "^4.0.11" + string.prototype.repeat "^1.0.0" -eslint-plugin-simple-import-sort@^10.0.0: - version "10.0.0" - resolved "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-10.0.0.tgz" - integrity sha512-AeTvO9UCMSNzIHRkg8S6c3RPy5YEwKWSQPx3DYghLedo2ZQxowPFLGDN1AZ2evfg6r6mjBSZSLxLFsWSu3acsw== +eslint-plugin-simple-import-sort@^12.1.1: + version "12.1.1" + resolved "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.1.tgz" + integrity sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA== eslint-scope@^7.2.2: version "7.2.2" @@ -9198,7 +9342,7 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -"eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.0.0 || ^8.0.0", eslint@^8.55.0, eslint@>=5.0.0, eslint@>=7, eslint@>=7.0.0, eslint@>=8.0.0: +"eslint@^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7", "eslint@^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.0.0 || ^8.0.0", eslint@^8.55.0, eslint@>=5.0.0, eslint@>=7, eslint@>=7.0.0, eslint@>=8.0.0: version "8.56.0" resolved "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz" integrity sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ== @@ -9384,6 +9528,16 @@ ethereum-cryptography@^2.0.0, ethereum-cryptography@^2.1.2, ethereum-cryptograph "@scure/bip32" "1.3.3" "@scure/bip39" "1.2.2" +ethereum-cryptography@^2.2.1: + version "2.2.1" + resolved "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz" + integrity sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg== + dependencies: + "@noble/curves" "1.4.2" + "@noble/hashes" "1.4.0" + "@scure/bip32" "1.4.0" + "@scure/bip39" "1.3.0" + ethereumjs-util@^5.2.0: version "5.2.1" resolved "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz" @@ -9408,7 +9562,56 @@ ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.5, ethereumjs-util@7.1.5: ethereum-cryptography "^0.1.3" rlp "^2.2.4" -ethers@^5.5.1, "ethers@^5.6.8 || ^6.0.8", ethers@^5.7.1, ethers@^5.7.2: +ethers@^5.5.1, ethers@^5.7.1: + version "5.7.2" + resolved "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz" + integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== + dependencies: + "@ethersproject/abi" "5.7.0" + "@ethersproject/abstract-provider" "5.7.0" + "@ethersproject/abstract-signer" "5.7.0" + "@ethersproject/address" "5.7.0" + "@ethersproject/base64" "5.7.0" + "@ethersproject/basex" "5.7.0" + "@ethersproject/bignumber" "5.7.0" + "@ethersproject/bytes" "5.7.0" + "@ethersproject/constants" "5.7.0" + "@ethersproject/contracts" "5.7.0" + "@ethersproject/hash" "5.7.0" + "@ethersproject/hdnode" "5.7.0" + "@ethersproject/json-wallets" "5.7.0" + "@ethersproject/keccak256" "5.7.0" + "@ethersproject/logger" "5.7.0" + "@ethersproject/networks" "5.7.1" + "@ethersproject/pbkdf2" "5.7.0" + "@ethersproject/properties" "5.7.0" + "@ethersproject/providers" "5.7.2" + "@ethersproject/random" "5.7.0" + "@ethersproject/rlp" "5.7.0" + "@ethersproject/sha2" "5.7.0" + "@ethersproject/signing-key" "5.7.0" + "@ethersproject/solidity" "5.7.0" + "@ethersproject/strings" "5.7.0" + "@ethersproject/transactions" "5.7.0" + "@ethersproject/units" "5.7.0" + "@ethersproject/wallet" "5.7.0" + "@ethersproject/web" "5.7.1" + "@ethersproject/wordlists" "5.7.0" + +"ethers@^5.6.8 || ^6.0.8", ethers@^6.13.2: + version "6.13.2" + resolved "https://registry.npmjs.org/ethers/-/ethers-6.13.2.tgz" + integrity sha512-9VkriTTed+/27BGuY1s0hf441kqwHJ1wtN2edksEtiRvXx+soxRX3iSXTfFqq2+YwrOqbDoTHjIhQnjJRlzKmg== + dependencies: + "@adraffy/ens-normalize" "1.10.1" + "@noble/curves" "1.2.0" + "@noble/hashes" "1.3.2" + "@types/node" "18.15.13" + aes-js "4.0.0-beta.5" + tslib "2.4.0" + ws "8.17.1" + +ethers@^5.7.2: version "5.7.2" resolved "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz" integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== @@ -9779,10 +9982,10 @@ focus-lock@^0.9.1: dependencies: tslib "^2.0.3" -follow-redirects@^1.14.0, follow-redirects@^1.14.9, follow-redirects@^1.15.0, follow-redirects@^1.15.4: - version "1.15.4" - resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz" - integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== +follow-redirects@^1.14.0, follow-redirects@^1.14.9, follow-redirects@^1.15.0, follow-redirects@^1.15.4, follow-redirects@^1.15.6: + version "1.15.6" + resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== for-each@^0.3.3: version "0.3.3" @@ -9874,12 +10077,12 @@ fsevents@^2.3.2, fsevents@~2.3.2, fsevents@~2.3.3: resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -function-bind@^1.1.1, function-bind@^1.1.2: +function-bind@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== -function.prototype.name@^1.1.5, function.prototype.name@^1.1.6: +function.prototype.name@^1.1.6: version "1.1.6" resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz" integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== @@ -9909,11 +10112,12 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5: resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: - version "1.2.2" - resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz" - integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== +get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4: + version "1.2.4" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz" + integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== dependencies: + es-errors "^1.3.0" function-bind "^1.1.2" has-proto "^1.0.1" has-symbols "^1.0.3" @@ -9944,13 +10148,14 @@ get-stream@^6.0.0: resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== +get-symbol-description@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz" + integrity sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" + call-bind "^1.0.5" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" glob-parent@^5.1.2: version "5.1.2" @@ -10048,9 +10253,9 @@ gopd@^1.0.1: get-intrinsic "^1.1.3" graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: - version "4.2.10" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + version "4.2.11" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== graphemer@^1.4.0: version "1.4.0" @@ -10094,36 +10299,29 @@ has-flag@^4.0.0: resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== +has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz" + integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== dependencies: - get-intrinsic "^1.1.1" + es-define-property "^1.0.0" -has-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz" - integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== +has-proto@^1.0.1, has-proto@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== +has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== dependencies: - function-bind "^1.1.1" + has-symbols "^1.0.3" hash-base@^3.0.0: version "3.1.0" @@ -10142,10 +10340,10 @@ hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7, hash.js@1.1.7: inherits "^2.0.3" minimalistic-assert "^1.0.1" -hasown@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz" - integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== +hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== dependencies: function-bind "^1.1.2" @@ -10194,7 +10392,7 @@ hmac-drbg@^1.0.1: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: +hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -10254,10 +10452,10 @@ humanize-ms@^1.2.1: dependencies: ms "^2.0.0" -husky@^8.0.3: - version "8.0.3" - resolved "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz" - integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg== +husky@^9.1.5: + version "9.1.5" + resolved "https://registry.npmjs.org/husky/-/husky-9.1.5.tgz" + integrity sha512-rowAVRUBfI0b4+niA4SJMhfQwc107VLkBUgEYYAOQAbqDCnra1nYh83hF/MDmhYs9t9n1E3DuKOrs2LYNC+0Ag== hyphenate-style-name@^1.0.3: version "1.0.4" @@ -10271,10 +10469,10 @@ i18next-browser-languagedetector@7.1.0: dependencies: "@babel/runtime" "^7.19.4" -i18next@^23.11.5, i18next@^23.7.16, "i18next@>= 23.2.3": - version "23.12.1" - resolved "https://registry.npmjs.org/i18next/-/i18next-23.12.1.tgz" - integrity sha512-l4y291ZGRgUhKuqVSiqyuU2DDzxKStlIWSaoNBR4grYmh0X+pRYbFpTMs3CnJ5ECKbOI8sQcJ3PbTUfLgPRaMA== +i18next@^23.12.2, i18next@^23.7.16, "i18next@>= 23.2.3": + version "23.14.0" + resolved "https://registry.npmjs.org/i18next/-/i18next-23.14.0.tgz" + integrity sha512-Y5GL4OdA8IU2geRrt2+Uc1iIhsjICdHZzT9tNwQ3TVqdNzgxHToGCKf/TPRP80vTCAP6svg2WbbJL+Gx5MFQVA== dependencies: "@babel/runtime" "^7.23.2" @@ -10319,6 +10517,11 @@ immediate@~3.0.5: resolved "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz" integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== +immer@^10.0.3, immer@>=9.0, immer@>=9.0.6: + version "10.1.1" + resolved "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz" + integrity sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw== + import-fresh@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz" @@ -10393,12 +10596,12 @@ interface-store@^3.0.0: resolved "https://registry.npmjs.org/interface-store/-/interface-store-3.0.4.tgz" integrity sha512-OjHUuGXbH4eXSBx1TF1tTySvjLldPLzRSYYXJwrEQI+XfH5JWYZofr0gVMV4F8XTwC+4V7jomDYkvGRmDSRKqQ== -internal-slot@^1.0.5: - version "1.0.6" - resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz" - integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== +internal-slot@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz" + integrity sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g== dependencies: - get-intrinsic "^1.2.2" + es-errors "^1.3.0" hasown "^2.0.0" side-channel "^1.0.4" @@ -10567,14 +10770,13 @@ is-arguments@^1.0.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz" - integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== +is-array-buffer@^3.0.4: + version "3.0.4" + resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz" + integrity sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw== dependencies: call-bind "^1.0.2" - get-intrinsic "^1.2.0" - is-typed-array "^1.1.10" + get-intrinsic "^1.2.1" is-arrayish@^0.2.1: version "0.2.1" @@ -10620,13 +10822,20 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-core-module@^2.13.0, is-core-module@^2.9.0: +is-core-module@^2.13.0: version "2.13.1" resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz" integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== dependencies: hasown "^2.0.0" +is-data-view@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz" + integrity sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w== + dependencies: + is-typed-array "^1.1.13" + is-date-object@^1.0.1, is-date-object@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" @@ -10707,10 +10916,10 @@ is-ip@^3.1.0: dependencies: ip-regex "^4.0.0" -is-map@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz" - integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== +is-map@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz" + integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw== is-nan@^1.3.2: version "1.3.2" @@ -10720,10 +10929,10 @@ is-nan@^1.3.2: call-bind "^1.0.0" define-properties "^1.1.3" -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== +is-negative-zero@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz" + integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw== is-number-object@^1.0.4: version "1.0.7" @@ -10762,17 +10971,17 @@ is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-set@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz" - integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== +is-set@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz" + integrity sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg== -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== +is-shared-array-buffer@^1.0.2, is-shared-array-buffer@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz" + integrity sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg== dependencies: - call-bind "^1.0.2" + call-bind "^1.0.7" is-stream@^2.0.0: version "2.0.1" @@ -10793,12 +11002,12 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" -is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.3, is-typed-array@^1.1.9: - version "1.1.12" - resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz" - integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== +is-typed-array@^1.1.13, is-typed-array@^1.1.3: + version "1.1.13" + resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz" + integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw== dependencies: - which-typed-array "^1.1.11" + which-typed-array "^1.1.14" is-typedarray@^1.0.0, is-typedarray@1.0.0: version "1.0.0" @@ -10810,10 +11019,10 @@ is-unicode-supported@^0.1.0: resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== -is-weakmap@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz" - integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== +is-weakmap@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz" + integrity sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w== is-weakref@^1.0.2: version "1.0.2" @@ -10822,13 +11031,13 @@ is-weakref@^1.0.2: dependencies: call-bind "^1.0.2" -is-weakset@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz" - integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== +is-weakset@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz" + integrity sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" + call-bind "^1.0.7" + get-intrinsic "^1.2.4" is-wsl@^1.1.0: version "1.1.0" @@ -10895,6 +11104,11 @@ isows@1.0.3: resolved "https://registry.npmjs.org/isows/-/isows-1.0.3.tgz" integrity sha512-2cKei4vlmg2cxEjm3wVSqn8pcoRF/LX/wpifuuNquFO4SQmPwarClT+SUCA2lt+l581tTeZIPIZuIDo2jWN1fg== +isows@1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/isows/-/isows-1.0.4.tgz" + integrity sha512-hEzjY+x9u9hPmBom9IIAqdJCwNLax+xrPb51vEPpERoFlIxgmZcHzsT5jKG06nvInKOBGvReAVz80Umed5CczQ== + it-all@^1.0.4: version "1.0.6" resolved "https://registry.npmjs.org/it-all/-/it-all-1.0.6.tgz" @@ -11377,7 +11591,7 @@ keccak@^3.0.0, keccak@^3.0.3: node-gyp-build "^4.2.0" readable-stream "^3.6.0" -keycode@^2.2.0, keycode@2.2.0: +keycode@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz" integrity sha512-ps3I9jAdNtRpJrbBvQjpzyFbss/skHqzS+eu4RxKLaEAtFqkjZaB6TZMSivPbLxf4K7VI4SjR0P5mRCX5+Q25A== @@ -11699,12 +11913,12 @@ lru-cache@^6.0.0: yallist "^4.0.0" m3u8-parser@^7.1.0: - version "7.1.0" - resolved "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-7.1.0.tgz" - integrity sha512-7N+pk79EH4oLKPEYdgRXgAsKDyA/VCo0qCHlUwacttQA0WqsjZQYmNfywMvjlY9MpEBVZEt0jKFd73Kv15EBYQ== + version "7.2.0" + resolved "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-7.2.0.tgz" + integrity sha512-CRatFqpjVtMiMaKXxNvuI3I++vUumIXVVT/JpCpdU/FynV/ceVw1qpPyyBNindL+JlPMSesx+WX1QJaZEJSaMQ== dependencies: "@babel/runtime" "^7.12.5" - "@videojs/vhs-utils" "^3.0.5" + "@videojs/vhs-utils" "^4.1.1" global "^4.4.0" m3u8-parser@4.8.0: @@ -12141,10 +12355,10 @@ mlly@^1.2.0, mlly@^1.4.2: pkg-types "^1.0.3" ufo "^1.3.0" -moment-timezone@^0.5.43: - version "0.5.44" - resolved "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.44.tgz" - integrity sha512-nv3YpzI/8lkQn0U6RkLd+f0W/zy/JnoR5/EyPz/dNkPTBjA2jNLCVxaiQ8QpeLymhSZvX0wCL5s27NQWdOPwAw== +moment-timezone@^0.5.45: + version "0.5.45" + resolved "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz" + integrity sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ== dependencies: moment "^2.29.4" @@ -12259,10 +12473,10 @@ murmurhash3js-revisited@^3.0.0: resolved "https://registry.npmjs.org/murmurhash3js-revisited/-/murmurhash3js-revisited-3.0.0.tgz" integrity sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g== -mux.js@^7.0.1, mux.js@7.0.2: - version "7.0.2" - resolved "https://registry.npmjs.org/mux.js/-/mux.js-7.0.2.tgz" - integrity sha512-CM6+QuyDbc0qW1OfEjkd2+jVKzTXF+z5VOKH0eZxtZtnrG/ilkW/U7l7IXGtBNLASF9sKZMcK1u669cq50Qq0A== +mux.js@^7.0.1, mux.js@7.0.3: + version "7.0.3" + resolved "https://registry.npmjs.org/mux.js/-/mux.js-7.0.3.tgz" + integrity sha512-gzlzJVEGFYPtl2vvEiJneSWAWD4nfYRHD5XgxmB2gWvXraMPOYk+sxfvexmNfjQUFpmk6hwLR5C6iSFmuwCHdQ== dependencies: "@babel/runtime" "^7.11.2" global "^4.4.0" @@ -12497,7 +12711,7 @@ object-hash@^3.0.0: resolved "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz" integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== -object-inspect@^1.13.1, object-inspect@^1.9.0: +object-inspect@^1.13.1: version "1.13.1" resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz" integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== @@ -12515,50 +12729,43 @@ object-keys@^1.1.1: resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object.assign@^4.1.3, object.assign@^4.1.4: - version "4.1.4" - resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== +object.assign@^4.1.3, object.assign@^4.1.4, object.assign@^4.1.5: + version "4.1.5" + resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz" + integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" + call-bind "^1.0.5" + define-properties "^1.2.1" has-symbols "^1.0.3" object-keys "^1.1.1" -object.entries@^1.1.6: - version "1.1.7" - resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz" - integrity sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -object.fromentries@^2.0.6: - version "2.0.7" - resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz" - integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== +object.entries@^1.1.8: + version "1.1.8" + resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.1.8.tgz" + integrity sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" -object.hasown@^1.1.2: - version "1.1.3" - resolved "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz" - integrity sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA== +object.fromentries@^2.0.8: + version "2.0.8" + resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz" + integrity sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ== dependencies: - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" -object.values@^1.1.6: - version "1.1.7" - resolved "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz" - integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== +object.values@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz" + integrity sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" oblivious-set@1.1.1: version "1.1.1" @@ -12987,6 +13194,11 @@ pony-cause@^2.1.10: resolved "https://registry.npmjs.org/pony-cause/-/pony-cause-2.1.10.tgz" integrity sha512-3IKLNXclQgkU++2fSi93sQ6BznFuxSLB11HdvZQ6JW/spahf/P1pAHBQEahr20rs0htZW0UDkM1HmA+nZkXKsw== +possible-typed-array-names@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz" + integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== + postcss-import@^15.1.0: version "15.1.0" resolved "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz" @@ -13031,15 +13243,24 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2: resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@^8.0.0, postcss@^8.2.14, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.39, postcss@>=8.0.9: - version "8.4.39" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz" - integrity sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw== +postcss@^8.0.0, postcss@^8.2.14, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.41, postcss@>=8.0.9: + version "8.4.41" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz" + integrity sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ== dependencies: nanoid "^3.3.7" picocolors "^1.0.1" source-map-js "^1.2.0" +postcss@8.4.38: + version "8.4.38" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz" + integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.0" + source-map-js "^1.2.0" + preact@^10.12.0, preact@^10.16.0: version "10.19.3" resolved "https://registry.npmjs.org/preact/-/preact-10.19.3.tgz" @@ -13057,10 +13278,10 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^3.1.1, prettier@>=3.0.0: - version "3.1.1" - resolved "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz" - integrity sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw== +prettier@^3.3.3, prettier@>=3.0.0: + version "3.3.3" + resolved "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz" + integrity sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew== pretty-format@^26.5.2, pretty-format@^26.6.2: version "26.6.2" @@ -13223,7 +13444,7 @@ qr.js@0.0.0: resolved "https://registry.npmjs.org/qr.js/-/qr.js-0.0.0.tgz" integrity sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ== -qrcode-generator@^1.4.1, qrcode-generator@^1.4.3: +qrcode-generator@^1.4.1, qrcode-generator@^1.4.3, qrcode-generator@^1.4.4: version "1.4.4" resolved "https://registry.npmjs.org/qrcode-generator/-/qrcode-generator-1.4.4.tgz" integrity sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw== @@ -13378,13 +13599,13 @@ react-devtools-core@^5.0.0: shell-quote "^1.6.1" ws "^7" -react-dom@*, "react-dom@^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18", "react-dom@^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.3.3 || ^17.0.0 || ^18.0.0", "react-dom@^16.6.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8 || ^17.0 || ^18.0", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || 17.x", "react-dom@^17.0.0 || ^18.0.0", react-dom@^18.0.0, react-dom@^18.2.0, react-dom@^18.x, "react-dom@>= 16.8.0", react-dom@>=16, "react-dom@>=16.14.0 <18.2.0", react-dom@>=16.2.0, react-dom@>=16.4.1, react-dom@>=16.6.0, react-dom@>=16.8, react-dom@>=16.8.0, react-dom@>=16.8.6: - version "18.2.0" - resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz" - integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== +react-dom@*, "react-dom@^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18", "react-dom@^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.3.3 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom@^16.8.0 || 17.x", "react-dom@^17.0.0 || ^18.0.0", react-dom@^18.0.0, react-dom@^18.2.0, react-dom@^18.3.1, react-dom@^18.x, "react-dom@>= 16.8.0", react-dom@>=16, "react-dom@>=16.14.0 <18.2.0", react-dom@>=16.2.0, react-dom@>=16.4.1, react-dom@>=16.6.0, react-dom@>=16.8, react-dom@>=16.8.6, react-dom@>=18.0.0: + version "18.3.1" + resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz" + integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== dependencies: loose-envify "^1.1.0" - scheduler "^0.23.0" + scheduler "^0.23.2" react-dropzone@^14.2.3: version "14.2.3" @@ -13422,19 +13643,19 @@ react-ga@^3.3.1: resolved "https://registry.npmjs.org/react-ga/-/react-ga-3.3.1.tgz" integrity sha512-4Vc0W5EvXAXUN/wWyxvsAKDLLgtJ3oLmhYYssx+YzphJpejtOst6cbIHCIyF50Fdxuf5DDKqRYny24yJ2y7GFQ== -react-helmet-async@^2.0.3: - version "2.0.4" - resolved "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-2.0.4.tgz" - integrity sha512-yxjQMWposw+akRfvpl5+8xejl4JtUlHnEBcji6u8/e6oc7ozT+P9PNTWMhCbz2y9tc5zPegw2BvKjQA+NwdEjQ== +react-helmet-async@^2.0.5: + version "2.0.5" + resolved "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-2.0.5.tgz" + integrity sha512-rYUYHeus+i27MvFE+Jaa4WsyBKGkL6qVgbJvSBoX8mbsWoABJXdEO0bZyi0F6i+4f0NuIb8AvqPMj3iXFHkMwg== dependencies: invariant "^2.2.4" react-fast-compare "^3.2.2" shallowequal "^1.1.0" -react-hook-form@^7.49.0: - version "7.49.2" - resolved "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.49.2.tgz" - integrity sha512-TZcnSc17+LPPVpMRIDNVITY6w20deMdNi6iehTFLV1x8SqThXGwu93HjlUVU09pzFgZH7qZOvLMM7UYf2ShAHA== +react-hook-form@^7.52.2: + version "7.52.2" + resolved "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.52.2.tgz" + integrity sha512-pqfPEbERnxxiNMPd0bzmt1tuaPcVccywFDpyk2uV5xCIBphHV5T8SVnX9/o3kplPE1zzKt77+YIoq+EMwJp56A== react-hot-toast@^2.4.1: version "2.4.1" @@ -13459,15 +13680,15 @@ react-i18next@^13.5.0: "@babel/runtime" "^7.22.5" html-parse-stringify "^3.0.1" -react-i18next@^14.1.2: - version "14.1.2" - resolved "https://registry.npmjs.org/react-i18next/-/react-i18next-14.1.2.tgz" - integrity sha512-FSIcJy6oauJbGEXfhUgVeLzvWBhIBIS+/9c6Lj4niwKZyGaGb4V4vUbATXSlsHJDXXB+ociNxqFNiFuV1gmoqg== +react-i18next@^15.0.1: + version "15.0.1" + resolved "https://registry.npmjs.org/react-i18next/-/react-i18next-15.0.1.tgz" + integrity sha512-NwxLqNM6CLbeGA9xPsjits0EnXdKgCRSS6cgkgOdNcPXqL+1fYNl8fBg1wmnnHvFy812Bt4IWTPE9zjoPmFj3w== dependencies: - "@babel/runtime" "^7.23.9" + "@babel/runtime" "^7.24.8" html-parse-stringify "^3.0.1" -"react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.1, "react-is@>= 16.8.0": +"react-is@^16.12.0 || ^17.0.0 || ^18.0.0", react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.1: version "16.13.1" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -13482,10 +13703,10 @@ react-is@^18.0.0: resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz" integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== -react-is@^18.2.0: - version "18.2.0" - resolved "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== +react-is@^18.3.1: + version "18.3.1" + resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz" + integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== react-lifecycles-compat@^3.0.0: version "3.0.4" @@ -13507,10 +13728,10 @@ react-moment@^1.1.3: resolved "https://registry.npmjs.org/react-moment/-/react-moment-1.1.3.tgz" integrity sha512-8EPvlUL8u6EknPp1ISF5MQ3wx2OHJVXIP/iZc4wRh3iV3XozftZERDv9ANZeAtMlhNNQHdFoqcZHFUkBSTONfA== -react-multi-carousel@^2.8.4: - version "2.8.4" - resolved "https://registry.npmjs.org/react-multi-carousel/-/react-multi-carousel-2.8.4.tgz" - integrity sha512-7Is5Wr+m2ebkR+oq2Su2tjUdBwpVtB2O6Tjb74KDNfxWe/FrsTQwezTJTk/r9cKCrRp9Li308v822/5bZm7XKg== +react-multi-carousel@^2.8.5: + version "2.8.5" + resolved "https://registry.npmjs.org/react-multi-carousel/-/react-multi-carousel-2.8.5.tgz" + integrity sha512-C5DAvJkfzR2JK9YixZ3oyF9x6R4LW6nzTpIXrl9Oujxi4uqP9SzVVCjl+JLM3tSdqdjAx/oWZK3dTVBSR73Q+w== react-native-fetch-api@^3.0.0: version "3.0.0" @@ -13527,7 +13748,7 @@ react-native-webview@^11.26.0: escape-string-regexp "2.0.0" invariant "2.2.4" -react-native@*, react-native@>=0.59: +react-native@*: version "0.74.2" resolved "https://registry.npmjs.org/react-native/-/react-native-0.74.2.tgz" integrity sha512-EBMBjPPL4/GjHMP4NqsZabT3gI5WU9cSmduABGAGrd8uIcmTZ5F2Ng9k6gFmRm7n8e8CULxDNu98ZpQfBjl7Bw== @@ -13570,10 +13791,10 @@ react-native@*, react-native@>=0.59: ws "^6.2.2" yargs "^17.6.2" -react-player@^2.13.0: - version "2.14.1" - resolved "https://registry.npmjs.org/react-player/-/react-player-2.14.1.tgz" - integrity sha512-jILj7F9o+6NHzrJ1GqZIxfJgskvGmKeJ05FNhPvgiCpvMZFmFneKEkukywHcULDO2lqITm+zcEkLSq42mX0FbA== +react-player@^2.16.0: + version "2.16.0" + resolved "https://registry.npmjs.org/react-player/-/react-player-2.16.0.tgz" + integrity sha512-mAIPHfioD7yxO0GNYVFD1303QFtI3lyyQZLY229UEAp/a10cSW+hPcakg0Keq8uWJxT2OiT/4Gt+Lc9bD6bJmQ== dependencies: deepmerge "^4.0.0" load-script "^1.0.0" @@ -13589,7 +13810,7 @@ react-qr-code@2.0.11: prop-types "^15.8.1" qr.js "0.0.0" -react-qrcode-logo@^2.10.0, react-qrcode-logo@^2.9.0: +react-qrcode-logo@^2.9.0: version "2.10.0" resolved "https://registry.npmjs.org/react-qrcode-logo/-/react-qrcode-logo-2.10.0.tgz" integrity sha512-Q1+jLtcyDl5rLR29YdkXVLzYk62p3+541x00HxURVBQhs6SqFyEZZVhvkU/VQ082ytXa3GdCmGWMLK5z0Vhe7g== @@ -13597,27 +13818,31 @@ react-qrcode-logo@^2.10.0, react-qrcode-logo@^2.9.0: lodash.isequal "^4.5.0" qrcode-generator "^1.4.1" -react-redux@^8.1.3: - version "8.1.3" - resolved "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz" - integrity sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw== +react-qrcode-logo@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/react-qrcode-logo/-/react-qrcode-logo-3.0.0.tgz" + integrity sha512-2+vZ3GNBdUpYxIKyt6SFZsDGXa0xniyUQ0wPI4O0hJTzRjttPIx1pPnH9IWQmp/4nDMoN47IBhi3Breu1KudYw== + dependencies: + lodash.isequal "^4.5.0" + qrcode-generator "^1.4.4" + +"react-redux@^7.2.1 || ^8.1.3 || ^9.0.0", react-redux@^9.1.2: + version "9.1.2" + resolved "https://registry.npmjs.org/react-redux/-/react-redux-9.1.2.tgz" + integrity sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w== dependencies: - "@babel/runtime" "^7.12.1" - "@types/hoist-non-react-statics" "^3.3.1" "@types/use-sync-external-store" "^0.0.3" - hoist-non-react-statics "^3.3.2" - react-is "^18.0.0" use-sync-external-store "^1.0.0" -react-refresh@^0.14.0: - version "0.14.0" - resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz" - integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ== +react-refresh@^0.14.0, react-refresh@^0.14.2: + version "0.14.2" + resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz" + integrity sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA== react-remove-scroll-bar@^2.1.0: - version "2.3.4" - resolved "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz" - integrity sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A== + version "2.3.6" + resolved "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz" + integrity sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g== dependencies: react-style-singleton "^2.2.1" tslib "^2.0.0" @@ -13633,20 +13858,20 @@ react-remove-scroll@2.4.1: use-callback-ref "^1.2.3" use-sidecar "^1.0.1" -react-router-dom@^6.22.3: - version "6.22.3" - resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.3.tgz" - integrity sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw== +react-router-dom@^6.26.1: + version "6.26.1" + resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.26.1.tgz" + integrity sha512-veut7m41S1fLql4pLhxeSW3jlqs+4MtjRLj0xvuCEXsxusJCbs6I8yn9BxzzDX2XDgafrccY6hwjmd/bL54tFw== dependencies: - "@remix-run/router" "1.15.3" - react-router "6.22.3" + "@remix-run/router" "1.19.1" + react-router "6.26.1" -react-router@6.22.3: - version "6.22.3" - resolved "https://registry.npmjs.org/react-router/-/react-router-6.22.3.tgz" - integrity sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ== +react-router@6.26.1: + version "6.26.1" + resolved "https://registry.npmjs.org/react-router/-/react-router-6.26.1.tgz" + integrity sha512-kIwJveZNwp7teQRI5QmwWo39A5bXRyqpH0COKKmPnyD2vBvDwgFXSqDUYtt1h+FEyfnE8eXr7oe0MxRzVwCcvQ== dependencies: - "@remix-run/router" "1.15.3" + "@remix-run/router" "1.19.1" react-shallow-renderer@^16.15.0: version "16.15.0" @@ -13656,10 +13881,10 @@ react-shallow-renderer@^16.15.0: object-assign "^4.1.1" react-is "^16.12.0 || ^17.0.0 || ^18.0.0" -react-share@^5.0.3: - version "5.0.3" - resolved "https://registry.npmjs.org/react-share/-/react-share-5.0.3.tgz" - integrity sha512-8BFkzfd8zNrO6JMP4Dwrt2sTSrRGQ9bNrU3K0riAwRJe4U/Z8/ryjKuhP2jLoHsfxj38MsPuyEQiVlIHVIICvw== +react-share@^5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/react-share/-/react-share-5.1.0.tgz" + integrity sha512-OvyfMtj/0UzH1wi90OdHhZVJ6WUC/+IeWvBwppeZozwIGyAjQgyR0QXlHOrxVHVECqnGvcpBaFTXVrqouTieaw== dependencies: classnames "^2.3.2" jsonp "^0.2.1" @@ -13732,10 +13957,10 @@ react-webcam@^7.2.0: resolved "https://registry.npmjs.org/react-webcam/-/react-webcam-7.2.0.tgz" integrity sha512-xkrzYPqa1ag2DP+2Q/kLKBmCIfEx49bVdgCCCcZf88oF+0NPEbkwYk3/s/C7Zy0mhM8k+hpdNkBLzxg8H0aWcg== -react@*, "react@^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18", "react@^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react@^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react@^15.6.2 || ^16.0 || ^17 || ^18", "react@^16.0 || ^17.0.0 || ^18.0.0", "react@^16.0.0 || ^17.0.0 || ^18.0.0", "react@^16.3.2 || ^17.0.0 || ^18.0.0", "react@^16.6.0 || ^17.0.0 || ^18.0.0", "react@^16.8 || ^17.0 || ^18.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17 || ^18", "react@^16.8.0 || ^17.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || 17.x", "react@^16.x || ^17.x || ^18.x", "react@^17 || ^18", "react@^17.0.0 || ^18.0.0", react@^18.0.0, react@^18.2.0, react@^18.x, "react@>= 16.8 || 18.0.0", "react@>= 16.8.0", react@>=16, "react@>=16.14.0 <18.2.0", react@>=16.2.0, react@>=16.3, react@>=16.4.1, react@>=16.6.0, react@>=16.8, react@>=16.8.0, react@>=16.8.6, react@>=17.0.0, react@>=18, "react@15.x || 16.x || 17.x || 18.x", react@18.2.0: - version "18.2.0" - resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" - integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== +react@*, "react@^0.14.0 || ^15.0.0 || ^16 || ^17 || ^18", "react@^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react@^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", "react@^15.6.2 || ^16.0 || ^17 || ^18", "react@^16.0 || ^17.0.0 || ^18.0.0", "react@^16.0.0 || ^17.0.0 || ^18.0.0", "react@^16.3.2 || ^17.0.0 || ^18.0.0", "react@^16.6.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || ^17 || ^18 || ^19", "react@^16.8.0 || ^17.0.0", "react@^16.8.0 || ^17.0.0 || ^18.0.0", "react@^16.8.0 || 17.x", "react@^16.9.0 || ^17.0.0 || ^18", "react@^16.x || ^17.x || ^18.x", "react@^17 || ^18", "react@^17.0.0 || ^18.0.0", react@^18.0, react@^18.0.0, react@^18.2.0, react@^18.3.1, react@^18.x, "react@>= 16.8 || 18.0.0", "react@>= 16.8.0", react@>=16, "react@>=16.14.0 <18.2.0", react@>=16.2.0, react@>=16.3, react@>=16.4.1, react@>=16.6.0, react@>=16.8, react@>=16.8.0, react@>=16.8.6, react@>=17.0.0, react@>=18, react@>=18.0.0, "react@15.x || 16.x || 17.x || 18.x", react@18.2.0: + version "18.3.1" + resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz" + integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== dependencies: loose-envify "^1.1.0" @@ -13848,29 +14073,26 @@ redis-parser@^3.0.0: dependencies: redis-errors "^1.0.0" -redux-saga@^1.2.3: - version "1.3.0" - resolved "https://registry.npmjs.org/redux-saga/-/redux-saga-1.3.0.tgz" - integrity sha512-J9RvCeAZXSTAibFY0kGw6Iy4EdyDNW7k6Q+liwX+bsck7QVsU78zz8vpBRweEfANxnnlG/xGGeOvf6r8UXzNJQ== - dependencies: - "@redux-saga/core" "^1.3.0" +redux-thunk@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz" + integrity sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw== -"redux@^4 || ^5.0.0-beta.0", redux@^4.2.1: - version "4.2.1" - resolved "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz" - integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w== - dependencies: - "@babel/runtime" "^7.9.2" +redux@^5.0.0, redux@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz" + integrity sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w== reflect.getprototypeof@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz" - integrity sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw== + version "1.0.6" + resolved "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz" + integrity sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.1" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" globalthis "^1.0.3" which-builtin-type "^1.1.3" @@ -13903,14 +14125,15 @@ regenerator-transform@^0.15.2: dependencies: "@babel/runtime" "^7.8.4" -regexp.prototype.flags@^1.5.0, regexp.prototype.flags@^1.5.1: - version "1.5.1" - resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz" - integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== +regexp.prototype.flags@^1.5.2: + version "1.5.2" + resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz" + integrity sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - set-function-name "^2.0.0" + call-bind "^1.0.6" + define-properties "^1.2.1" + es-errors "^1.3.0" + set-function-name "^2.0.1" regexpu-core@^5.3.1: version "5.3.2" @@ -13946,6 +14169,11 @@ require-main-filename@^2.0.0: resolved "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== +reselect@^5.1.0: + version "5.1.1" + resolved "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz" + integrity sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w== + resize-observer-polyfill@^1.5.0, resize-observer-polyfill@^1.5.1: version "1.5.1" resolved "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz" @@ -13970,12 +14198,12 @@ resolve@^1.1.7, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.22 path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@^2.0.0-next.4: - version "2.0.0-next.4" - resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz" - integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ== +resolve@^2.0.0-next.5: + version "2.0.0-next.5" + resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz" + integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== dependencies: - is-core-module "^2.9.0" + is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -14043,29 +14271,29 @@ rollup-plugin-visualizer@^5.9.2: source-map "^0.7.4" yargs "^17.5.1" -rollup@^1.20.0||^2.0.0||^3.0.0||^4.0.0, rollup@^4.13.0, "rollup@2.x || 3.x || 4.x": - version "4.17.2" - resolved "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz" - integrity sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ== +rollup@^1.20.0||^2.0.0||^3.0.0||^4.0.0, rollup@^4.20.0, "rollup@2.x || 3.x || 4.x": + version "4.21.0" + resolved "https://registry.npmjs.org/rollup/-/rollup-4.21.0.tgz" + integrity sha512-vo+S/lfA2lMS7rZ2Qoubi6I5hwZwzXeUIctILZLbHI+laNtvhhOIon2S1JksA5UEDQ7l3vberd0fxK44lTYjbQ== dependencies: "@types/estree" "1.0.5" optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.17.2" - "@rollup/rollup-android-arm64" "4.17.2" - "@rollup/rollup-darwin-arm64" "4.17.2" - "@rollup/rollup-darwin-x64" "4.17.2" - "@rollup/rollup-linux-arm-gnueabihf" "4.17.2" - "@rollup/rollup-linux-arm-musleabihf" "4.17.2" - "@rollup/rollup-linux-arm64-gnu" "4.17.2" - "@rollup/rollup-linux-arm64-musl" "4.17.2" - "@rollup/rollup-linux-powerpc64le-gnu" "4.17.2" - "@rollup/rollup-linux-riscv64-gnu" "4.17.2" - "@rollup/rollup-linux-s390x-gnu" "4.17.2" - "@rollup/rollup-linux-x64-gnu" "4.17.2" - "@rollup/rollup-linux-x64-musl" "4.17.2" - "@rollup/rollup-win32-arm64-msvc" "4.17.2" - "@rollup/rollup-win32-ia32-msvc" "4.17.2" - "@rollup/rollup-win32-x64-msvc" "4.17.2" + "@rollup/rollup-android-arm-eabi" "4.21.0" + "@rollup/rollup-android-arm64" "4.21.0" + "@rollup/rollup-darwin-arm64" "4.21.0" + "@rollup/rollup-darwin-x64" "4.21.0" + "@rollup/rollup-linux-arm-gnueabihf" "4.21.0" + "@rollup/rollup-linux-arm-musleabihf" "4.21.0" + "@rollup/rollup-linux-arm64-gnu" "4.21.0" + "@rollup/rollup-linux-arm64-musl" "4.21.0" + "@rollup/rollup-linux-powerpc64le-gnu" "4.21.0" + "@rollup/rollup-linux-riscv64-gnu" "4.21.0" + "@rollup/rollup-linux-s390x-gnu" "4.21.0" + "@rollup/rollup-linux-x64-gnu" "4.21.0" + "@rollup/rollup-linux-x64-musl" "4.21.0" + "@rollup/rollup-win32-arm64-msvc" "4.21.0" + "@rollup/rollup-win32-ia32-msvc" "4.21.0" + "@rollup/rollup-win32-x64-msvc" "4.21.0" fsevents "~2.3.2" rpc-websockets@^7.5.1: @@ -14102,13 +14330,13 @@ rust-result@^1.0.0: dependencies: individual "^2.0.0" -safe-array-concat@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.1.tgz" - integrity sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q== +safe-array-concat@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz" + integrity sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" + call-bind "^1.0.7" + get-intrinsic "^1.2.4" has-symbols "^1.0.3" isarray "^2.0.5" @@ -14134,13 +14362,13 @@ safe-json-parse@4.0.0: dependencies: rust-result "^1.0.0" -safe-regex-test@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz" - integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== +safe-regex-test@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz" + integrity sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" + call-bind "^1.0.6" + es-errors "^1.3.0" is-regex "^1.1.4" safe-stable-stringify@^2.1.0: @@ -14153,10 +14381,10 @@ safer-buffer@^2.1.0, "safer-buffer@>= 2.1.2 < 3.0.0": resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -scheduler@^0.23.0: - version "0.23.0" - resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz" - integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== +scheduler@^0.23.2: + version "0.23.2" + resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz" + integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== dependencies: loose-envify "^1.1.0" @@ -14264,24 +14492,27 @@ set-blocking@^2.0.0: resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== -set-function-length@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz" - integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== +set-function-length@^1.2.1: + version "1.2.2" + resolved "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz" + integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== dependencies: - define-data-property "^1.1.1" - get-intrinsic "^1.2.1" + define-data-property "^1.1.4" + es-errors "^1.3.0" + function-bind "^1.1.2" + get-intrinsic "^1.2.4" gopd "^1.0.1" - has-property-descriptors "^1.0.0" + has-property-descriptors "^1.0.2" -set-function-name@^2.0.0, set-function-name@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz" - integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== +set-function-name@^2.0.1, set-function-name@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz" + integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ== dependencies: - define-data-property "^1.0.1" + define-data-property "^1.1.4" + es-errors "^1.3.0" functions-have-names "^1.2.3" - has-property-descriptors "^1.0.0" + has-property-descriptors "^1.0.2" set-harmonic-interval@^1.0.1: version "1.0.1" @@ -14313,7 +14544,7 @@ shallow-clone@^3.0.0: dependencies: kind-of "^6.0.2" -shallowequal@^1.1.0: +shallowequal@^1.1.0, shallowequal@1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz" integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== @@ -14335,14 +14566,15 @@ shell-quote@^1.6.1, shell-quote@^1.7.3: resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz" integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== +side-channel@^1.0.4, side-channel@^1.0.6: + version "1.0.6" + resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.7" @@ -14668,47 +14900,59 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" -string.prototype.matchall@^4.0.8: - version "4.0.10" - resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz" - integrity sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ== +string.prototype.matchall@^4.0.11: + version "4.0.11" + resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz" + integrity sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + get-intrinsic "^1.2.4" + gopd "^1.0.1" has-symbols "^1.0.3" - internal-slot "^1.0.5" - regexp.prototype.flags "^1.5.0" - set-function-name "^2.0.0" - side-channel "^1.0.4" + internal-slot "^1.0.7" + regexp.prototype.flags "^1.5.2" + set-function-name "^2.0.2" + side-channel "^1.0.6" -string.prototype.trim@^1.2.8: - version "1.2.8" - resolved "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz" - integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== +string.prototype.repeat@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz" + integrity sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + define-properties "^1.1.3" + es-abstract "^1.17.5" -string.prototype.trimend@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz" - integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== +string.prototype.trim@^1.2.9: + version "1.2.9" + resolved "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz" + integrity sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.0" + es-object-atoms "^1.0.0" -string.prototype.trimstart@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz" - integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== +string.prototype.trimend@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz" + integrity sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" + +string.prototype.trimstart@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz" + integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg== + dependencies: + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" "strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" @@ -14772,21 +15016,20 @@ sturdy-websocket@^0.2.1: resolved "https://registry.npmjs.org/sturdy-websocket/-/sturdy-websocket-0.2.1.tgz" integrity sha512-NnzSOEKyv4I83qbuKw9ROtJrrT6Z/Xt7I0HiP/e6H6GnpeTDvzwGIGeJ8slai+VwODSHQDooW2CAilJwT9SpRg== -styled-components@^5.3.3, "styled-components@>= 2": - version "5.3.5" - resolved "https://registry.npmjs.org/styled-components/-/styled-components-5.3.5.tgz" - integrity sha512-ndETJ9RKaaL6q41B69WudeqLzOpY1A/ET/glXkNZ2T7dPjPqpPCXXQjDFYZWwNnE5co0wX+gTCqx9mfxTmSIPg== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/traverse" "^7.4.5" - "@emotion/is-prop-valid" "^1.1.0" - "@emotion/stylis" "^0.8.4" - "@emotion/unitless" "^0.7.4" - babel-plugin-styled-components ">= 1.12.0" - css-to-react-native "^3.0.0" - hoist-non-react-statics "^3.0.0" - shallowequal "^1.1.0" - supports-color "^5.5.0" +styled-components@^6.1.12: + version "6.1.13" + resolved "https://registry.npmjs.org/styled-components/-/styled-components-6.1.13.tgz" + integrity sha512-M0+N2xSnAtwcVAQeFEsGWFFxXDftHUD7XrKla06QbpUMmbmtFBMMTcKWvFXtWxuD5qQkB8iU5gk6QASlx2ZRMw== + dependencies: + "@emotion/is-prop-valid" "1.2.2" + "@emotion/unitless" "0.8.1" + "@types/stylis" "4.2.5" + css-to-react-native "3.2.0" + csstype "3.1.3" + postcss "8.4.38" + shallowequal "1.1.0" + stylis "4.3.2" + tslib "2.6.2" stylis@^4.3.0: version "4.3.1" @@ -14798,6 +15041,11 @@ stylis@4.2.0: resolved "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz" integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== +stylis@4.3.2: + version "4.3.2" + resolved "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz" + integrity sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg== + sucrase@^3.32.0: version "3.35.0" resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz" @@ -14826,7 +15074,7 @@ superstruct@^1.0.3: resolved "https://registry.npmjs.org/superstruct/-/superstruct-1.0.3.tgz" integrity sha512-8iTn3oSS8nRGn+C2pgXSKPI3jmpm6FExNazNpjvqS6ZUJQCej3PUXEKM8NjHBOs54ExM+LPW/FBRhymrdcCiSg== -supports-color@^5.3.0, supports-color@^5.5.0: +supports-color@^5.3.0: version "5.5.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== @@ -14872,18 +15120,18 @@ symbol-observable@^2.0.3: resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-2.0.3.tgz" integrity sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA== -synckit@^0.8.6: - version "0.8.8" - resolved "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz" - integrity sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ== +synckit@^0.9.1: + version "0.9.1" + resolved "https://registry.npmjs.org/synckit/-/synckit-0.9.1.tgz" + integrity sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A== dependencies: "@pkgr/core" "^0.1.0" tslib "^2.6.2" tailwindcss@^3.4.3: - version "3.4.4" - resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz" - integrity sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A== + version "3.4.7" + resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.7.tgz" + integrity sha512-rxWZbe87YJb4OcSopb7up2Ba4U82BoiSGUdoDr3Ydrg9ckxFS/YWsvhN323GMcddgU65QRy7JndC7ahhInhvlQ== dependencies: "@alloc/quick-lru" "^5.2.0" arg "^5.0.2" @@ -15076,15 +15324,20 @@ tslib@^1.10.0: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.6.2: - version "2.6.2" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + version "2.6.3" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz" + integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ== tslib@1.14.1: version "1.14.1" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@2.6.2: + version "2.6.2" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + tty-browserify@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz" @@ -15137,44 +15390,49 @@ type@^2.5.0: resolved "https://registry.npmjs.org/type/-/type-2.7.2.tgz" integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== -typed-array-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz" - integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== +typed-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz" + integrity sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" - is-typed-array "^1.1.10" + call-bind "^1.0.7" + es-errors "^1.3.0" + is-typed-array "^1.1.13" -typed-array-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz" - integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== +typed-array-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz" + integrity sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw== dependencies: - call-bind "^1.0.2" + call-bind "^1.0.7" for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" -typed-array-byte-offset@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz" - integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== +typed-array-byte-offset@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz" + integrity sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA== dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" -typed-array-length@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz" - integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== +typed-array-length@^1.0.6: + version "1.0.6" + resolved "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz" + integrity sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g== dependencies: - call-bind "^1.0.2" + call-bind "^1.0.7" for-each "^0.3.3" - is-typed-array "^1.1.9" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + possible-typed-array-names "^1.0.0" typedarray-to-buffer@^3.1.5, typedarray-to-buffer@3.1.5: version "3.1.5" @@ -15183,29 +15441,10 @@ typedarray-to-buffer@^3.1.5, typedarray-to-buffer@3.1.5: dependencies: is-typedarray "^1.0.0" -typescript-compare@^0.0.2: - version "0.0.2" - resolved "https://registry.npmjs.org/typescript-compare/-/typescript-compare-0.0.2.tgz" - integrity sha512-8ja4j7pMHkfLJQO2/8tut7ub+J3Lw2S3061eJLFQcvs3tsmJKp8KG5NtpLn7KcY2w08edF74BSVN7qJS0U6oHA== - dependencies: - typescript-logic "^0.0.0" - -typescript-logic@^0.0.0: - version "0.0.0" - resolved "https://registry.npmjs.org/typescript-logic/-/typescript-logic-0.0.0.tgz" - integrity sha512-zXFars5LUkI3zP492ls0VskH3TtdeHCqu0i7/duGt60i5IGPIpAHE/DWo5FqJ6EjQ15YKXrt+AETjv60Dat34Q== - -typescript-tuple@^2.2.1: - version "2.2.1" - resolved "https://registry.npmjs.org/typescript-tuple/-/typescript-tuple-2.2.1.tgz" - integrity sha512-Zcr0lbt8z5ZdEzERHAMAniTiIKerFCMgd7yjq1fPnDJ43et/k9twIFQMUYff9k5oXcsQ0WpvFcgzK2ZKASoW6Q== - dependencies: - typescript-compare "^0.0.2" - -typescript@^5.1, typescript@^5.4.2, typescript@>=4.2.0, typescript@>=4.9.5, typescript@>=5.0.4: - version "5.4.2" - resolved "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz" - integrity sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ== +typescript@^5.1, typescript@^5.5.4, typescript@>=4.2.0, typescript@>=4.9.5, typescript@>=5.0.4: + version "5.5.4" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz" + integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q== ufo@^1.3.0, ufo@^1.3.1, ufo@^1.3.2: version "1.3.2" @@ -15411,6 +15650,11 @@ use-callback-ref@^1.2.3, use-callback-ref@^1.2.5: dependencies: tslib "^2.0.0" +use-debounce@^10.0.3: + version "10.0.3" + resolved "https://registry.npmjs.org/use-debounce/-/use-debounce-10.0.3.tgz" + integrity sha512-DxQSI9ZKso689WM1mjgGU3ozcxU1TJElBJ3X6S4SMzMNcm2lVH0AHmyXB+K7ewjz2BSUKJTDqTcwtSMRfB89dg== + use-isomorphic-layout-effect@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz" @@ -15474,6 +15718,11 @@ utils-merge@1.0.1: resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== +uuid@^10.0.0: + version "10.0.0" + resolved "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz" + integrity sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ== + uuid@^8.3.2: version "8.3.2" resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" @@ -15552,24 +15801,23 @@ vary@~1.1.2: videojs-font "3.2.0" videojs-vtt.js "^0.15.5" -"video.js@^7 || ^8", video.js@^8, video.js@^8.10.0: - version "8.10.0" - resolved "https://registry.npmjs.org/video.js/-/video.js-8.10.0.tgz" - integrity sha512-7UeG/flj/pp8tNGW8WKPP1VJb3x2FgLoqUWzpZqkoq5YIyf6MNzmIrKtxprl438T5RVkcj+OzV8IX4jYSAn4Sw== +"video.js@^7 || ^8", video.js@^8, video.js@^8.17.3: + version "8.17.3" + resolved "https://registry.npmjs.org/video.js/-/video.js-8.17.3.tgz" + integrity sha512-zhhmE0LNxJRA603/48oYzF7GYdT+rQRscvcsouYxFE71aKhalHLBP6S9/XjixnyjcrYgwIx8OQo6eSjcbbAW0Q== dependencies: "@babel/runtime" "^7.12.5" - "@videojs/http-streaming" "3.10.0" + "@videojs/http-streaming" "3.13.2" "@videojs/vhs-utils" "^4.0.0" - "@videojs/xhr" "2.6.0" + "@videojs/xhr" "2.7.0" aes-decrypter "^4.0.1" global "4.4.0" - keycode "2.2.0" m3u8-parser "^7.1.0" mpd-parser "^1.2.2" mux.js "^7.0.1" safe-json-parse "4.0.0" - videojs-contrib-quality-levels "4.0.0" - videojs-font "4.1.0" + videojs-contrib-quality-levels "4.1.0" + videojs-font "4.2.0" videojs-vtt.js "0.15.5" videojs-contrib-quality-levels@^2.0.9: @@ -15580,10 +15828,10 @@ videojs-contrib-quality-levels@^2.0.9: global "^4.3.2" video.js "^6 || ^7 || ^8" -videojs-contrib-quality-levels@^4.0.0, videojs-contrib-quality-levels@4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/videojs-contrib-quality-levels/-/videojs-contrib-quality-levels-4.0.0.tgz" - integrity sha512-u5rmd8BjLwANp7XwuQ0Q/me34bMe6zg9PQdHfTS7aXgiVRbNTb4djcmfG7aeSrkpZjg+XCLezFNenlJaCjBHKw== +videojs-contrib-quality-levels@^4.0.0, videojs-contrib-quality-levels@4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/videojs-contrib-quality-levels/-/videojs-contrib-quality-levels-4.1.0.tgz" + integrity sha512-TfrXJJg1Bv4t6TOCMEVMwF/CoS8iENYsWNKip8zfhB5kTcegiFYezEA0eHAJPU64ZC8NQbxQgOwAsYU8VXbOWA== dependencies: global "^4.4.0" @@ -15592,10 +15840,10 @@ videojs-font@3.2.0: resolved "https://registry.npmjs.org/videojs-font/-/videojs-font-3.2.0.tgz" integrity sha512-g8vHMKK2/JGorSfqAZQUmYYNnXmfec4MLhwtEFS+mMs2IDY398GLysy6BH6K+aS1KMNu/xWZ8Sue/X/mdQPliA== -videojs-font@4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/videojs-font/-/videojs-font-4.1.0.tgz" - integrity sha512-X1LuPfLZPisPLrANIAKCknZbZu5obVM/ylfd1CN+SsCmPZQ3UMDPcvLTpPBJxcBuTpHQq2MO1QCFt7p8spnZ/w== +videojs-font@4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/videojs-font/-/videojs-font-4.2.0.tgz" + integrity sha512-YPq+wiKoGy2/M7ccjmlvwi58z2xsykkkfNMyIg4xb7EZQQNwB71hcSsB3o75CqQV7/y5lXkXhI/rsGAS7jfEmQ== videojs-hls-quality-selector@^1.1.4: version "1.1.4" @@ -15642,19 +15890,20 @@ viem@^1.1.4: isows "1.0.3" ws "8.13.0" -"viem@^1.16.6 || ^2.1.1", viem@^2.8.11, viem@^2.8.6, viem@>=0.3.35: - version "2.8.11" - resolved "https://registry.npmjs.org/viem/-/viem-2.8.11.tgz" - integrity sha512-TMmHle2k6gZ0+LENMr5ulb/bKGMTaCFj5V3sbS52OGCnhxI4t46NDIk6RIIAiaPR4AkwZPf31LY5LORjpb02Tg== +"viem@^1.16.6 || ^2.1.1", viem@^2.20.0, viem@^2.8.6, viem@>=0.3.35: + version "2.20.0" + resolved "https://registry.npmjs.org/viem/-/viem-2.20.0.tgz" + integrity sha512-cM4vs81HnSNbfceI1MLkx4pCVzbVjl9xiNSv5SCutYjUyFFOVSPDlEyhpg2iHinxx1NM4Qne3END5eLT8rvUdg== dependencies: "@adraffy/ens-normalize" "1.10.0" - "@noble/curves" "1.2.0" - "@noble/hashes" "1.3.2" - "@scure/bip32" "1.3.2" - "@scure/bip39" "1.2.1" - abitype "1.0.0" - isows "1.0.3" - ws "8.13.0" + "@noble/curves" "1.4.0" + "@noble/hashes" "1.4.0" + "@scure/bip32" "1.4.0" + "@scure/bip39" "1.3.0" + abitype "1.0.5" + isows "1.0.4" + webauthn-p256 "0.0.5" + ws "8.17.1" viem@1.5.3: version "1.5.3" @@ -15686,18 +15935,18 @@ viem@2.8.6, viem@2.x: isows "1.0.3" ws "8.13.0" -vite-plugin-node-polyfills@^0.21.0: - version "0.21.0" - resolved "https://registry.npmjs.org/vite-plugin-node-polyfills/-/vite-plugin-node-polyfills-0.21.0.tgz" - integrity sha512-Sk4DiKnmxN8E0vhgEhzLudfJQfaT8k4/gJ25xvUPG54KjLJ6HAmDKbr4rzDD/QWEY+Lwg80KE85fGYBQihEPQA== +vite-plugin-node-polyfills@^0.22.0: + version "0.22.0" + resolved "https://registry.npmjs.org/vite-plugin-node-polyfills/-/vite-plugin-node-polyfills-0.22.0.tgz" + integrity sha512-F+G3LjiGbG8QpbH9bZ//GSBr9i1InSTkaulfUHFa9jkLqVGORFBoqc2A/Yu5Mmh1kNAbiAeKeK+6aaQUf3x0JA== dependencies: "@rollup/plugin-inject" "^5.0.5" node-stdlib-browser "^1.2.0" -vite-plugin-radar@^0.9.2: - version "0.9.3" - resolved "https://registry.npmjs.org/vite-plugin-radar/-/vite-plugin-radar-0.9.3.tgz" - integrity sha512-o/7F0gHQW9yUxpExXYwQLxFYOSxiWIPs3Uh24sg+wl5ikghzLKMQ2Xldak/rsT0o06rzdrAqP9+XSOwfCbwz2Q== +vite-plugin-radar@^0.9.6: + version "0.9.6" + resolved "https://registry.npmjs.org/vite-plugin-radar/-/vite-plugin-radar-0.9.6.tgz" + integrity sha512-tLvUt7+iZznxYa8GmCrZBV3Q0fLQApsyg9EIJgaen8DjGky3vFIq9KoDWAoVMs9FZ5qbsSBb3YfSvoqwVV+5xw== vite-plugin-svgr@^4.2.0: version "4.2.0" @@ -15708,14 +15957,14 @@ vite-plugin-svgr@^4.2.0: "@svgr/core" "^8.1.0" "@svgr/plugin-jsx" "^8.1.0" -"vite@^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0", "vite@^2.6.0 || 3 || 4 || 5", "vite@^4.2.0 || ^5.0.0", vite@^5.3.3: - version "5.3.3" - resolved "https://registry.npmjs.org/vite/-/vite-5.3.3.tgz" - integrity sha512-NPQdeCU0Dv2z5fu+ULotpuq5yfCS1BzKUIPhNbP3YBfAMGJXbt2nS+sbTFu+qchaqWTD+H3JK++nRwr6XIcp6A== +"vite@^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0", "vite@^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0", "vite@^2.6.0 || 3 || 4 || 5", "vite@^4.2.0 || ^5.0.0", vite@^5.4.2: + version "5.4.2" + resolved "https://registry.npmjs.org/vite/-/vite-5.4.2.tgz" + integrity sha512-dDrQTRHp5C1fTFzcSaMxjk6vdpKvT+2/mIdE07Gw2ykehT49O0z/VHS3zZ8iV/Gh8BJJKHWOe5RjaNrW5xf/GA== dependencies: esbuild "^0.21.3" - postcss "^8.4.39" - rollup "^4.13.0" + postcss "^8.4.41" + rollup "^4.20.0" optionalDependencies: fsevents "~2.3.3" @@ -15948,6 +16197,14 @@ web3-utils@1.8.0: randombytes "^2.1.0" utf8 "3.0.0" +webauthn-p256@0.0.5: + version "0.0.5" + resolved "https://registry.npmjs.org/webauthn-p256/-/webauthn-p256-0.0.5.tgz" + integrity sha512-drMGNWKdaixZNobeORVIqq7k5DsRC9FnG201K2QjeOoQLmtSDaSsVZdkg6n5jUALJKcAG++zBPJXmv6hy0nWFg== + dependencies: + "@noble/curves" "^1.4.0" + "@noble/hashes" "^1.4.0" + webextension-polyfill@^0.10.0, "webextension-polyfill@>=0.10.0 <1.0": version "0.10.0" resolved "https://registry.npmjs.org/webextension-polyfill/-/webextension-polyfill-0.10.0.tgz" @@ -15995,12 +16252,12 @@ which-boxed-primitive@^1.0.2: is-symbol "^1.0.3" which-builtin-type@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz" - integrity sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw== + version "1.1.4" + resolved "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.4.tgz" + integrity sha512-bppkmBSsHFmIMSl8BO9TbsyzsvGjVoppt8xUiGzwiu/bhDCGxnpOKCxgqj6GuyHE0mINMDecBFPlOm2hzY084w== dependencies: - function.prototype.name "^1.1.5" - has-tostringtag "^1.0.0" + function.prototype.name "^1.1.6" + has-tostringtag "^1.0.2" is-async-function "^2.0.0" is-date-object "^1.0.5" is-finalizationregistry "^1.0.2" @@ -16009,34 +16266,34 @@ which-builtin-type@^1.1.3: is-weakref "^1.0.2" isarray "^2.0.5" which-boxed-primitive "^1.0.2" - which-collection "^1.0.1" - which-typed-array "^1.1.9" + which-collection "^1.0.2" + which-typed-array "^1.1.15" -which-collection@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz" - integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== +which-collection@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz" + integrity sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw== dependencies: - is-map "^2.0.1" - is-set "^2.0.1" - is-weakmap "^2.0.1" - is-weakset "^2.0.1" + is-map "^2.0.3" + is-set "^2.0.3" + is-weakmap "^2.0.2" + is-weakset "^2.0.3" which-module@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz" integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q== -which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.2, which-typed-array@^1.1.9: - version "1.1.13" - resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz" - integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== +which-typed-array@^1.1.14, which-typed-array@^1.1.15, which-typed-array@^1.1.2: + version "1.1.15" + resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz" + integrity sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA== dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.4" + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" for-each "^0.3.3" gopd "^1.0.1" - has-tostringtag "^1.0.0" + has-tostringtag "^1.0.2" which@^2.0.1: version "2.0.2" @@ -16045,10 +16302,10 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -wicg-inert@^3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/wicg-inert/-/wicg-inert-3.1.2.tgz" - integrity sha512-Ba9tGNYxXwaqKEi9sJJvPMKuo063umUPsHN0JJsjrs2j8KDSzkWLMZGZ+MH1Jf1Fq4OWZ5HsESJID6nRza2ang== +wicg-inert@^3.1.3: + version "3.1.3" + resolved "https://registry.npmjs.org/wicg-inert/-/wicg-inert-3.1.3.tgz" + integrity sha512-5L0PKK7iP+0Q/jv2ccgmkz/pfXbumZtlEyWS/xnX+L+Og3f7WjL4+iEs18k4IuldOX3PgGpza3qGndL9xUBjCQ== "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" @@ -16137,6 +16394,11 @@ ws@8.13.0: resolved "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz" integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== +ws@8.17.1: + version "8.17.1" + resolved "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz" + integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== + ws@8.5.0: version "8.5.0" resolved "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz" diff --git a/rair-node/bin/api/auth/auth.Service.js b/rair-node/bin/api/auth/auth.Service.js index f8e40b992..d51322d3f 100644 --- a/rair-node/bin/api/auth/auth.Service.js +++ b/rair-node/bin/api/auth/auth.Service.js @@ -100,7 +100,7 @@ module.exports = { ? await superAdminInstance.hasSuperAdminRights(userData.publicAddress) : superAdmins.includes(userData.publicAddress); userData.oreId = req?.metaAuth?.oreId; - req.session.userData = userData; + req.session.userData = { ...userData, loginType: req.web3LoginMethod }; // eslint-disable-next-line no-unused-vars const { _id, adminNFT, ...publicFacingUserData } = userData; diff --git a/rair-node/bin/api/contracts/contracts.Controller.js b/rair-node/bin/api/contracts/contracts.Controller.js index c665d0e72..696ab9a75 100644 --- a/rair-node/bin/api/contracts/contracts.Controller.js +++ b/rair-node/bin/api/contracts/contracts.Controller.js @@ -11,6 +11,7 @@ const { productsByNetworkAndAddress, offersByNetworkAndAddress, contractListForFactory, + getProductList, } = require('./contracts.Service'); const { isAdmin, @@ -79,6 +80,13 @@ router.get( validation(['dbId'], 'params'), getContractById, ); + +router.get( + '/:id/products', + validation(['dbId'], 'params'), + getProductList, +); + router.patch( '/:id', requireUserSession, diff --git a/rair-node/bin/api/contracts/contracts.Service.js b/rair-node/bin/api/contracts/contracts.Service.js index b235779fe..1d4228c06 100644 --- a/rair-node/bin/api/contracts/contracts.Service.js +++ b/rair-node/bin/api/contracts/contracts.Service.js @@ -1,6 +1,5 @@ -const _ = require('lodash'); const { ObjectId } = require('mongodb'); -const log = require('../../utils/logger'); +const log = require('../../utils/logger')(module); const { Contract, Blockchain, File, Product } = require('../../models'); const AppError = require('../../utils/errors/AppError'); const eFactory = require('../../utils/entityFactory'); @@ -186,14 +185,13 @@ module.exports = { const { pageNum = '1', itemsPerPage = '20', - blockchain = '', + blockchain = [], category = [], hidden = false, contractTitle = '', } = req.query; const pageSize = parseInt(itemsPerPage, 10); const skip = (parseInt(pageNum, 10) - 1) * pageSize; - const blockchainArr = blockchain === '' ? [] : blockchain.split(','); const options = []; @@ -216,10 +214,10 @@ module.exports = { }, }, ], - as: 'products', + as: 'product', }, }; - options.push(lookupProduct, { $unwind: '$products' }); + options.push(lookupProduct, { $unwind: '$product' }); const lookupUser = { $lookup: { from: 'User', @@ -289,12 +287,47 @@ module.exports = { }); } + const lookupSingleToken = { + $lookup: { + from: 'MintedToken', + let: { + contr: '$_id', + startingToken: '$product.firstTokenIndex', + }, + pipeline: [ + { + $match: { + $expr: { + $and: [ + { + $eq: ['$contract', '$$contr'], + }, + { + $gte: ['$uniqueIndexInContract', '$$startingToken'], + }, + ], + }, + }, + }, + { $limit: 1 }, + { $project: { + 'metadata.animation_url': 1, + 'metadata.image_thumbnail': 1, + 'metadata.image': 1, + }, + }, + ], + as: 'frontToken', + }, + }; + options.push(lookupSingleToken, { $unwind: '$frontToken' }); + options.push( { $lookup: { from: 'Offer', let: { - prod: '$products.collectionIndexInContract', + prod: '$product.collectionIndexInContract', contractL: '$_id', }, pipeline: [ @@ -313,16 +346,16 @@ module.exports = { }, }, ], - as: 'products.offers', + as: 'product.offers', }, }, { $match: { $or: [ - { diamond: true, 'products.offers': { $not: { $size: 0 } } }, + { diamond: true, 'product.offers': { $not: { $size: 0 } } }, { diamond: { $in: [false, undefined] }, - 'products.offers': { $not: { $size: 0 } }, + 'product.offers': { $not: { $size: 0 } }, }, ], }, @@ -332,8 +365,8 @@ module.exports = { const blockchainFilter = { display: { $ne: false }, }; - if (blockchainArr?.length >= 1) { - blockchainFilter.hash = [...blockchainArr]; + if (blockchain?.length >= 1) { + blockchainFilter.hash = { $in: [...blockchain] }; } const foundBlockchain = await Blockchain.find(blockchainFilter); @@ -342,8 +375,8 @@ module.exports = { blockchain: { $in: foundBlockchain.map((chain) => chain.hash) }, }, }); - if (foundBlockchain.length === 0 && blockchainArr.length >= 1) { - return next(new AppError('Invalid blockchain.', 404)); + if (foundBlockchain.length === 0 && blockchain.length >= 1) { + return next(new AppError('Invalid blockchain filter.', 404)); } if (!hidden) { @@ -361,19 +394,27 @@ module.exports = { }); } - const totalNumber = _.chain( - await Contract.aggregate(options).count('contracts'), - ) - .head() - .get('contracts', 0) - .value(); - - const contracts = await Contract.aggregate(options) - .sort({ 'products.name': 1 }) - .skip(skip) - .limit(pageSize); + const [result] = await Contract.aggregate([ + ...options, + { + $facet: { + contracts: [ + { $sort: { 'product.name': 1 } }, + { $skip: skip }, + { $limit: pageSize }, + ], + count: [ + { $count: 'total' }, + ], + }, + }, + ]); - return res.json({ success: true, contracts, totalNumber }); + return res.json({ + success: true, + contracts: result.contracts, + totalNumber: result?.count?.[0]?.total || 0, + }); } catch (e) { return next(e); } @@ -385,7 +426,6 @@ module.exports = { display: { $ne: false }, }); const contractQuery = { - blockView: false, blockchain: foundBlockchain.map((chain) => chain.hash), }; if (!superAdmin) { @@ -397,12 +437,19 @@ module.exports = { title: 1, blockchain: 1, diamond: 1, + blockView: 1, + blockSync: 1, }); return res.json({ success: true, contracts }); } catch (e) { return next(e); } }, + getProductList: async (req, res, next) => { + const { id } = req.params; + const products = await Product.find({ contract: id }, { name: 1, _id: 1 }); + return res.json({ success: true, products }); + }, getAllContracts: async (req, res, next) => { const { pageNum = 1, diff --git a/rair-node/bin/api/credits/credits.Service.js b/rair-node/bin/api/credits/credits.Service.js index f113bae4f..504a04d1f 100644 --- a/rair-node/bin/api/credits/credits.Service.js +++ b/rair-node/bin/api/credits/credits.Service.js @@ -6,7 +6,7 @@ const { getContractRunner, getInstance } = require('../../integrations/ethers/co const log = require('../../utils/logger')(module); const addressMapping = { - //'0x5': '0xad78463579Ff43bdC917674c64749c35c7E325f5', + // '0x5': '0xad78463579Ff43bdC917674c64749c35c7E325f5', '0x250': '0x6C9Ca38fFb93756a52f0072B72eA3C6769f87892', }; diff --git a/rair-node/bin/api/files/files.Controller.js b/rair-node/bin/api/files/files.Controller.js index 2e99435f2..be7b28578 100644 --- a/rair-node/bin/api/files/files.Controller.js +++ b/rair-node/bin/api/files/files.Controller.js @@ -8,7 +8,6 @@ const { removeFileAndOffer, updateFile, isFileOwner, - listCategories, updateMedia, deleteMedia, listMedia, @@ -71,7 +70,6 @@ router.get( validation(['dbId'], 'params'), getFilesForToken, ); -router.get('/categories', listCategories); router.get('/:id/unlocks', getFileAndOffer); router.post( '/:id/unlocks', diff --git a/rair-node/bin/api/files/files.Service.js b/rair-node/bin/api/files/files.Service.js index 4b821531d..db860e326 100644 --- a/rair-node/bin/api/files/files.Service.js +++ b/rair-node/bin/api/files/files.Service.js @@ -1,11 +1,9 @@ const { ObjectId } = require('mongodb'); -const _ = require('lodash'); const { File, MintedToken, Unlock, Offer, - Category, User, Blockchain, Contract, @@ -35,7 +33,7 @@ module.exports = { const { pageNum = '1', itemsPerPage = '20', - blockchain = '', + blockchain = [], category = [], userAddress = '', contractAddress = '', @@ -48,14 +46,14 @@ module.exports = { const foundUser = await User.findOne({ publicAddress: userAddress }); - const blockchainQuery = { + const blockchainFilter = { display: { $ne: false }, }; - if (blockchain) { - blockchainQuery.hash = blockchain; + if (blockchain.length) { + blockchainFilter.hash = { $in: [...blockchain] }; } + const foundBlockchain = await Blockchain.find(blockchainFilter); - const foundBlockchain = await Blockchain.find(blockchainQuery); const contractQuery = { blockView: false, }; @@ -132,28 +130,29 @@ module.exports = { }, ]; - let data = (await File.aggregate([ + const [result] = await File.aggregate([ ...pipeline, - { $skip: skip }, - { $limit: pageSize }, - ])); - - const [countResult] = await File.aggregate([...pipeline, { $count: 'totalCount' }]); - - const { totalCount } = countResult || 0; + { + $facet: { + list: [ + { $skip: skip }, + { $limit: pageSize }, + ], + count: [ + { $count: 'total' }, + ], + }, + }, + ]); // verify the user have needed tokens for unlock the files - data = await checkFileAccess(data, req.user); - - const list = _.chain(data) - .reduce((result, value) => { - // eslint-disable-next-line no-param-reassign - result[value._id] = value; - return result; - }, {}) - .value(); + const unlockCheck = await checkFileAccess(result.list, req.user); - return res.json({ success: true, list, totalNumber: totalCount }); + return res.json({ + success: true, + list: unlockCheck, + totalNumber: result?.count?.[0]?.total || 0, + }); } catch (e) { log.error(e); return next(e.message); @@ -228,14 +227,6 @@ module.exports = { return next(err); } }, - listCategories: async (req, res, next) => { - try { - const categories = await Category.find(); - res.json({ success: true, categories }); - } catch (e) { - next(e); - } - }, getFile: async (req, res, next) => { const { id } = req.params; if (id) { diff --git a/rair-node/bin/api/nft/nft.Service.js b/rair-node/bin/api/nft/nft.Service.js index 61d447831..771e12ba3 100644 --- a/rair-node/bin/api/nft/nft.Service.js +++ b/rair-node/bin/api/nft/nft.Service.js @@ -84,20 +84,24 @@ module.exports = { }); } - const result = await MintedToken.aggregate([ + const [result] = await MintedToken.aggregate([ ...pipeline, - { $skip: skip }, - { $limit: pageSize }, - ]); - - const count = await MintedToken.aggregate([ - ...pipeline, - { - $count: 'totalCount', - }, + { $facet: { + list: [ + { $skip: skip }, + { $limit: pageSize }, + ], + count: [ + { $count: 'total' }, + ], + } }, ]); - res.json({ success: true, result, totalCount: count[0]?.totalCount }); + res.json({ + success: true, + result: result.list, + totalCount: result.count?.[0]?.total || 0, + }); } catch (e) { next(e); } @@ -664,23 +668,39 @@ module.exports = { } } - const totalCount = _.chain( - await MintedToken.aggregate(aggregateOptions) - .count('tokens') - .collation({ locale: 'en_US', numericOrdering: true }), - ) - .head() - .get('tokens', 0) - .value(); + const sorting = {}; + if (sortByPrice) { + sorting['offer.price'] = Number(sortByPrice); + } + if (sortByToken) { + sorting.token = Number(sortByToken); + } - const tokensSorted = await MintedToken.aggregate(aggregateOptions) - .sort(_.assign({}, sortByPrice ? { 'offer.price': Number(sortByPrice) } : {}, sortByToken ? { token: Number(sortByToken) } : {})) - .collation({ locale: 'en_US', numericOrdering: true }) - .limit(tokenLimit); + const [result] = await MintedToken.aggregate( + [ + ...aggregateOptions, + { + $facet: { + tokens: [ + { $sort: sorting }, + { $limit: tokenLimit }, + ], + count: [ + { $count: 'total' }, + ], + }, + }, + ], + { + collation: { + locale: 'en_US', numericOrdering: true, + }, + }, + ); - const tokens = attributesCounter(tokensSorted); + const tokens = attributesCounter(result.tokens); - return res.json({ success: true, result: { totalCount, tokens } }); + return res.json({ success: true, totalCount: result?.count?.[0]?.total || 0, tokens }); } catch (err) { return next(err); } diff --git a/rair-node/bin/api/offers/offers.Controller.js b/rair-node/bin/api/offers/offers.Controller.js index 3c8faf03b..f5c025620 100644 --- a/rair-node/bin/api/offers/offers.Controller.js +++ b/rair-node/bin/api/offers/offers.Controller.js @@ -2,6 +2,7 @@ const express = require('express'); const { getAllOffers, updateOfferData, + getAvailableTokensInOffer, } = require('./offers.Service'); const { validation, requireUserSession } = require('../../middleware'); @@ -12,6 +13,12 @@ router.get( validation(['pagination', 'dbOffers'], 'query'), getAllOffers, ); +router.get( + '/:id/available', + requireUserSession, + validation(['dbId'], 'params'), + getAvailableTokensInOffer, +); router.put( '/:id', requireUserSession, diff --git a/rair-node/bin/api/offers/offers.Service.js b/rair-node/bin/api/offers/offers.Service.js index fd19d3ecc..353c79906 100644 --- a/rair-node/bin/api/offers/offers.Service.js +++ b/rair-node/bin/api/offers/offers.Service.js @@ -1,3 +1,4 @@ +const { ObjectId } = require('mongodb'); const AppError = require('../../utils/errors/AppError'); const { Offer, Contract } = require('../../models'); const eFactory = require('../../utils/entityFactory'); @@ -30,6 +31,64 @@ exports.getOfferIndexesByContractAndProduct = async (req, res, next) => { } }; +exports.getAvailableTokensInOffer = async (req, res, next) => { + try { + const { id } = req.params; + const [result] = await Offer.aggregate([ + { + $match: { + _id: new ObjectId(id), + }, + }, + { + $lookup: { + from: 'MintedToken', + let: { + offerIndex: '$diamondRangeIndex', + contractId: '$contract', + }, + pipeline: [ + { + $match: { + $expr: { + $and: [ + { $eq: ['$$offerIndex', '$offer'] }, + { $eq: ['$contract', '$$contractId'] }, + { $eq: ['$isMinted', false] }, + ], + }, + }, + }, + { + $project: { + token: 1, + }, + }, + { + $project: { + _id: 0, + }, + }, + ], + as: 'availableTokens', + }, + }, + { + $project: { + availableTokens: 1, + }, + }, + ]); + + return res.json({ + success: true, + availableTokens: result.availableTokens, + }); + } catch (err) { + return next(err); + } +}; + exports.updateOfferData = async (req, res, next) => { try { const { id } = req.params; diff --git a/rair-node/bin/api/products/product.Controller.js b/rair-node/bin/api/products/product.Controller.js index 1f3ce1711..eaa2e5e73 100644 --- a/rair-node/bin/api/products/product.Controller.js +++ b/rair-node/bin/api/products/product.Controller.js @@ -17,12 +17,6 @@ router.get( productService.getProductsByUser, ); -router.get( - '/:id', - validation(['dbId'], 'params'), - productService.getProductById, -); - router.post( '/:id', upload.single('banner'), diff --git a/rair-node/bin/api/products/product.Service.js b/rair-node/bin/api/products/product.Service.js index f4ffcf67d..54cc820c5 100644 --- a/rair-node/bin/api/products/product.Service.js +++ b/rair-node/bin/api/products/product.Service.js @@ -6,14 +6,6 @@ const eFactory = require('../../utils/entityFactory'); const { addFile } = require('../../integrations/ipfsService')(); exports.getAllProducts = eFactory.getAll(ProductModel); -exports.getProductById = async (req, res, next) => { - try { - const product = await ProductModel.findById(req.params.id); - res.json({ success: true, product }); - } catch (e) { - next(e); - } -}; exports.setProductBanner = async (req, res, next) => { try { diff --git a/rair-node/bin/api/resales/resales.Service.js b/rair-node/bin/api/resales/resales.Service.js index f29c38142..c56c77d4f 100644 --- a/rair-node/bin/api/resales/resales.Service.js +++ b/rair-node/bin/api/resales/resales.Service.js @@ -8,24 +8,59 @@ const { getInstance, getContractRunner } = require('../../integrations/ethers/co exports.openResales = async (req, res, next) => { try { const { contract, blockchain, index } = req.query; - const filter = { buyer: undefined }; + const pipeline = [ + { + $match: { + buyer: { $exists: false }, + }, + }, + { + $lookup: { + from: 'User', + as: 'sellerData', + localField: 'seller', + foreignField: 'publicAddress', + }, + }, + { + $unwind: { + path: '$sellerData', + preserveNullAndEmptyArrays: true, + }, + }, + ]; + if (index) { + pipeline.push({ + $match: { + tokenIndex: index, + }, + }); + } + pipeline.push({ + $lookup: { + from: 'Contract', + as: 'contractData', + localField: 'tokenContract', + foreignField: '_id', + }, + }, { + $unwind: { + path: '$contractData', + preserveNullAndEmptyArrays: true, + }, + }); if (blockchain) { - const contractFilter = { blockchain }; + const contractQuery = { + 'contractData.blockchain': blockchain, + }; if (contract) { - contractFilter.contractAddress = contract; + contractQuery['contractData.contractAddress'] = contract; } - const foundContract = (await Contract.find(contractFilter)) - .map((ctr) => ctr._id); - if (foundContract?.length) { - filter.tokenContract = { - $in: foundContract, - }; - } - } - if (index) { - filter.tokenIndex = index; + pipeline.push({ + $match: contractQuery, + }); } - const offers = await ResaleTokenOffer.find(filter); + const offers = await ResaleTokenOffer.aggregate(pipeline); return res.json({ success: true, data: offers }); } catch (e) { return next(new AppError(e)); diff --git a/rair-node/bin/api/settings/settings.Service.js b/rair-node/bin/api/settings/settings.Service.js index dbe29a453..2083384ca 100644 --- a/rair-node/bin/api/settings/settings.Service.js +++ b/rair-node/bin/api/settings/settings.Service.js @@ -63,7 +63,7 @@ exports.getFeaturedCollection = async (req, res, next) => { product: collectionData.collectionIndexInContract, collectionName: collectionData.name, collectionBanner: collectionData.bannerImage, - user: userData, + user: userData || contractData.user, }; } } @@ -79,21 +79,47 @@ exports.getFeaturedCollection = async (req, res, next) => { exports.getServerSettings = async (req, res, next) => { try { - const settings = await ServerSetting.findOne({}, { - 'footerLinks._id': false, - 'customValues._id': false, - }).lean(); + const [settings] = await ServerSetting.aggregate( + [ + { + $lookup: { + from: 'Product', + let: { + productId: '$featuredCollection', + }, + pipeline: [ + { + $match: { + $expr: { + $eq: ['$$productId', '$_id'], + }, + }, + }, + { + $project: { + _id: true, + contract: true, + }, + }, + ], + as: 'featuredCollection', + }, + }, + { + $unwind: { + path: '$featuredCollection', + preserveNullAndEmptyArrays: true, + }, + }, + { + $project: { + 'footerLinks._id': false, + 'customValues._id': false, + }, + }, + ], + ); const blockchainSettings = await Blockchain.find({}); - if (settings.featuredCollection) { - const collectionData = await Product.findById(settings.featuredCollection).lean(); - if (collectionData) { - const contractData = await Contract.findById(collectionData.contract); - if (contractData) { - collectionData.contract = contractData; - } - settings.featuredCollection = collectionData; - } - } return res.json({ success: true, settings, @@ -181,6 +207,7 @@ exports.getTheme = async (req, res, next) => { buttonPrimaryColor, buttonFadeColor, buttonSecondaryColor, + iconColor, } = await ServerSetting.findOne({}).lean(); return res.json({ success: true, @@ -195,6 +222,7 @@ exports.getTheme = async (req, res, next) => { buttonPrimaryColor, buttonFadeColor, buttonSecondaryColor, + iconColor, }, }); } catch (error) { diff --git a/rair-node/bin/api/tokens/tokens.Service.js b/rair-node/bin/api/tokens/tokens.Service.js index 9d5e9bb52..3cb880111 100644 --- a/rair-node/bin/api/tokens/tokens.Service.js +++ b/rair-node/bin/api/tokens/tokens.Service.js @@ -1,6 +1,7 @@ const fs = require('fs'); const _ = require('lodash'); const csv = require('csv-parser'); +const { ObjectId } = require('mongodb'); const AppError = require('../../utils/errors/AppError'); const { OfferPool, @@ -491,35 +492,84 @@ exports.updateSingleTokenMetadata = async (req, res, next) => { exports.getFullTokenInfo = async (req, res, next) => { const { id } = req.params; - const tokenData = await MintedToken.findById(id).lean(); - if (!tokenData) { - return next(new AppError('No token information found')); - } - const contractData = await Contract.findById(tokenData.contract); - if (!contractData) { - return next(new AppError('No contract information found')); - } - tokenData.contract = contractData; - const rangeQuery = { - contract: tokenData.contract._id, - }; - if (tokenData.contract.diamond) { - rangeQuery.diamondRangeIndex = tokenData.offer; - } else { - rangeQuery.offerIndex = tokenData.offer; - } - const rangeData = await Offer.findOne(rangeQuery); - if (rangeData) { - tokenData.range = rangeData; - const productData = await Product.findOne({ - contract: tokenData.contract._id, - collectionIndexInContract: rangeData.product, - }); - if (productData) { - tokenData.product = productData; - } - } - return res.json({ success: true, tokenData }); + + const tokenData = await MintedToken.aggregate([ + { + $match: { _id: new ObjectId(id) }, + }, + { + $lookup: { + from: 'Contract', + as: 'contract', + localField: 'contract', + foreignField: '_id', + }, + }, + { + $unwind: '$contract', + }, + { + $lookup: { + from: 'Offer', + as: 'offer', + let: { contractId: '$contract._id', offerIndex: '$offer' }, + pipeline: [{ + $match: { + $expr: { + $and: [ + { + $eq: ['$$contractId', '$contract'], + }, + { + $eq: ['$diamondRangeIndex', '$$offerIndex'], + }, + ], + }, + }, + }], + }, + }, + { + $unwind: '$offer', + }, + { + $lookup: { + from: 'Product', + as: 'product', + let: { contractId: '$contract._id', productIndex: '$offer.product' }, + pipeline: [{ + $match: { + $expr: { + $and: [ + { + $eq: ['$$contractId', '$contract'], + }, + { + $eq: ['$collectionIndexInContract', '$$productIndex'], + }, + ], + }, + }, + }], + }, + }, + { + $unwind: '$product', + }, + { + $lookup: { + from: 'User', + as: 'ownerData', + localField: 'ownerAddress', + foreignField: 'publicAddress', + }, + }, + { + $unwind: '$ownerData', + }, + ]); + + return res.json({ success: true, tokenData: tokenData[0] }); }; exports.createTokensViaCSV = async (req, res, next) => { diff --git a/rair-node/bin/api/transactions/transactions.Controller.js b/rair-node/bin/api/transactions/transactions.Controller.js index 8dd1d5ca5..31c587a55 100644 --- a/rair-node/bin/api/transactions/transactions.Controller.js +++ b/rair-node/bin/api/transactions/transactions.Controller.js @@ -1,12 +1,13 @@ const { Router } = require('express'); const { requireUserSession } = require('../../middleware'); const { processUserTransaction } = require('./transactions.Service'); + const router = Router(); router.post( '/:network/:hash', requireUserSession, - processUserTransaction + processUserTransaction, ); module.exports = router; diff --git a/rair-node/bin/api/users/users.Service.js b/rair-node/bin/api/users/users.Service.js index 355efa713..d66d0822c 100644 --- a/rair-node/bin/api/users/users.Service.js +++ b/rair-node/bin/api/users/users.Service.js @@ -207,7 +207,7 @@ exports.updateUserByUserAddress = async (req, res, next) => { { publicAddress }, fieldsForUpdate, { new: true, projection: { nonce: 0 } }, - ); + ).lean(); req.session.userData = { ...req.session.userData, diff --git a/rair-node/bin/index.js b/rair-node/bin/index.js index 23d92d8ac..35ba6b9bc 100644 --- a/rair-node/bin/index.js +++ b/rair-node/bin/index.js @@ -82,7 +82,7 @@ async function main() { }, }); - await seedDB(context); + await seedDB(); app.use(morgan('dev')); app.use(bodyParser.raw()); diff --git a/rair-node/bin/integrations/ethers/web3Signature.js b/rair-node/bin/integrations/ethers/web3Signature.js index 02e6e45a1..bfc32ef38 100644 --- a/rair-node/bin/integrations/ethers/web3Signature.js +++ b/rair-node/bin/integrations/ethers/web3Signature.js @@ -173,6 +173,7 @@ module.exports = { cache.del(MetaMessage); cache.del(`${userAddress}secret`); req.metaAuth = { recovered: userAddress }; + req.web3LoginMethod = 'web3auth'; } else { req.metaAuth = undefined; } @@ -180,6 +181,7 @@ module.exports = { }, validateChallengeV2: async (req, res, next) => { req.metaAuth = await validateChallenge(req, 'body'); + req.web3LoginMethod = 'metamask'; return next(); }, }; diff --git a/rair-node/bin/models/serverSettings.js b/rair-node/bin/models/serverSettings.js index 5db068ca3..ef2cf769d 100644 --- a/rair-node/bin/models/serverSettings.js +++ b/rair-node/bin/models/serverSettings.js @@ -15,10 +15,10 @@ const ServerSetting = new Schema({ superAdmins: [{ type: String, required: false }], superAdminsOnVault: { type: Boolean, default: false }, databaseResales: { type: Boolean, default: false }, - // Light mode and dark mode colors for background - darkModePrimary: { type: String, required: false }, - darkModeSecondary: { type: String, required: false }, - darkModeText: { type: String, required: false }, + // Dark mode colors + darkModePrimary: { type: String, required: true, default: '#222021' }, + darkModeSecondary: { type: String, required: true, default: '#dedede' }, + darkModeText: { type: String, required: true, default: 'white' }, // Logo images darkModeBannerLogo: { type: String, required: false }, darkModeMobileLogo: { type: String, required: false }, @@ -26,9 +26,11 @@ const ServerSetting = new Schema({ lightModeBannerLogo: { type: String, required: false }, lightModeMobileLogo: { type: String, required: false }, // Button - buttonPrimaryColor: { type: String, required: false }, - buttonFadeColor: { type: String, required: false }, - buttonSecondaryColor: { type: String, required: false }, + buttonPrimaryColor: { type: String, required: true, default: '#725bdb' }, + buttonFadeColor: { type: String, required: true, default: '#e882d5' }, + buttonSecondaryColor: { type: String, required: true, default: '#19a7f6' }, + // Icon color + iconColor: { type: String, required: true, default: '#e882d5' }, // Custom footer footerLinks: { type: [{ diff --git a/rair-node/bin/schemas/databaseSchemas.js b/rair-node/bin/schemas/databaseSchemas.js index c51c5903a..9eb6a0acf 100644 --- a/rair-node/bin/schemas/databaseSchemas.js +++ b/rair-node/bin/schemas/databaseSchemas.js @@ -14,6 +14,7 @@ module.exports = { buttonPrimaryColor: Joi.string(), buttonFadeColor: Joi.string(), buttonSecondaryColor: Joi.string(), + iconColor: Joi.string(), superAdminsOnVault: Joi.boolean(), databaseResales: Joi.boolean(), footerLinks: Joi.array().items(Joi.object({ diff --git a/rair-node/bin/schemas/filterAndSort.js b/rair-node/bin/schemas/filterAndSort.js index 1b41b0a2c..f2761f28b 100644 --- a/rair-node/bin/schemas/filterAndSort.js +++ b/rair-node/bin/schemas/filterAndSort.js @@ -2,7 +2,7 @@ const Joi = require('joi'); const { mongoId, ethAddress } = require('./reusableCustomTypes'); module.exports = () => ({ - blockchain: Joi.string(), + blockchain: Joi.array().items(Joi.string()), category: Joi.array().items(mongoId), userAddress: ethAddress, contractAddress: ethAddress, diff --git a/rair-node/bin/seeds/index.js b/rair-node/bin/seeds/index.js index 793624f51..6eb610fee 100644 --- a/rair-node/bin/seeds/index.js +++ b/rair-node/bin/seeds/index.js @@ -1,7 +1,7 @@ const log = require('../utils/logger')(module); const categories = require('./categories'); const syncRestrictions = require('./syncRestrictions'); -const { Category, ServerSetting, Contract } = require('../models'); +const { Category, ServerSetting, Contract, Blockchain } = require('../models'); module.exports = async () => { try { @@ -42,4 +42,30 @@ module.exports = async () => { }); log.info('Server settings set by default!'); } + + // Populate CORE blockchain + try { + const coreExists = await Blockchain.findOne({ hash: '0x2105' }); + if (!coreExists) { + await Blockchain.create( + { + hash: '0x2105', + name: 'Base', + display: true, + sync: true, + alchemySupport: false, + blockExplorerGateway: 'https://basescan.org', + diamondFactoryAddress: '0x1F89Cc515dDc53dA2fac5B0Ca3b322066A71E6BA', + diamondMarketplaceAddress: '0x58795f50b50d492C4252B9BBF78485EF4043FF3E', + mainTokenAddress: '0x2b0fFbF00388f9078d5512256c43B983BB805eF8', + numericalId: 8453, + rpcEndpoint: 'https://base.meowrpc.com', + symbol: 'ETH', + testnet: false, + }, + ); + } + } catch (err) { + log.info('Error populating Core chain'); + } }; diff --git a/rair-node/bin/utils/entityFactory.js b/rair-node/bin/utils/entityFactory.js index 598b41d4b..8493dd3d4 100644 --- a/rair-node/bin/utils/entityFactory.js +++ b/rair-node/bin/utils/entityFactory.js @@ -36,7 +36,7 @@ exports.updateOne = (Model) => }); if (!doc) { - return next(new AppError(`No document found with ID ${id}`, 404)) + return next(new AppError(`No document found with ID ${id}`, 404)); } return res.status(200).json({ diff --git a/rair-node/bin/utils/helpers.js b/rair-node/bin/utils/helpers.js index 635719f90..ec4e10a60 100644 --- a/rair-node/bin/utils/helpers.js +++ b/rair-node/bin/utils/helpers.js @@ -274,7 +274,7 @@ const processPaginationQuery = (queryFields) => { const skip = (parseInt(pageNum, 10) - 1) * limit; return { skip, limit, query }; -} +}; module.exports = { attributesCounter, diff --git a/rair-sync/bin/integrations/ethers/contracts/diamondMarketplaceABI.json b/rair-sync/bin/integrations/ethers/contracts/diamondMarketplaceABI.json index 8ff2897fa..686e6be6a 100644 --- a/rair-sync/bin/integrations/ethers/contracts/diamondMarketplaceABI.json +++ b/rair-sync/bin/integrations/ethers/contracts/diamondMarketplaceABI.json @@ -1 +1 @@ -{"address":"0x1F89Cc515dDc53dA2fac5B0Ca3b322066A71E6BA","abi":[{"inputs":[{"internalType":"address","name":"_initializationContractAddress","type":"address"},{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"InitializationFunctionReverted","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"enum IDiamondCut.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"indexed":false,"internalType":"struct IDiamondCut.FacetCut[]","name":"_diamondCut","type":"tuple[]"},{"indexed":false,"internalType":"address","name":"_init","type":"address"},{"indexed":false,"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"DiamondCut","type":"event"},{"inputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"enum IDiamondCut.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"internalType":"struct IDiamondCut.FacetCut[]","name":"_diamondCut","type":"tuple[]"},{"internalType":"address","name":"_init","type":"address"},{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"diamondCut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_functionSelector","type":"bytes4"}],"name":"facetAddress","outputs":[{"internalType":"address","name":"facetAddress_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facetAddresses","outputs":[{"internalType":"address[]","name":"facetAddresses_","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_facet","type":"address"}],"name":"facetFunctionSelectors","outputs":[{"internalType":"bytes4[]","name":"_facetFunctionSelectors","type":"bytes4[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facets","outputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"internalType":"struct IDiamondLoupe.Facet[]","name":"facets_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"length","type":"uint256"}],"name":"StringsInsufficientHexLength","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"indexed":false,"internalType":"string","name":"rangeName","type":"string"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeSplitsLength","type":"uint256"},{"indexed":false,"internalType":"bool","name":"visible","type":"bool"},{"indexed":false,"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"AddedMintingOffer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"}],"name":"MintedToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeSplitsLength","type":"uint256"},{"indexed":false,"internalType":"bool","name":"visible","type":"bool"},{"indexed":false,"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"UpdatedMintingOffer","type":"event"},{"inputs":[{"internalType":"address","name":"erc721Address_","type":"address"},{"internalType":"uint256","name":"rangeIndex_","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[]","name":"splits","type":"tuple[]"},{"internalType":"bool","name":"visible_","type":"bool"},{"internalType":"address","name":"nodeAddress_","type":"address"}],"name":"addMintingOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc721Address_","type":"address"},{"internalType":"uint256[]","name":"rangeIndexes","type":"uint256[]"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[][]","name":"splits","type":"tuple[][]"},{"internalType":"bool[]","name":"visibility","type":"bool[]"},{"internalType":"address","name":"nodeAddress_","type":"address"}],"name":"addMintingOfferBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex_","type":"uint256"},{"internalType":"uint256","name":"tokenIndex_","type":"uint256"}],"name":"buyMintingOffer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex_","type":"uint256"},{"internalType":"uint256[]","name":"tokenIndexes","type":"uint256[]"},{"internalType":"address[]","name":"recipients","type":"address[]"}],"name":"buyMintingOfferBatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"getOfferInfo","outputs":[{"components":[{"internalType":"address","name":"erc721Address","type":"address"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[]","name":"fees","type":"tuple[]"},{"internalType":"bool","name":"visible","type":"bool"}],"internalType":"struct mintingOffer","name":"mintOffer","type":"tuple"},{"components":[{"internalType":"uint256","name":"rangeStart","type":"uint256"},{"internalType":"uint256","name":"rangeEnd","type":"uint256"},{"internalType":"uint256","name":"tokensAllowed","type":"uint256"},{"internalType":"uint256","name":"mintableTokens","type":"uint256"},{"internalType":"uint256","name":"lockedTokens","type":"uint256"},{"internalType":"uint256","name":"rangePrice","type":"uint256"},{"internalType":"string","name":"rangeName","type":"string"}],"internalType":"struct IRAIR721.range","name":"rangeData","type":"tuple"},{"internalType":"uint256","name":"productIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc721Address","type":"address"},{"internalType":"uint256","name":"rangeIndex","type":"uint256"}],"name":"getOfferInfoForAddress","outputs":[{"internalType":"uint256","name":"offerIndex","type":"uint256"},{"components":[{"internalType":"address","name":"erc721Address","type":"address"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[]","name":"fees","type":"tuple[]"},{"internalType":"bool","name":"visible","type":"bool"}],"internalType":"struct mintingOffer","name":"mintOffer","type":"tuple"},{"components":[{"internalType":"uint256","name":"rangeStart","type":"uint256"},{"internalType":"uint256","name":"rangeEnd","type":"uint256"},{"internalType":"uint256","name":"tokensAllowed","type":"uint256"},{"internalType":"uint256","name":"mintableTokens","type":"uint256"},{"internalType":"uint256","name":"lockedTokens","type":"uint256"},{"internalType":"uint256","name":"rangePrice","type":"uint256"},{"internalType":"string","name":"rangeName","type":"string"}],"internalType":"struct IRAIR721.range","name":"rangeData","type":"tuple"},{"internalType":"uint256","name":"productIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc721Address","type":"address"}],"name":"getOffersCountForAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalOfferCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"mintingOfferId_","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[]","name":"splits_","type":"tuple[]"},{"internalType":"bool","name":"visible_","type":"bool"}],"name":"updateMintingOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"decimals","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"precalculatedMultiplier","type":"uint256"}],"name":"UpdatedDecimals","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"decimals","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newPercentage","type":"uint256"}],"name":"UpdatedNodeFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAddress","type":"address"}],"name":"UpdatedTreasuryAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"decimals","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newPercentage","type":"uint256"}],"name":"UpdatedTreasuryFee","type":"event"},{"inputs":[],"name":"MAINTAINER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDecimals","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNodeFee","outputs":[{"internalType":"uint16","name":"decimals","type":"uint16"},{"internalType":"uint256","name":"nodeFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTreasuryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTreasuryFee","outputs":[{"internalType":"uint16","name":"decimals","type":"uint16"},{"internalType":"uint256","name":"treasuryFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"newDecimals_","type":"uint16"}],"name":"updateDecimals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFee_","type":"uint256"}],"name":"updateNodeFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress_","type":"address"}],"name":"updateTreasuryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFee_","type":"uint256"}],"name":"updateTreasuryFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"uint256","name":"token","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"offerId","type":"uint256"}],"name":"TokenOfferCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"uint256","name":"token","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenPrice","type":"uint256"}],"name":"TokenSold","type":"event"},{"inputs":[],"name":"RESALE_ADMIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"},{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"tokenPrice","type":"uint256"},{"internalType":"address","name":"nodeAddress","type":"address"}],"name":"createGasTokenOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"},{"internalType":"address","name":"buyer","type":"address"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"tokenPrice","type":"uint256"},{"internalType":"address","name":"nodeAddress","type":"address"}],"name":"generateResaleHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"}],"name":"getRoyalties","outputs":[{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct ResaleStorage.feeSplits[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"purchaseGasTokenOffer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"},{"internalType":"address","name":"buyer","type":"address"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"tokenPrice","type":"uint256"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"purchaseTokenOffer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setDecimalPow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setPurchaseGracePeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct ResaleStorage.feeSplits[]","name":"fees","type":"tuple[]"}],"name":"setRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file +{"address":"0x58795f50b50d492C4252B9BBF78485EF4043FF3E","abi":[{"inputs":[{"internalType":"address","name":"_initializationContractAddress","type":"address"},{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"InitializationFunctionReverted","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"enum IDiamondCut.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"indexed":false,"internalType":"struct IDiamondCut.FacetCut[]","name":"_diamondCut","type":"tuple[]"},{"indexed":false,"internalType":"address","name":"_init","type":"address"},{"indexed":false,"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"DiamondCut","type":"event"},{"inputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"enum IDiamondCut.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"internalType":"struct IDiamondCut.FacetCut[]","name":"_diamondCut","type":"tuple[]"},{"internalType":"address","name":"_init","type":"address"},{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"diamondCut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_functionSelector","type":"bytes4"}],"name":"facetAddress","outputs":[{"internalType":"address","name":"facetAddress_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facetAddresses","outputs":[{"internalType":"address[]","name":"facetAddresses_","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_facet","type":"address"}],"name":"facetFunctionSelectors","outputs":[{"internalType":"bytes4[]","name":"_facetFunctionSelectors","type":"bytes4[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facets","outputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"internalType":"struct IDiamondLoupe.Facet[]","name":"facets_","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"length","type":"uint256"}],"name":"StringsInsufficientHexLength","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"indexed":false,"internalType":"string","name":"rangeName","type":"string"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeSplitsLength","type":"uint256"},{"indexed":false,"internalType":"bool","name":"visible","type":"bool"},{"indexed":false,"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"AddedMintingOffer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenIndex","type":"uint256"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"}],"name":"MintedToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeSplitsLength","type":"uint256"},{"indexed":false,"internalType":"bool","name":"visible","type":"bool"},{"indexed":false,"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"UpdatedMintingOffer","type":"event"},{"inputs":[{"internalType":"address","name":"erc721Address_","type":"address"},{"internalType":"uint256","name":"rangeIndex_","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[]","name":"splits","type":"tuple[]"},{"internalType":"bool","name":"visible_","type":"bool"},{"internalType":"address","name":"nodeAddress_","type":"address"}],"name":"addMintingOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc721Address_","type":"address"},{"internalType":"uint256[]","name":"rangeIndexes","type":"uint256[]"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[][]","name":"splits","type":"tuple[][]"},{"internalType":"bool[]","name":"visibility","type":"bool[]"},{"internalType":"address","name":"nodeAddress_","type":"address"}],"name":"addMintingOfferBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex_","type":"uint256"},{"internalType":"uint256","name":"tokenIndex_","type":"uint256"}],"name":"buyMintingOffer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex_","type":"uint256"},{"internalType":"uint256[]","name":"tokenIndexes","type":"uint256[]"},{"internalType":"address[]","name":"recipients","type":"address[]"}],"name":"buyMintingOfferBatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"getOfferInfo","outputs":[{"components":[{"internalType":"address","name":"erc721Address","type":"address"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[]","name":"fees","type":"tuple[]"},{"internalType":"bool","name":"visible","type":"bool"}],"internalType":"struct mintingOffer","name":"mintOffer","type":"tuple"},{"components":[{"internalType":"uint256","name":"rangeStart","type":"uint256"},{"internalType":"uint256","name":"rangeEnd","type":"uint256"},{"internalType":"uint256","name":"tokensAllowed","type":"uint256"},{"internalType":"uint256","name":"mintableTokens","type":"uint256"},{"internalType":"uint256","name":"lockedTokens","type":"uint256"},{"internalType":"uint256","name":"rangePrice","type":"uint256"},{"internalType":"string","name":"rangeName","type":"string"}],"internalType":"struct IRAIR721.range","name":"rangeData","type":"tuple"},{"internalType":"uint256","name":"productIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc721Address","type":"address"},{"internalType":"uint256","name":"rangeIndex","type":"uint256"}],"name":"getOfferInfoForAddress","outputs":[{"internalType":"uint256","name":"offerIndex","type":"uint256"},{"components":[{"internalType":"address","name":"erc721Address","type":"address"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"uint256","name":"rangeIndex","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[]","name":"fees","type":"tuple[]"},{"internalType":"bool","name":"visible","type":"bool"}],"internalType":"struct mintingOffer","name":"mintOffer","type":"tuple"},{"components":[{"internalType":"uint256","name":"rangeStart","type":"uint256"},{"internalType":"uint256","name":"rangeEnd","type":"uint256"},{"internalType":"uint256","name":"tokensAllowed","type":"uint256"},{"internalType":"uint256","name":"mintableTokens","type":"uint256"},{"internalType":"uint256","name":"lockedTokens","type":"uint256"},{"internalType":"uint256","name":"rangePrice","type":"uint256"},{"internalType":"string","name":"rangeName","type":"string"}],"internalType":"struct IRAIR721.range","name":"rangeData","type":"tuple"},{"internalType":"uint256","name":"productIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc721Address","type":"address"}],"name":"getOffersCountForAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalOfferCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"mintingOfferId_","type":"uint256"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bool","name":"canBeContract","type":"bool"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct feeSplits[]","name":"splits_","type":"tuple[]"},{"internalType":"bool","name":"visible_","type":"bool"}],"name":"updateMintingOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"decimals","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"precalculatedMultiplier","type":"uint256"}],"name":"UpdatedDecimals","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"decimals","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newPercentage","type":"uint256"}],"name":"UpdatedNodeFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAddress","type":"address"}],"name":"UpdatedTreasuryAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"decimals","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newPercentage","type":"uint256"}],"name":"UpdatedTreasuryFee","type":"event"},{"inputs":[],"name":"MAINTAINER","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDecimals","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getNodeFee","outputs":[{"internalType":"uint16","name":"decimals","type":"uint16"},{"internalType":"uint256","name":"nodeFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTreasuryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTreasuryFee","outputs":[{"internalType":"uint16","name":"decimals","type":"uint16"},{"internalType":"uint256","name":"treasuryFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"newDecimals_","type":"uint16"}],"name":"updateDecimals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFee_","type":"uint256"}],"name":"updateNodeFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress_","type":"address"}],"name":"updateTreasuryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFee_","type":"uint256"}],"name":"updateTreasuryFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"uint256","name":"token","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"offerId","type":"uint256"}],"name":"TokenOfferCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"offerId","type":"uint256"}],"name":"TokenOfferDeleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"offerId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTokenPrice","type":"uint256"}],"name":"TokenOfferUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"erc721Address","type":"address"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"uint256","name":"token","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenPrice","type":"uint256"}],"name":"TokenSold","type":"event"},{"inputs":[],"name":"RESALE_ADMIN","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"},{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"tokenPrice","type":"uint256"},{"internalType":"address","name":"nodeAddress","type":"address"}],"name":"createGasTokenOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"deleteGasTokenOffer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"},{"internalType":"address","name":"buyer","type":"address"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"tokenPrice","type":"uint256"},{"internalType":"address","name":"nodeAddress","type":"address"}],"name":"generateResaleHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"getResaleOffer","outputs":[{"components":[{"internalType":"address","name":"erc721","type":"address"},{"internalType":"address","name":"buyer","type":"address"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"tokenPrice","type":"uint256"},{"internalType":"address","name":"nodeAddress","type":"address"}],"internalType":"struct ResaleStorage.resaleOffer","name":"offer","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"}],"name":"getRoyalties","outputs":[{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct ResaleStorage.feeSplits[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex","type":"uint256"}],"name":"purchaseGasTokenOffer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"},{"internalType":"address","name":"buyer","type":"address"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"token","type":"uint256"},{"internalType":"uint256","name":"tokenPrice","type":"uint256"},{"internalType":"address","name":"nodeAddress","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"purchaseTokenOffer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setDecimalPow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"setPurchaseGracePeriod","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc721","type":"address"},{"components":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"percentage","type":"uint256"}],"internalType":"struct ResaleStorage.feeSplits[]","name":"fees","type":"tuple[]"}],"name":"setRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"offerIndex","type":"uint256"},{"internalType":"uint256","name":"newPrice","type":"uint256"}],"name":"updateGasTokenOffer","outputs":[],"stateMutability":"nonpayable","type":"function"}]} \ No newline at end of file diff --git a/rair-sync/bin/utils/eventCatcherMapping.js b/rair-sync/bin/utils/eventCatcherMapping.js index 3abe8dfd2..2e06b2fa7 100644 --- a/rair-sync/bin/utils/eventCatcherMapping.js +++ b/rair-sync/bin/utils/eventCatcherMapping.js @@ -33,6 +33,8 @@ const { updateMintingOffer, sellResaleOffer, createResaleOffer, + updateResaleOffer, + deleteResaleOffer, transferredToken, } = require('./eventCatcherUtils'); @@ -56,6 +58,8 @@ const insertionMapping = { UpdatedMintingOffer: updateMintingOffer, TokenSold: sellResaleOffer, TokenOfferCreated: createResaleOffer, + TokenOfferUpdated: updateResaleOffer, + TokenOfferDeleted: deleteResaleOffer, // Classic Factory NewContractDeployed: insertContract, diff --git a/rair-sync/bin/utils/eventCatcherUtils/deleteResaleOffer.js b/rair-sync/bin/utils/eventCatcherUtils/deleteResaleOffer.js new file mode 100644 index 000000000..d6a205bab --- /dev/null +++ b/rair-sync/bin/utils/eventCatcherUtils/deleteResaleOffer.js @@ -0,0 +1,22 @@ +const { ResaleTokenOffer, Contract } = require('../../models'); + +module.exports = async ( + transactionData, + // Contains + /* + network, + transactionHash, + fromAddress, + diamondEvent, + */ + offerId, +) => { + const contracts = await Contract.find({ blockchain: transactionData.network }, { _id: 1 }); + const foundOffer = await ResaleTokenOffer.findOneAndDelete({ + blockchainOfferId: offerId, + buyer: undefined, + tokenContract: { $in: contracts.map((item) => item._id) }, + }); + + return foundOffer; +}; diff --git a/rair-sync/bin/utils/eventCatcherUtils/index.js b/rair-sync/bin/utils/eventCatcherUtils/index.js index d81eeef12..7aa5fa615 100644 --- a/rair-sync/bin/utils/eventCatcherUtils/index.js +++ b/rair-sync/bin/utils/eventCatcherUtils/index.js @@ -16,6 +16,8 @@ const withdrawCredits = require('./witdrawCredits'); const updateMintingOffer = require('./updateMintingOffer'); const sellResaleOffer = require('./sellResaleOffer'); const createResaleOffer = require('./createResaleOffer'); +const updateResaleOffer = require('./updateResaleOffer'); +const deleteResaleOffer = require('./deleteResaleOffer'); const transferredToken = require('./transferredToken'); module.exports = { @@ -38,4 +40,6 @@ module.exports = { sellResaleOffer, createResaleOffer, transferredToken, + updateResaleOffer, + deleteResaleOffer, }; diff --git a/rair-sync/bin/utils/eventCatcherUtils/updateResaleOffer.js b/rair-sync/bin/utils/eventCatcherUtils/updateResaleOffer.js new file mode 100644 index 000000000..2bd567296 --- /dev/null +++ b/rair-sync/bin/utils/eventCatcherUtils/updateResaleOffer.js @@ -0,0 +1,27 @@ +const { ResaleTokenOffer, Contract } = require('../../models'); + +module.exports = async ( + transactionData, + // Contains + /* + network, + transactionHash, + fromAddress, + diamondEvent, + */ + offerId, + newPrice, +) => { + const contracts = await Contract.find({ blockchain: transactionData.network }, { _id: 1 }); + const foundOffer = await ResaleTokenOffer.findOneAndUpdate({ + blockchainOfferId: offerId, + buyer: undefined, + tokenContract: { $in: contracts.map((item) => item._id) }, + }, { + $set: { + price: newPrice, + }, + }); + + return foundOffer; +};