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 (
+
+
+
+
+
+
+
+
+
+
+ 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 (
+
+ );
+ }
+
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)
);