diff --git a/govtool/frontend/src/App.tsx b/govtool/frontend/src/App.tsx index 7db190366..9e7b9300e 100644 --- a/govtool/frontend/src/App.tsx +++ b/govtool/frontend/src/App.tsx @@ -4,6 +4,7 @@ import { Route, Routes, useNavigate } from "react-router-dom"; import { Modal, ScrollToTop } from "@atoms"; import { PATHS } from "@consts"; import { useCardano, useModal } from "@context"; +import { useWalletConnectionListener } from "@hooks"; import { DashboardCards, DashboardGovernanceActions, @@ -11,28 +12,28 @@ import { } from "@organisms"; import { ChooseStakeKey, + CreateGovernanceAction, Dashboard, - ErrorPage, - Home, - GovernanceActions, + DashboardGovernanceActionsCategory, DelegateTodRep, - RegisterAsdRep, + ErrorPage, GovernanceActionDetails, - UpdatedRepMetadata, + GovernanceActions, GovernanceActionsCategory, - DashboardGovernanceActionsCategory, + Home, + RegisterAsdRep, + RegisterAsSoleVoter, + RetireAsDrep, RetireAsSoleVoter, + UpdatedRepMetadata, } from "@pages"; +import { SetupInterceptors } from "@services"; import { callAll, getItemFromLocalStorage, WALLET_LS_KEY, removeItemFromLocalStorage, } from "@utils"; -import { SetupInterceptors } from "./services"; -import { useWalletConnectionListener } from "./hooks"; -import { RegisterAsSoleVoter } from "./pages/RegisterAsSoleVoter"; -import { CreateGovernanceAction } from "./pages/CreateGovernanceAction"; export default () => { const { enable } = useCardano(); @@ -110,6 +111,7 @@ export default () => { /> } /> } /> + } /> } @@ -126,8 +128,8 @@ export default () => { handleClose={ !modals[modal.type].preventDismiss ? callAll(modals[modal.type]?.onClose, () => - openModal({ type: "none", state: null }), - ) + openModal({ type: "none", state: null }), + ) : undefined } > diff --git a/govtool/frontend/src/components/organisms/DashboardCards.tsx b/govtool/frontend/src/components/organisms/DashboardCards.tsx index fd684fd6b..98a99630d 100644 --- a/govtool/frontend/src/components/organisms/DashboardCards.tsx +++ b/govtool/frontend/src/components/organisms/DashboardCards.tsx @@ -1,10 +1,10 @@ -import { useCallback, useMemo, useState } from "react"; +import { useCallback, useMemo } from "react"; import { useNavigate } from "react-router-dom"; import { Box, CircularProgress } from "@mui/material"; import { Trans } from "react-i18next"; import { IMAGES, PATHS } from "@consts"; -import { useCardano, useModal } from "@context"; +import { useCardano } from "@context"; import { useGetAdaHolderVotingPowerQuery, useScreenDimension, @@ -17,8 +17,6 @@ import { correctAdaFormat, formHexToBech32, openInNewTab } from "@utils"; export const DashboardCards = () => { const { - buildDRepRetirementCert, - buildSignSubmitConwayCertTx, dRepID, dRepIDBech32, isPendingTransaction, @@ -28,67 +26,10 @@ export const DashboardCards = () => { const navigate = useNavigate(); const { currentDelegation } = useGetAdaHolderCurrentDelegationQuery(stakeKey); const { screenWidth } = useScreenDimension(); - const { openModal } = useModal(); - const [isRetirementLoading, setIsRetirementLoading] = - useState(false); const { votingPower } = useGetAdaHolderVotingPowerQuery(stakeKey); const { t } = useTranslation(); const { voter } = useGetVoterInfo(); - const retireAsDrep = useCallback(async () => { - try { - setIsRetirementLoading(true); - const isPendingTx = isPendingTransaction(); - - if (isPendingTx) return; - if (!voter?.deposit) throw new Error("Can not get deposit"); - - const certBuilder = await buildDRepRetirementCert( - voter.deposit.toString(), - ); - const result = await buildSignSubmitConwayCertTx({ - certBuilder, - type: "retireAsDrep", - voterDeposit: voter.deposit.toString(), - }); - if (result) { - openModal({ - type: "statusModal", - state: { - status: "success", - title: t("modals.retirement.title"), - message: t("modals.retirement.message"), - link: `https://adanordic.com/latest_transactions`, - buttonText: t("modals.common.goToDashboard"), - dataTestId: "retirement-transaction-submitted-modal", - }, - }); - } - // eslint-disable-next-line @typescript-eslint/no-explicit-any - } catch (error: any) { - const errorMessage = error.info ? error.info : error; - - openModal({ - type: "statusModal", - state: { - status: "warning", - message: errorMessage, - buttonText: t("modals.common.goToDashboard"), - title: t("modals.common.oops"), - dataTestId: "retirement-transaction-error-modal", - }, - }); - } finally { - setIsRetirementLoading(false); - } - }, [ - buildDRepRetirementCert, - buildSignSubmitConwayCertTx, - isPendingTransaction, - openModal, - voter?.deposit, - ]); - const delegationDescription = useMemo(() => { const correctAdaRepresentation = correctAdaFormat(votingPower); if (currentDelegation === dRepID) { @@ -416,12 +357,13 @@ export const DashboardCards = () => { : "register-learn-more-button" } description={registrationCardDescription} - firstButtonAction={ - voter?.isRegisteredAsDRep - ? retireAsDrep - : () => navigateTo(PATHS.registerAsdRep) + firstButtonAction={() => + navigateTo( + voter?.isRegisteredAsDRep + ? PATHS.retireAsDrep + : PATHS.registerAsdRep, + ) } - firstButtonIsLoading={isRetirementLoading} firstButtonLabel={ pendingTransaction.registerAsDrep || pendingTransaction.retireAsDrep ? "" diff --git a/govtool/frontend/src/components/organisms/RegisterAsDRepSteps/WhatRetirementMeans.tsx b/govtool/frontend/src/components/organisms/RegisterAsDRepSteps/WhatRetirementMeans.tsx new file mode 100644 index 000000000..23f0fe766 --- /dev/null +++ b/govtool/frontend/src/components/organisms/RegisterAsDRepSteps/WhatRetirementMeans.tsx @@ -0,0 +1,112 @@ +import { useCallback, useState } from "react"; + +import { Typography } from "@atoms"; +import { useCardano, useModal } from "@context"; +import { useGetVoterInfo, useScreenDimension, useTranslation } from "@hooks"; + +import { BgCard } from ".."; + +export const WhatRetirementMeans = ({ + onClickCancel, +}: { + onClickCancel: () => void; +}) => { + const { + isPendingTransaction, + buildDRepRetirementCert, + buildSignSubmitConwayCertTx, + } = useCardano(); + const { t } = useTranslation(); + const { isMobile } = useScreenDimension(); + const { closeModal, openModal } = useModal(); + const [isRetirementLoading, setIsRetirementLoading] = + useState(false); + const { voter } = useGetVoterInfo(); + + const onSubmit = () => { + onClickCancel(); + closeModal(); + }; + + const retireAsDrep = useCallback(async () => { + try { + setIsRetirementLoading(true); + const isPendingTx = isPendingTransaction(); + if (isPendingTx) return; + if (!voter?.deposit) throw new Error(t("errors.appCannotGetDeposit")); + + const certBuilder = await buildDRepRetirementCert( + voter?.deposit.toString(), + ); + const result = await buildSignSubmitConwayCertTx({ + certBuilder, + type: "retireAsDrep", + voterDeposit: voter?.deposit.toString(), + }); + if (result) { + openModal({ + type: "statusModal", + state: { + buttonText: t("modals.common.goToDashboard"), + dataTestId: "retirement-transaction-submitted-modal", + link: "https://adanordic.com/latest_transactions", + message: t("modals.retirement.message"), + onSubmit, + status: "success", + title: t("modals.retirement.title"), + }, + }); + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } catch (error: any) { + const errorMessage = error.info ? error.info : error; + + openModal({ + type: "statusModal", + state: { + buttonText: t("modals.common.goToDashboard"), + dataTestId: "retirement-transaction-error-modal", + message: errorMessage, + onSubmit, + status: "warning", + title: t("modals.common.oops"), + }, + }); + } finally { + setIsRetirementLoading(false); + } + }, [ + buildDRepRetirementCert, + buildSignSubmitConwayCertTx, + isPendingTransaction, + openModal, + voter?.deposit, + ]); + + return ( + + + {t("retirement.whatRetirementMeansTitle")} + + + {t("retirement.whatRetirementMeansDescription")} + + + ); +}; diff --git a/govtool/frontend/src/components/organisms/RegisterAsDRepSteps/index.ts b/govtool/frontend/src/components/organisms/RegisterAsDRepSteps/index.ts index 00566b6d4..29b5cb726 100644 --- a/govtool/frontend/src/components/organisms/RegisterAsDRepSteps/index.ts +++ b/govtool/frontend/src/components/organisms/RegisterAsDRepSteps/index.ts @@ -2,3 +2,4 @@ export * from "./DRepStorageInformation"; export * from "./DRepStoreDataInfo"; export * from "./RegisterAsDRepForm"; export * from "./RolesAndResponsibilities"; +export * from "./WhatRetirementMeans"; diff --git a/govtool/frontend/src/components/organisms/RetireAsSoleVoterBox.tsx b/govtool/frontend/src/components/organisms/RetireAsSoleVoterBox.tsx index f691d3d72..081e05d40 100644 --- a/govtool/frontend/src/components/organisms/RetireAsSoleVoterBox.tsx +++ b/govtool/frontend/src/components/organisms/RetireAsSoleVoterBox.tsx @@ -27,10 +27,10 @@ export const RetireAsSoleVoterBox = () => { const isPendingTx = isPendingTransaction(); if (isPendingTx) return; if (!voter?.deposit) { - throw new Error("Can not fetch deposit"); + throw new Error(t("errors.appCannotGetDeposit")); } const certBuilder = await buildDRepRetirementCert( - voter?.deposit?.toString() + voter?.deposit?.toString(), ); const result = await buildSignSubmitConwayCertTx({ certBuilder, diff --git a/govtool/frontend/src/consts/paths.ts b/govtool/frontend/src/consts/paths.ts index 679962a36..1e2eddda5 100644 --- a/govtool/frontend/src/consts/paths.ts +++ b/govtool/frontend/src/consts/paths.ts @@ -1,22 +1,23 @@ export const PATHS = { createGovernanceAction: "/create_governance_action", + dashboard: "/dashboard", + dashboardGovernanceActions: "/connected/governance_actions", dashboardGovernanceActionsAction: "/connected/governance_actions/:proposalId", dashboardGovernanceActionsCategory: "/connected/governance_actions/category/:category", - dashboardGovernanceActions: "/connected/governance_actions", - dashboard: "/dashboard", delegateTodRep: "/delegate", error: "/error", faqs: "/faqs", governanceActions: "/governance_actions", governanceActionsAction: "/governance_actions/:proposalId", + governanceActionsCategory: "/governance_actions/category/:category", governanceActionsCategoryAction: "/governance_actions/category/:category/:proposalId", - governanceActionsCategory: "/governance_actions/category/:category", guides: "/guides", home: "/", registerAsdRep: "/register", registerAsSoleVoter: "/register_sole_voter", + retireAsDrep: "/retire_drep", retireAsSoleVoter: "/retire_sole_voter", stakeKeys: "/stake_keys", updateMetadata: "/update_metadata", diff --git a/govtool/frontend/src/i18n/locales/en.ts b/govtool/frontend/src/i18n/locales/en.ts index 5f451f5f5..73e9c4217 100644 --- a/govtool/frontend/src/i18n/locales/en.ts +++ b/govtool/frontend/src/i18n/locales/en.ts @@ -243,6 +243,7 @@ export const en = { }, errors: { appCannotCreateTransaction: "Application can not create transaction.", + appCannotGetDeposit: "Can not fetch deposit", appCannotGetUtxos: "Application can not get utxos", appCannotGetVkeys: "Application can not get vkey", checkIsWalletConnected: "Check if the wallet is connected.", @@ -516,6 +517,13 @@ export const en = { }, }, }, + retirement: { + continue: "Continue to Retirement", + retireAsDrep: "Retire as a Drep", + whatRetirementMeansTitle: "What Retirement Means", + whatRetirementMeansDescription: + "By retiring you are giving up your voting rights. Voting Power that is delegated to you will remain in place.\n\nADA Holders that have delegated to be able to see that you are retired in the DRep directory. They will be able to re-delegate their Voting Power to another DRep.\n\nYou can still participate in Governance by proposing Governance Actions, by delegating your personal Voting Power to another DRep, or by coming out of retirement, and assuming your previous role as a DRep.\n\nIf you come out of retirement, your DRep ID will be the same as it was before retirement, and your Voting Power will consist of your own ADA balance and what delegated power that remains associated\nto your DRep ID.", + }, slider: { showAll: "Show All", viewAll: "View all", diff --git a/govtool/frontend/src/pages/RetireAsDrep.tsx b/govtool/frontend/src/pages/RetireAsDrep.tsx new file mode 100644 index 000000000..f0349b0f1 --- /dev/null +++ b/govtool/frontend/src/pages/RetireAsDrep.tsx @@ -0,0 +1,44 @@ +import { useEffect } from "react"; +import { useNavigate } from "react-router-dom"; +import { Box } from "@mui/material"; + +import { Background } from "@atoms"; +import { PATHS } from "@consts"; +import { DashboardTopNav, WhatRetirementMeans } from "@organisms"; +import { useScreenDimension, useTranslation } from "@hooks"; +import { LinkWithIcon } from "@molecules"; +import { checkIsWalletConnected } from "@utils"; + +export const RetireAsDrep = () => { + const navigate = useNavigate(); + const { t } = useTranslation(); + const { isMobile } = useScreenDimension(); + + useEffect(() => { + if (checkIsWalletConnected()) { + navigate(PATHS.home); + } + }, []); + + const onClickBackToDashboard = () => navigate(PATHS.dashboard); + + return ( + + + + + + + + ); +}; diff --git a/govtool/frontend/src/pages/index.ts b/govtool/frontend/src/pages/index.ts index c2f422300..3739fa117 100644 --- a/govtool/frontend/src/pages/index.ts +++ b/govtool/frontend/src/pages/index.ts @@ -1,4 +1,5 @@ export * from "./ChooseStakeKey"; +export * from "./CreateGovernanceAction"; export * from "./Dashboard"; export * from "./DashboardGovernanceActionsCategory"; export * from "./DelegateTodRep"; @@ -8,5 +9,7 @@ export * from "./GovernanceActions"; export * from "./GovernanceActionsCategory"; export * from "./Home"; export * from "./RegisterAsdRep"; +export * from "./RegisterAsSoleVoter"; +export * from "./RetireAsDrep"; export * from "./RetireAsSoleVoter"; export * from "./UpdatedRepMetadata";