From c561fd34959d5bd1ba3ae872fb64dc7790b88223 Mon Sep 17 00:00:00 2001 From: Mehdi Torabi <46302001+mehdi-torabiv@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:57:15 +0300 Subject: [PATCH] Fix/public page view (#360) * update announcements * replace Tctext * update oci * update url * update * fix * fix public page view * fix * fix * fix public view page --------- Co-authored-by: Cyrille <1618640+cyri113@users.noreply.github.com> --- package-lock.json | 8 +- package.json | 2 +- src/pages/announcements/index.tsx | 38 ++++++--- src/pages/not-found.tsx | 68 ++++++++++++++++ src/pages/reputation-score/index.tsx | 2 +- src/pages/reputation-score/mint.tsx | 67 ++++++++++------ .../{[...score].tsx => score.tsx} | 77 ++++++++++--------- src/utils/withRoles.tsx | 11 ++- 8 files changed, 193 insertions(+), 80 deletions(-) create mode 100644 src/pages/not-found.tsx rename src/pages/reputation-score/{[...score].tsx => score.tsx} (74%) diff --git a/package-lock.json b/package-lock.json index c6f023c9..70724208 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,7 +45,7 @@ "moment-timezone": "^0.5.38", "next": "^14.2.18", "next-router-mock": "^0.9.9", - "oci-js-sdk": "^1.6.1", + "oci-js-sdk": "^1.6.3", "papaparse": "^5.4.1", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -21268,9 +21268,9 @@ "license": "MIT" }, "node_modules/oci-js-sdk": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/oci-js-sdk/-/oci-js-sdk-1.6.1.tgz", - "integrity": "sha512-SJCjGutEo0mgXsQ1w9NSww7xWiMQ5ZOQsor9ufUBC6NjExxk3Yb8etd6MNMWoa1InISpxhNtu/REIEFwBeK1Yg==", + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/oci-js-sdk/-/oci-js-sdk-1.6.3.tgz", + "integrity": "sha512-qxel2knoiHReFvw/I5vNqo9/dSHRz3bzX1J3WmGnHLqlrupR1KNSXfxfNSwyjRF8eJjzDLMpJ+DSKZPOANO4zA==", "license": "ISC", "dependencies": { "@ethereum-attestation-service/eas-sdk": "^2.7.0", diff --git a/package.json b/package.json index 5559f2fb..830deb38 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "moment-timezone": "^0.5.38", "next": "^14.2.18", "next-router-mock": "^0.9.9", - "oci-js-sdk": "^1.6.1", + "oci-js-sdk": "^1.6.3", "papaparse": "^5.4.1", "react": "^18.3.1", "react-dom": "^18.3.1", diff --git a/src/pages/announcements/index.tsx b/src/pages/announcements/index.tsx index a069cdce..3364a5ec 100644 --- a/src/pages/announcements/index.tsx +++ b/src/pages/announcements/index.tsx @@ -1,4 +1,5 @@ import React, { useEffect, useState } from 'react'; +import { Link, Stack, Typography } from '@mui/material'; import moment from 'moment'; import Image from 'next/image'; import router from 'next/router'; @@ -18,7 +19,6 @@ import TcBoxContainer from '../../components/shared/TcBox/TcBoxContainer'; import TcButton from '../../components/shared/TcButton'; import TcDatePickerPopover from '../../components/shared/TcDatePickerPopover'; import TcPagination from '../../components/shared/TcPagination'; -import TcText from '../../components/shared/TcText'; import { useToken } from '../../context/TokenContext'; import { defaultLayout } from '../../layouts/defaultLayout'; import { StorageService } from '../../services/StorageService'; @@ -195,11 +195,27 @@ function Index() {
- + + + Announcement Scheduling + + + smart announcements allow you to send targeted messages to + specific user segments.{' '} + + Learn more + + + } - variant='outlined' + variant='contained' onClick={() => router.push('/announcements/create-new-announcements') } @@ -239,16 +255,16 @@ function Index() {
) : (
- - + No announcements yet + + + > + Your announcements will show up for the month and timezone + selected once you create them{' '} +
)}
diff --git a/src/pages/not-found.tsx b/src/pages/not-found.tsx new file mode 100644 index 00000000..bb7eba4b --- /dev/null +++ b/src/pages/not-found.tsx @@ -0,0 +1,68 @@ +import Image from 'next/image'; +import { useRouter } from 'next/router'; + +import notFounded from '../assets/svg/404.svg'; +import tcLogo from '../assets/svg/tc-logo.svg'; +import TcButton from '../components/shared/TcButton'; + +const NotFound = () => { + const router = useRouter(); + + return ( +
+
+ Image Alt +
+
+
+ Image Alt +
+
+

+ Oops! We’re sorry, we couldn’t find
the page you’re looking + for. +

+
+

What could have caused this?

+
+

+ The link you clicked might be old and does not work anymore. +

+

+ Or you might have accidentally typed the wrong URL in the + address bar. +

+
+
+
+

What you can do

+

+ You might retype the URL or try some helpful links instead: +

+
+
+ router.push('/')} + className='py-2 md:w-1/2' + /> + router.push('/centric')} + variant='outlined' + text='Connect your community' + className='py-2 md:w-1/2' + /> +
+
+
+
+ ); +}; + +export default NotFound; diff --git a/src/pages/reputation-score/index.tsx b/src/pages/reputation-score/index.tsx index 847212c6..eb03a45d 100644 --- a/src/pages/reputation-score/index.tsx +++ b/src/pages/reputation-score/index.tsx @@ -86,7 +86,7 @@ function ReputationScore() { color='primary' onClick={() => router.push( - `/reputation-score/${dynamicNFTModuleInfo?.metadata[0]?.tokenId}/${address}/score` + `/reputation-score/score?tokenId=${dynamicNFTModuleInfo?.metadata[0]?.tokenId}&address=${address}` ) } disabled={!isConnected} diff --git a/src/pages/reputation-score/mint.tsx b/src/pages/reputation-score/mint.tsx index 3a8d5107..147a05aa 100644 --- a/src/pages/reputation-score/mint.tsx +++ b/src/pages/reputation-score/mint.tsx @@ -73,6 +73,7 @@ function Mint() { address, conf.APP_DEVELOPER_PUBLIC_ADDRESS as `0x${string}` ); + setUserProfile(result); setLoading(false); } catch (error) { @@ -168,9 +169,8 @@ const AttestationSection: React.FC = ({ isLoading, userProfile, }) => { - const handleNavigation = () => { - const url = 'https://identity-on-chain-platform.pages.dev/permissions'; + const url = 'https://app.logid.xyz/permissions'; window.open(url, '_blank'); }; return ( @@ -246,7 +246,7 @@ const MintSection: React.FC = ({ const { address } = useAccount(); const { dynamicNFTModuleInfo } = useAppStore(); - const { data: hasMinted } = useReadContract({ + const { data: hasMinted, refetch } = useReadContract({ address: engagementContract?.address as `0x${string}`, abi: engagementContract?.abi as Abi, functionName: 'balanceOf', @@ -259,10 +259,39 @@ const MintSection: React.FC = ({ isPending, } = useWriteContract(); - const { isPending: isWaiting } = useWaitForTransactionReceipt({ + const handleMintNFT = async () => { + try { + await writeContractAsync({ + address: engagementContract?.address as `0x${string}`, + abi: engagementContract?.abi as Abi, + functionName: 'mint', + args: [address, dynamicNFTModuleInfo.metadata[0].tokenId, 1, '0x0'], + }); + } catch (error: any) { + console.error('Mint failed:', error); + } + }; + + const { + data: receipt, + isSuccess, + isError, + isFetching: isWaitingForReceiptConfirmation, + } = useWaitForTransactionReceipt({ hash: transactionHash, }); + useEffect(() => { + if (receipt && isSuccess) { + showMessage( + 'Your Reputation NFT has been successfully minted!', + 'success' + ); + + refetch(); + } + }, [receipt, isSuccess, isError]); + return ( @@ -315,26 +344,16 @@ const MintSection: React.FC = ({ )} @@ -346,7 +365,7 @@ const UserProfileBox: React.FC = ({ profile }) => { const router = useRouter(); const handleNavigation = () => { - const url = 'https://identity-on-chain-platform.pages.dev/permissions'; + const url = 'https://app.logid.xyz/permissions'; router.push(url); }; diff --git a/src/pages/reputation-score/[...score].tsx b/src/pages/reputation-score/score.tsx similarity index 74% rename from src/pages/reputation-score/[...score].tsx rename to src/pages/reputation-score/score.tsx index 965c2cb7..80dd6ffa 100644 --- a/src/pages/reputation-score/[...score].tsx +++ b/src/pages/reputation-score/score.tsx @@ -1,5 +1,6 @@ +'use client'; + import React, { useEffect, useState } from 'react'; -import { useRouter } from 'next/router'; import { FiShare2 } from 'react-icons/fi'; import GaugeChart from '@/components/global/GaugeChart'; @@ -14,54 +15,43 @@ import { useSnackbar } from '@/context/SnackbarContext'; const ScorePage = () => { const { showMessage } = useSnackbar(); const { retrieveReputationScore } = useAppStore(); - const router = useRouter(); const [communityName, setCommunityName] = useState(null); const [reputationScore, setReputationScore] = useState(null); const [loading, setLoading] = useState(true); - const [tokenId, setTokenId] = useState(null); - const [address, setAddress] = useState(null); + const [error, setError] = useState(null); useEffect(() => { - const parseUrl = () => { - const pathSegments = router.asPath.split('/'); - const tokenIndex = pathSegments.indexOf('reputation-score') + 1; - - if (tokenIndex > 0 && tokenIndex + 1 < pathSegments.length) { - setTokenId(pathSegments[tokenIndex]); - setAddress(pathSegments[tokenIndex + 1]); + const fetchReputationScore = async (tokenId: string, address: string) => { + setLoading(true); + setError(null); + + try { + const score = await retrieveReputationScore({ tokenId, address }); + + setReputationScore(score.reputationScore ?? 0); + setCommunityName(score.communityName); + } catch (err) { + console.error('Error fetching reputation score:', err); + setError('Failed to fetch reputation score.'); + } finally { + setLoading(false); } }; - parseUrl(); - }, [router.asPath]); + // Use URLSearchParams to extract query parameters + const params = new URLSearchParams(window.location.search); + const tokenId = params.get('tokenId'); + const address = params.get('address'); - useEffect(() => { - if (tokenId && address) { - const fetchReputationScore = async () => { - setLoading(true); - try { - console.log('Fetching reputation score for:', { tokenId, address }); - - const score = await retrieveReputationScore({ - tokenId, - address, - }); - - console.log('Reputation Score Retrieved:', score); - setReputationScore(score.reputationScore ?? 0); - setCommunityName(score.communityName); - } catch (error) { - console.error('Error fetching reputation score:', error); - showMessage('Failed to load reputation score.', 'error'); - } finally { - setLoading(false); - } - }; - - fetchReputationScore(); + if (!tokenId || !address) { + setError('Invalid URL format. Missing tokenId or address.'); + setLoading(false); + return; } - }, [tokenId, address]); + + fetchReputationScore(tokenId, address); + }, [retrieveReputationScore]); const gaugeOptions = { chart: { @@ -129,6 +119,17 @@ const ScorePage = () => { return ; } + if (error) { + return ( +
+
+

Error

+

{error}

+
+
+ ); + } + return ( <> diff --git a/src/utils/withRoles.tsx b/src/utils/withRoles.tsx index 84c1b6e8..87eb12d3 100644 --- a/src/utils/withRoles.tsx +++ b/src/utils/withRoles.tsx @@ -1,3 +1,5 @@ +'use client'; + import React, { ComponentType, FunctionComponent, @@ -6,6 +8,8 @@ import React, { } from 'react'; import { useRouter } from 'next/router'; +import SimpleBackdrop from '@/components/global/LoadingBackdrop'; + import useAppStore from '../store/useStore'; interface WithRolesProps { @@ -21,7 +25,7 @@ interface ComponentWithLayout

extends FunctionComponent

{ export function withRoles

( Component: ComponentWithLayout

, - requiredPermissions: string[] + requiredPermissions: string[] = [] ): ComponentWithLayout

{ const WithRolesWrapper: ComponentWithLayout

= (props) => { const userPermissions = useAppStore( @@ -31,6 +35,11 @@ export function withRoles

( const router = useRouter(); useEffect(() => { + if (requiredPermissions.length === 0) { + setIsPermissionLoaded(true); + return; + } + const hasPermission = requiredPermissions.some((permission) => userPermissions.includes(permission) );