From 589097dc945c5d0e13b43b701d2961b40bad73c4 Mon Sep 17 00:00:00 2001 From: Aguwa Blessing <150056008+blessingbytes@users.noreply.github.com> Date: Sun, 26 Jan 2025 18:01:43 +0000 Subject: [PATCH 1/3] fix: domain navigation --- pages/identities/[tokenId].tsx | 156 +++++++++++++++++++++++++++------ 1 file changed, 129 insertions(+), 27 deletions(-) diff --git a/pages/identities/[tokenId].tsx b/pages/identities/[tokenId].tsx index 48a034e3..4b16c9a9 100644 --- a/pages/identities/[tokenId].tsx +++ b/pages/identities/[tokenId].tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useState } from "react"; +import React, { useCallback, useEffect, useMemo, useState } from "react"; import homeStyles from "../../styles/Home.module.css"; import styles from "../../styles/components/identitiesV1.module.css"; import { useRouter } from "next/router"; @@ -6,7 +6,11 @@ import { NextPage } from "next"; import IdentityWarnings from "../../components/identities/identityWarnings"; import IdentityCard from "../../components/identities/identityCard"; import IdentityActions from "../../components/identities/actions/identityActions"; -import { useAccount } from "@starknet-react/core"; +import { + useAccount, + useConnect, + useSendTransaction, +} from "@starknet-react/core"; import IdentityPageSkeleton from "../../components/identities/skeletons/identityPageSkeleton"; import UpdateProfilePic from "../../components/identities/updateProfilePic"; import TxConfirmationModal from "../../components/UI/txConfirmationModal"; @@ -16,6 +20,11 @@ import { formatHexString } from "../../utils/stringService"; import { getDomainData } from "@/utils/cacheDomainData"; import { useSearchParams } from "next/navigation"; import IdentityActionsSkeleton from "@/components/identities/skeletons/identityActionsSkeleton"; +import { hexToDecimal } from "@/utils/feltService"; +import AddButton from "@/components/UI/AddButtonIdentities"; +import WalletConnect from "@/components/UI/walletConnect"; +import { Connector } from "starknetkit"; +import { FaPlus } from "react-icons/fa"; const TokenIdPage: NextPage = () => { const router = useRouter(); @@ -34,6 +43,23 @@ const TokenIdPage: NextPage = () => { const [minting, setMinting] = useState(false); const searchParams = useSearchParams(); const mintingInUrl = searchParams.get("minting") === "true"; + const { connectAsync, connectors } = useConnect(); + const [ownedIdentities, setOwnedIdentities] = useState([]); + const randomTokenId: number = Math.floor(Math.random() * 1000000000000); + const [showWalletConnectModal, setShowWalletConnectModal] = + useState(false); + + const callData = useMemo(() => { + return { + contractAddress: process.env.NEXT_PUBLIC_IDENTITY_CONTRACT as string, + entrypoint: "mint", + calldata: [randomTokenId.toString()], + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + const { sendAsync: execute } = useSendTransaction({ + calls: [callData], + }); useEffect(() => { if (mintingInUrl) setMinting(true); @@ -126,6 +152,42 @@ const TokenIdPage: NextPage = () => { } }, [tokenId, refreshData]); + function mint() { + execute(); + } + useEffect(() => { + if (address) { + // Our Indexer + fetch( + `${ + process.env.NEXT_PUBLIC_SERVER_LINK + }/addr_to_full_ids?addr=${hexToDecimal(address)}` + ) + .then((response) => response.json()) + .then((data) => { + setOwnedIdentities(data.full_ids); + // setLoading(false); + }); + + // fetch( + // `${ + // process.env.NEXT_PUBLIC_SERVER_LINK + // }/addr_to_external_domains?addr=${hexToDecimal(address)}` + // ) + // .then((response) => response.json()) + // .then((data: ExternalDomains) => { + // setExternalDomains(data.domains); + // }); + } + }, [address, router.asPath]); + const connectWallet = async (connector: Connector) => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + await connectAsync({ connector }); + localStorage.setItem("SID-connectedWallet", connector.id); + localStorage.setItem("SID-lastUsedConnector", connector.id); + }; + //console.log({ router: router.query.tokenId, searchParams }); return ( <>
@@ -136,33 +198,67 @@ const TokenIdPage: NextPage = () => {
window.history.back()} />
-
- <> -
- setIsUpdatingPp(true)} - ppImageUrl={ppImageUrl} - /> - {!hideActions ? ( - +
+
+ {ownedIdentities.map((domain, index) => ( + + ))} +
+ +
+
+ <> +
+ setIsUpdatingPp(true)} + ppImageUrl={ppImageUrl} /> - ) : ( - minting && - )} -
- - + {!hideActions ? ( + + ) : ( + minting && + )} +
+ + +
) : ( @@ -180,6 +276,12 @@ const TokenIdPage: NextPage = () => { closeModal={() => setIsTxModalOpen(false)} title="Your new profile picture is being set !" /> + setShowWalletConnectModal(false)} + open={showWalletConnectModal} + connectors={connectors as Connector[]} + connectWallet={connectWallet} + /> ); }; From 346cfbc439e3a34033d3c491b0695174597bfb78 Mon Sep 17 00:00:00 2001 From: Aguwa Blessing <150056008+blessingbytes@users.noreply.github.com> Date: Tue, 28 Jan 2025 06:09:40 +0000 Subject: [PATCH 2/3] fix: domain navigation --- pages/identities.tsx | 6 ++++++ pages/identities/[tokenId].tsx | 16 ++-------------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/pages/identities.tsx b/pages/identities.tsx index a3382c83..7dd339d8 100644 --- a/pages/identities.tsx +++ b/pages/identities.tsx @@ -95,6 +95,12 @@ const Identities: NextPage = () => { execute(); } + useEffect(()=>{ + if(ownedIdentities.length > 0 ){ + router.push(`/identities/${ownedIdentities[0].id}`); + } + },[ownedIdentities,router]) + const connectWallet = async (connector: Connector) => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore diff --git a/pages/identities/[tokenId].tsx b/pages/identities/[tokenId].tsx index 4b16c9a9..58e1b5b2 100644 --- a/pages/identities/[tokenId].tsx +++ b/pages/identities/[tokenId].tsx @@ -166,18 +166,7 @@ const TokenIdPage: NextPage = () => { .then((response) => response.json()) .then((data) => { setOwnedIdentities(data.full_ids); - // setLoading(false); }); - - // fetch( - // `${ - // process.env.NEXT_PUBLIC_SERVER_LINK - // }/addr_to_external_domains?addr=${hexToDecimal(address)}` - // ) - // .then((response) => response.json()) - // .then((data: ExternalDomains) => { - // setExternalDomains(data.domains); - // }); } }, [address, router.asPath]); const connectWallet = async (connector: Connector) => { @@ -187,7 +176,6 @@ const TokenIdPage: NextPage = () => { localStorage.setItem("SID-connectedWallet", connector.id); localStorage.setItem("SID-lastUsedConnector", connector.id); }; - //console.log({ router: router.query.tokenId, searchParams }); return ( <>
@@ -202,7 +190,7 @@ const TokenIdPage: NextPage = () => {
{ownedIdentities.map((domain, index) => ( @@ -215,7 +203,7 @@ const TokenIdPage: NextPage = () => { key={index} onClick={() => router.push(`/identities/${domain.id}`)} > - {domain.id} + {domain.domain ? domain.domain : domain.id} ))}
From a71c12b31a2511a606fa930b83b154df96499f71 Mon Sep 17 00:00:00 2001 From: Aguwa Blessing <150056008+blessingbytes@users.noreply.github.com> Date: Tue, 28 Jan 2025 12:23:15 +0000 Subject: [PATCH 3/3] fear: add a reuseable component --- components/identities/availableIdentities.tsx | 272 +++++++++++++++++ pages/identities.tsx | 53 +--- pages/identities/[tokenId].tsx | 280 +----------------- 3 files changed, 296 insertions(+), 309 deletions(-) create mode 100644 components/identities/availableIdentities.tsx diff --git a/components/identities/availableIdentities.tsx b/components/identities/availableIdentities.tsx new file mode 100644 index 00000000..a507ad72 --- /dev/null +++ b/components/identities/availableIdentities.tsx @@ -0,0 +1,272 @@ +import React, { useCallback, useEffect, useMemo, useState } from "react"; +import homeStyles from "../../styles/Home.module.css"; +import styles from "../../styles/components/identitiesV1.module.css"; +import { useRouter } from "next/router"; +import IdentityWarnings from "../../components/identities/identityWarnings"; +import IdentityCard from "../../components/identities/identityCard"; +import IdentityActions from "../../components/identities/actions/identityActions"; +import { + useAccount, + useConnect, + useSendTransaction, +} from "@starknet-react/core"; +import IdentityPageSkeleton from "../../components/identities/skeletons/identityPageSkeleton"; +import UpdateProfilePic from "../../components/identities/updateProfilePic"; +import TxConfirmationModal from "../../components/UI/txConfirmationModal"; +import { Identity } from "../../utils/apiWrappers/identity"; +import { formatHexString } from "../../utils/stringService"; +import { getDomainData } from "@/utils/cacheDomainData"; +import { useSearchParams } from "next/navigation"; +import IdentityActionsSkeleton from "@/components/identities/skeletons/identityActionsSkeleton"; +import { hexToDecimal } from "@/utils/feltService"; +import WalletConnect from "@/components/UI/walletConnect"; +import { Connector } from "starknetkit"; +import { FaPlus } from "react-icons/fa"; + +const AvailableIdentities = ({ tokenId }: { tokenId: string }) => { + const router = useRouter(); + const { address } = useAccount(); + //const tokenId: string = router.query.tokenId as string; + const [identity, setIdentity] = useState(); + const [isIdentityADomain, setIsIdentityADomain] = useState< + boolean | undefined + >(); + const [hideActions, setHideActions] = useState(false); + const [isOwner, setIsOwner] = useState(true); + const [isUpdatingPp, setIsUpdatingPp] = useState(false); + const [isTxModalOpen, setIsTxModalOpen] = useState(false); + const [ppTxHash, setPpTxHash] = useState(); + const [ppImageUrl, setPpImageUrl] = useState(""); + const [minting, setMinting] = useState(false); + const searchParams = useSearchParams(); + const mintingInUrl = searchParams.get("minting") === "true"; + const { connectAsync, connectors } = useConnect(); + const [ownedIdentities, setOwnedIdentities] = useState([]); + const randomTokenId: number = Math.floor(Math.random() * 1000000000000); + const [showWalletConnectModal, setShowWalletConnectModal] = + useState(false); + + const callData = useMemo(() => { + return { + contractAddress: process.env.NEXT_PUBLIC_IDENTITY_CONTRACT as string, + entrypoint: "mint", + calldata: [randomTokenId.toString()], + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + const { sendAsync: execute } = useSendTransaction({ + calls: [callData], + }); + + useEffect(() => { + if (mintingInUrl) setMinting(true); + else setMinting(false); + }, [mintingInUrl]); + + const endMinting = useCallback(() => { + router.replace(router.asPath.split("?")[0]); + setMinting(false); + setHideActions(false); + }, [router]); + + useEffect(() => { + if (minting && identity) endMinting(); + }, [minting, identity, endMinting]); + + useEffect(() => { + if (!identity || !address) { + setIsOwner(false); + return; + } + setIsOwner(identity.ownerAddress === formatHexString(address)); + }, [identity, address]); + + useEffect(() => { + if (!identity) { + setPpImageUrl(""); + return; + } + + const fetchProfilePic = async () => { + try { + const imgUrl = await identity.getPfpFromVerifierData(); + setPpImageUrl(imgUrl); + } catch (error) { + setPpImageUrl(""); + } + }; + + fetchProfilePic(); + }, [identity]); + + const hideActionsHandler = (state: boolean) => { + if (state == true) { + setHideActions(true); + } else { + setHideActions(false); + } + }; + + const refreshData = useCallback( + () => + fetch(`${process.env.NEXT_PUBLIC_SERVER_LINK}/id_to_data?id=${tokenId}`) + .then(async (response) => { + if (!response.ok) { + throw new Error(await response.text()); + } + return response.json(); + }) + .then((data: IdentityData) => { + if (minting) endMinting(); + setIdentity(new Identity(data)); + setIsIdentityADomain(Boolean(data?.domain)); + }) + .catch(() => { + // Domain data might not be indexed yet, so we check local storage + const domainData = getDomainData(tokenId); + if (domainData) { + setIdentity(new Identity(domainData)); + setIsIdentityADomain(Boolean(domainData?.domain)); + } else { + setIsIdentityADomain(false); + } + }), + [tokenId, minting, endMinting] + ); + + useEffect(() => { + if (minting && tokenId && !identity) { + const interval = setInterval(() => refreshData(), 1000); + return () => clearInterval(interval); + } + }, [minting, tokenId, identity, refreshData]); + + useEffect(() => { + if (tokenId) { + refreshData(); + const timer = setInterval(() => refreshData(), 30e3); + return () => clearInterval(timer); + } + }, [tokenId, refreshData]); + + function mint() { + execute(); + } + useEffect(() => { + if (address) { + // Our Indexer + fetch( + `${ + process.env.NEXT_PUBLIC_SERVER_LINK + }/addr_to_full_ids?addr=${hexToDecimal(address)}` + ) + .then((response) => response.json()) + .then((data) => { + setOwnedIdentities(data.full_ids); + }); + } + }, [address, router.asPath]); + + const connectWallet = async (connector: Connector) => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + await connectAsync({ connector }); + localStorage.setItem("SID-connectedWallet", connector.id); + localStorage.setItem("SID-lastUsedConnector", connector.id); + }; + return ( + <> +
+ {isIdentityADomain === undefined ? ( + + ) : !isUpdatingPp ? ( +
+
+
+
+ {ownedIdentities.map((domain, index) => ( + + ))} +
+ +
+
+ <> +
+ setIsUpdatingPp(true)} + ppImageUrl={ppImageUrl} + /> + {!hideActions ? ( + + ) : ( + minting && + )} +
+ + +
+
+
+ ) : ( + setIsUpdatingPp(false)} + openTxModal={() => setIsTxModalOpen(true)} + setPfpTxHash={setPpTxHash} + /> + )} +
+ setIsTxModalOpen(false)} + title="Your new profile picture is being set !" + /> + setShowWalletConnectModal(false)} + open={showWalletConnectModal} + connectors={connectors as Connector[]} + connectWallet={connectWallet} + /> + + ); +}; + +export default AvailableIdentities; diff --git a/pages/identities.tsx b/pages/identities.tsx index 7dd339d8..f0b49568 100644 --- a/pages/identities.tsx +++ b/pages/identities.tsx @@ -7,18 +7,16 @@ import { useSendTransaction, } from "@starknet-react/core"; import { useEffect, useState } from "react"; -import IdentitiesGallery from "../components/identities/identitiesGalleryV1"; -import MintIcon from "../components/UI/iconsComponents/icons/mintIcon"; import { useRouter } from "next/router"; import { hexToDecimal } from "../utils/feltService"; import IdentitiesSkeleton from "../components/identities/skeletons/identitiesSkeleton"; import TxConfirmationModal from "../components/UI/txConfirmationModal"; -import ClickableAction from "../components/UI/iconsComponents/clickableAction"; import { useNotificationManager } from "../hooks/useNotificationManager"; import { NotificationType, TransactionType } from "../utils/constants"; import WalletConnect from "@/components/UI/walletConnect"; import { Connector } from "starknetkit"; import AddButton from "@/components/UI/AddButtonIdentities"; +import AvailableIdentities from "@/components/identities/availableIdentities"; const Identities: NextPage = () => { const { address } = useAccount(); @@ -95,12 +93,6 @@ const Identities: NextPage = () => { execute(); } - useEffect(()=>{ - if(ownedIdentities.length > 0 ){ - router.push(`/identities/${ownedIdentities[0].id}`); - } - },[ownedIdentities,router]) - const connectWallet = async (connector: Connector) => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore @@ -111,13 +103,13 @@ const Identities: NextPage = () => { return ( <> -
+
{loading ? ( ) : ownedIdentities.length + externalDomains.length === 0 || !address ? ( - <> +

All Your Identities in One Place

@@ -137,45 +129,22 @@ const Identities: NextPage = () => { } width="auto" /> */} - mint() - : () => setShowWalletConnectModal(true) - } radius="8px" -> - ADD IDENTITIES - - -
- - ) : ( -
- -
- {/* } + mint() : () => setShowWalletConnectModal(true) } - width="auto" - /> */} - mint() - : () => setShowWalletConnectModal(true) - } radius="8px" -> - ADD IDENTITIES + radius="8px" + > + ADD IDENTITIES
+ ) : ( +
+ +
)}
diff --git a/pages/identities/[tokenId].tsx b/pages/identities/[tokenId].tsx index 58e1b5b2..c8eb175e 100644 --- a/pages/identities/[tokenId].tsx +++ b/pages/identities/[tokenId].tsx @@ -1,277 +1,23 @@ -import React, { useCallback, useEffect, useMemo, useState } from "react"; +import React from "react"; +import AvailableIdentities from "@/components/identities/availableIdentities"; import homeStyles from "../../styles/Home.module.css"; -import styles from "../../styles/components/identitiesV1.module.css"; -import { useRouter } from "next/router"; import { NextPage } from "next"; -import IdentityWarnings from "../../components/identities/identityWarnings"; -import IdentityCard from "../../components/identities/identityCard"; -import IdentityActions from "../../components/identities/actions/identityActions"; -import { - useAccount, - useConnect, - useSendTransaction, -} from "@starknet-react/core"; -import IdentityPageSkeleton from "../../components/identities/skeletons/identityPageSkeleton"; -import UpdateProfilePic from "../../components/identities/updateProfilePic"; -import TxConfirmationModal from "../../components/UI/txConfirmationModal"; -import BackButton from "../../components/UI/backButton"; -import { Identity } from "../../utils/apiWrappers/identity"; -import { formatHexString } from "../../utils/stringService"; -import { getDomainData } from "@/utils/cacheDomainData"; -import { useSearchParams } from "next/navigation"; -import IdentityActionsSkeleton from "@/components/identities/skeletons/identityActionsSkeleton"; -import { hexToDecimal } from "@/utils/feltService"; -import AddButton from "@/components/UI/AddButtonIdentities"; -import WalletConnect from "@/components/UI/walletConnect"; -import { Connector } from "starknetkit"; -import { FaPlus } from "react-icons/fa"; +import { useRouter } from "next/router"; +import BackButton from "@/components/UI/backButton"; const TokenIdPage: NextPage = () => { const router = useRouter(); - const { address } = useAccount(); - const tokenId: string = router.query.tokenId as string; - const [identity, setIdentity] = useState(); - const [isIdentityADomain, setIsIdentityADomain] = useState< - boolean | undefined - >(); - const [hideActions, setHideActions] = useState(false); - const [isOwner, setIsOwner] = useState(true); - const [isUpdatingPp, setIsUpdatingPp] = useState(false); - const [isTxModalOpen, setIsTxModalOpen] = useState(false); - const [ppTxHash, setPpTxHash] = useState(); - const [ppImageUrl, setPpImageUrl] = useState(""); - const [minting, setMinting] = useState(false); - const searchParams = useSearchParams(); - const mintingInUrl = searchParams.get("minting") === "true"; - const { connectAsync, connectors } = useConnect(); - const [ownedIdentities, setOwnedIdentities] = useState([]); - const randomTokenId: number = Math.floor(Math.random() * 1000000000000); - const [showWalletConnectModal, setShowWalletConnectModal] = - useState(false); - - const callData = useMemo(() => { - return { - contractAddress: process.env.NEXT_PUBLIC_IDENTITY_CONTRACT as string, - entrypoint: "mint", - calldata: [randomTokenId.toString()], - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - const { sendAsync: execute } = useSendTransaction({ - calls: [callData], - }); - - useEffect(() => { - if (mintingInUrl) setMinting(true); - else setMinting(false); - }, [mintingInUrl]); - - const endMinting = useCallback(() => { - router.replace(router.asPath.split("?")[0]); - setMinting(false); - setHideActions(false); - }, [router]); - - useEffect(() => { - if (minting && identity) endMinting(); - }, [minting, identity, endMinting]); - - useEffect(() => { - if (!identity || !address) { - setIsOwner(false); - return; - } - setIsOwner(identity.ownerAddress === formatHexString(address)); - }, [identity, address]); - - useEffect(() => { - if (!identity) { - setPpImageUrl(""); - return; - } - - const fetchProfilePic = async () => { - try { - const imgUrl = await identity.getPfpFromVerifierData(); - setPpImageUrl(imgUrl); - } catch (error) { - setPpImageUrl(""); - } - }; - - fetchProfilePic(); - }, [identity]); - - const hideActionsHandler = (state: boolean) => { - if (state == true) { - setHideActions(true); - } else { - setHideActions(false); - } - }; - - const refreshData = useCallback( - () => - fetch(`${process.env.NEXT_PUBLIC_SERVER_LINK}/id_to_data?id=${tokenId}`) - .then(async (response) => { - if (!response.ok) { - throw new Error(await response.text()); - } - return response.json(); - }) - .then((data: IdentityData) => { - if (minting) endMinting(); - setIdentity(new Identity(data)); - setIsIdentityADomain(Boolean(data?.domain)); - }) - .catch(() => { - // Domain data might not be indexed yet, so we check local storage - const domainData = getDomainData(tokenId); - if (domainData) { - setIdentity(new Identity(domainData)); - setIsIdentityADomain(Boolean(domainData?.domain)); - } else { - setIsIdentityADomain(false); - } - }), - [tokenId, minting, endMinting] - ); - - useEffect(() => { - if (minting && tokenId && !identity) { - const interval = setInterval(() => refreshData(), 1000); - return () => clearInterval(interval); - } - }, [minting, tokenId, identity, refreshData]); - - useEffect(() => { - if (tokenId) { - refreshData(); - const timer = setInterval(() => refreshData(), 30e3); - return () => clearInterval(timer); - } - }, [tokenId, refreshData]); - - function mint() { - execute(); - } - useEffect(() => { - if (address) { - // Our Indexer - fetch( - `${ - process.env.NEXT_PUBLIC_SERVER_LINK - }/addr_to_full_ids?addr=${hexToDecimal(address)}` - ) - .then((response) => response.json()) - .then((data) => { - setOwnedIdentities(data.full_ids); - }); - } - }, [address, router.asPath]); - const connectWallet = async (connector: Connector) => { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - await connectAsync({ connector }); - localStorage.setItem("SID-connectedWallet", connector.id); - localStorage.setItem("SID-lastUsedConnector", connector.id); - }; + const tokenId: string = router.query.tokenId as string; return ( - <> -
- {isIdentityADomain === undefined ? ( - - ) : !isUpdatingPp ? ( -
-
- window.history.back()} /> -
-
-
-
- {ownedIdentities.map((domain, index) => ( - - ))} -
- -
-
- <> -
- setIsUpdatingPp(true)} - ppImageUrl={ppImageUrl} - /> - {!hideActions ? ( - - ) : ( - minting && - )} -
- - -
-
-
- ) : ( - setIsUpdatingPp(false)} - openTxModal={() => setIsTxModalOpen(true)} - setPfpTxHash={setPpTxHash} - /> - )} +
+
+
+ window.history.back()} /> +
+
- setIsTxModalOpen(false)} - title="Your new profile picture is being set !" - /> - setShowWalletConnectModal(false)} - open={showWalletConnectModal} - connectors={connectors as Connector[]} - connectWallet={connectWallet} - /> - +
); }; -export default TokenIdPage; +export default TokenIdPage; \ No newline at end of file