Skip to content

Commit

Permalink
Fix/hotfixes (#61)
Browse files Browse the repository at this point in the history
* add snackbar global component

* fix issue on onchain platform

* remove import
  • Loading branch information
mehdi-torabiv authored Aug 29, 2024
1 parent a6de7cc commit 4c3baa1
Show file tree
Hide file tree
Showing 9 changed files with 341 additions and 59 deletions.
9 changes: 7 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,14 @@ import { api } from './services/api';

import DefaultLayout from './layouts/DefaultLayout';

import Dashboard from './pages/Dashboard';
// import Dashboard from './pages/Dashboard';
import Identifiers from './pages/Identifiers';
import Permissions from './pages/Permissions';
import Attestation from './pages/Identifiers/Attestation';
import Callback from './pages/Callback';
import ProtectedRoute from './ProtectedRoute';
import { LitProvider } from './hooks/LitProvider';
import { CustomSnackbar } from './components/shared/CustomSnackbar';

const queryClient = new QueryClient({
defaultOptions: {
Expand Down Expand Up @@ -142,7 +143,10 @@ const App: React.FC = () => {
</ProtectedRoute>
}
>
<Route path="/" element={<Dashboard />} />
<Route
path="/"
element={<Navigate to="/identifiers" />}
/>
<Route path="/identifiers" element={<Identifiers />} />
<Route
path="identifiers/:providers/attestation"
Expand All @@ -153,6 +157,7 @@ const App: React.FC = () => {
<Route path="/callback" element={<Callback />} />
<Route path="*" element={<div>Not found</div>} />
</Routes>
<CustomSnackbar />
</ThemeProvider>
</RainbowKitProvider>
</RainbowKitAuthenticationProvider>
Expand Down
10 changes: 10 additions & 0 deletions src/ProtectedRoute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useEffect, useState } from 'react';
import { Navigate } from 'react-router-dom';
import CircularProgress from '@mui/material/CircularProgress';
import Backdrop from '@mui/material/Backdrop';
import { useAccount } from 'wagmi';

interface ProtectedRouteProps {
children: JSX.Element;
Expand All @@ -11,6 +12,15 @@ const ProtectedRoute = ({ children }: ProtectedRouteProps) => {
const [loading, setLoading] = useState<boolean>(true);
const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);

const { isConnected } = useAccount();

useEffect(() => {
if (!isConnected) {
setIsAuthenticated(false);
localStorage.removeItem('OCI_TOKEN');
}
}, [isConnected]);

useEffect(() => {
const checkAuthStatus = async () => {
const token = localStorage.getItem('OCI_TOKEN');
Expand Down
33 changes: 33 additions & 0 deletions src/components/shared/CustomSnackbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Snackbar, Alert } from '@mui/material';

import useSnackbarStore from '../../store/useSnackbarStore';

/**
* CustomSnackbar component displays a Snackbar using Material-UI's Snackbar component.
* It uses Zustand store for managing Snackbar state globally.
*
* @returns {JSX.Element} The rendered CustomSnackbar component.
*/
export const CustomSnackbar = (): JSX.Element => {
const { message, open, options, closeSnackbar } = useSnackbarStore();

return (
<Snackbar
anchorOrigin={
options?.position || { vertical: 'bottom', horizontal: 'right' }
}
autoHideDuration={options?.duration}
open={open}
onClose={closeSnackbar}
>
<Alert
severity={options?.severity || 'info'}
sx={{ width: '100%' }}
variant="filled"
onClose={closeSnackbar}
>
{message}
</Alert>
</Snackbar>
);
};
12 changes: 6 additions & 6 deletions src/libs/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import SpaceDashboardIcon from '@mui/icons-material/SpaceDashboard';
// import SpaceDashboardIcon from '@mui/icons-material/SpaceDashboard';
import FingerprintIcon from '@mui/icons-material/Fingerprint';
import { SiAdguard } from 'react-icons/si';
import { SvgIconComponent } from '@mui/icons-material';
Expand All @@ -13,11 +13,11 @@ export interface MenuItem {
export const DRAWER_WIDTH = 240;

export const SIDEBAR_MENU: MenuItem[] = [
{
title: 'Dashboard',
path: '/',
icon: SpaceDashboardIcon,
},
// {
// title: 'Dashboard',
// path: '/',
// icon: SpaceDashboardIcon,
// },
{
title: 'Identifiers',
path: '/identifiers',
Expand Down
21 changes: 20 additions & 1 deletion src/pages/Identifiers/Attestation/Attestation.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { useState, useEffect } from 'react';
import Paper from '@mui/material/Paper';
import Typography from '@mui/material/Typography';
Expand All @@ -21,6 +22,7 @@ import {
convertStringsToBigInts,
getTokenForProvider,
} from '../../../utils/helper';
import useSnackbarStore from '../../../store/useSnackbarStore';

const steps = [{ label: 'Auth' }, { label: 'Attest' }, { label: 'Transact' }];

Expand All @@ -31,7 +33,7 @@ type DecodedToken = { provider: Provider; iat: number; exp: number };
export function Attestation() {
const { isConnected, address } = useAccount();
const signer = useSigner();

const { showSnackbar } = useSnackbarStore();
const { providers } = useParams<{ providers: 'DISCORD' | 'GOOGLE' }>();
const location = useLocation();
const navigate = useNavigate();
Expand Down Expand Up @@ -149,9 +151,26 @@ export function Attestation() {

const newAttestationUID = await tx.wait();

showSnackbar('Attestation created successfully', {
severity: 'success',
});

navigate('/identifiers');

console.log('New attestation UID:', newAttestationUID);

console.log('Transaction receipt:', tx.receipt);
} catch (error: any) {
const errorCode = error?.info?.error?.code || '';

if (errorCode === 4001) {
showSnackbar(
`${errorCode}, you reject the transaction. please try again...`,
{
severity: 'error',
}
);
}
} finally {
setIsAttesting(false);
}
Expand Down
99 changes: 75 additions & 24 deletions src/pages/Identifiers/Identifiers.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable react-hooks/exhaustive-deps */
import React, { useEffect, useState, useCallback } from 'react';
import {
List,
Expand All @@ -12,6 +14,8 @@ import {
Avatar,
CircularProgress,
IconButton,
Backdrop,
Stack,
} from '@mui/material';
import VerifiedIcon from '@mui/icons-material/Verified';
import VisibilityIcon from '@mui/icons-material/Visibility';
Expand All @@ -35,6 +39,7 @@ import {
} from '../../services/api/eas/query';
import { RevokePayload } from '../../interfaces';
import { convertStringsToBigInts } from '../../utils/helper';
import useSnackbarStore from '../../store/useSnackbarStore';

interface IdentifierItemProps {
identifier: {
Expand Down Expand Up @@ -79,22 +84,24 @@ const IdentifierItem: React.FC<IdentifierItemProps> = ({
<VerifiedIcon sx={{ color: 'blue', mr: 1 }} />
)}
<Typography>{identifier.name}</Typography>
<div className="ml-3">
{isRevealedPending ? (
<CircularProgress size={24} />
) : (
<>
{isRevealed !== '*********' ? isRevealed : '*********'}
<IconButton onClick={onReveal} sx={{ ml: 1 }}>
{isRevealed !== '*********' ? (
<VisibilityOffIcon />
) : (
<VisibilityIcon />
)}
</IconButton>
</>
)}
</div>
{identifier.verified && (
<div className="ml-3">
{isRevealedPending ? (
<CircularProgress size={24} />
) : (
<>
{isRevealed !== '*********' ? isRevealed : '*********'}
<IconButton onClick={onReveal} sx={{ ml: 1 }}>
{isRevealed !== '*********' ? (
<VisibilityOffIcon />
) : (
<VisibilityIcon />
)}
</IconButton>
</>
)}
</div>
)}
</div>
}
sx={{ ml: 2 }}
Expand All @@ -103,7 +110,7 @@ const IdentifierItem: React.FC<IdentifierItemProps> = ({
{identifier.verified ? (
<Button
variant="outlined"
color="error"
color="inherit"
onClick={() => onRevoke(identifier.uid)}
disabled={isLoading}
startIcon={isLoading ? <CircularProgress size={16} /> : null}
Expand All @@ -126,7 +133,10 @@ const IdentifierItem: React.FC<IdentifierItemProps> = ({
);

export function Identifiers() {
const { showSnackbar } = useSnackbarStore();
const { chainId } = useAccount();
const navigate = useNavigate();

const signer = useSigner();

const [identifiers, setIdentifiers] = useState([
Expand All @@ -142,7 +152,11 @@ export function Identifiers() {
const [attestations, setAttestations] = useState<
(IAttestation & { provider?: string; id?: string })[]
>([]);
const { data: attestationsResponse, refetch } = useGetAttestations();
const {
data: attestationsResponse,
refetch,
isLoading,
} = useGetAttestations();

const { mutate: mutateRevokeIdentifier, data: revokeIdentifierResponse } =
useRevokeIdentifierMutation();
Expand Down Expand Up @@ -217,8 +231,6 @@ export function Identifiers() {
setRevealedIdentifiers(initialRevealedState);
}, [attestations]);

const navigate = useNavigate();

const handleRevoke = useCallback(
(uid: string) => {
const siweJwt = localStorage.getItem('OCI_TOKEN');
Expand Down Expand Up @@ -298,7 +310,7 @@ export function Identifiers() {
useEffect(() => {
const revokeIdentifier = async () => {
if (revokeIdentifierResponse) {
console.log('Revoke identifier response', revokeIdentifierResponse);
console.log('Revoke identifier response:', revokeIdentifierResponse);

const payload: RevokePayload = convertStringsToBigInts(
revokeIdentifierResponse.data
Expand Down Expand Up @@ -328,8 +340,12 @@ export function Identifiers() {
};

const tx = await eas.revokeByDelegation(transformedPayload);

await tx.wait();
console.log({ tx });

showSnackbar('Identifier revoked successfully', {
severity: 'success',
});

setLoadingIdentifiers((prev) => ({
...prev,
Expand All @@ -338,8 +354,17 @@ export function Identifiers() {
} else {
throw new Error('Invalid message type for revocation');
}
} catch (error) {
console.error('Error during revocation:', error);
} catch (error: any) {
const errorCode = error?.info?.error?.code || '';

if (errorCode === 4001) {
showSnackbar(
`${errorCode}, you reject the transaction. please try again...`,
{
severity: 'error',
}
);
}

if ('uid' in payload.message) {
setLoadingIdentifiers((prev) => ({
Expand All @@ -356,6 +381,32 @@ export function Identifiers() {
revokeIdentifier();
}, [revokeIdentifierResponse]);

if (isLoading) {
return (
<Backdrop
open={isLoading}
sx={{
zIndex: (theme) => theme.zIndex.drawer + 1,
background: '#fff',
color: 'black',
}}
>
<Stack
sx={{
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
}}
>
<CircularProgress color="inherit" />
<Typography variant="h6" gutterBottom style={{ marginLeft: '15px' }}>
Loading...
</Typography>
</Stack>
</Backdrop>
);
}

return (
<div>
<Typography variant="h6" gutterBottom>
Expand Down
Loading

0 comments on commit 4c3baa1

Please sign in to comment.