diff --git a/govtool/frontend/src/App.tsx b/govtool/frontend/src/App.tsx
index 13bc34a7d..c380c6664 100644
--- a/govtool/frontend/src/App.tsx
+++ b/govtool/frontend/src/App.tsx
@@ -32,6 +32,7 @@ import {
import { SetupInterceptors } from "./services";
import { useGetVoterInfo, useWalletConnectionListener } from "./hooks";
import { RegisterAsSoleVoter } from "./pages/RegisterAsSoleVoter";
+import { CreateGovernanceAction } from "./pages/CreateGovernanceAction";
export default function App() {
const { enable, setVoter, setIsDrepLoading } = useCardano();
@@ -115,6 +116,10 @@ export default function App() {
element={}
/>
+ }
+ />
} />
} />
>;
- subtitle: string;
+ onChange: (newValue: string) => void;
+ subtitle?: string;
title: string;
tooltipText?: string;
tooltipTitle?: string;
@@ -76,13 +76,15 @@ export const ActionRadio: FC = ({ ...props }) => {
)}
-
- {subtitle}
-
+ {subtitle ? (
+
+ {subtitle}
+
+ ) : null}
);
diff --git a/govtool/frontend/src/components/molecules/BackToButton.tsx b/govtool/frontend/src/components/molecules/BackToButton.tsx
new file mode 100644
index 000000000..e3a697d36
--- /dev/null
+++ b/govtool/frontend/src/components/molecules/BackToButton.tsx
@@ -0,0 +1,26 @@
+import { Box } from "@mui/material";
+import ArrowBackIosIcon from "@mui/icons-material/ArrowBackIos";
+
+import { Typography } from "@atoms";
+
+import { BackToLinkProps } from "./types";
+
+export const BackToButton = ({ label, onClick, sx }: BackToLinkProps) => {
+ return (
+
+
+
+ {label}
+
+
+ );
+};
diff --git a/govtool/frontend/src/components/molecules/index.ts b/govtool/frontend/src/components/molecules/index.ts
index 7b4c1668f..3afe1db00 100644
--- a/govtool/frontend/src/components/molecules/index.ts
+++ b/govtool/frontend/src/components/molecules/index.ts
@@ -1,4 +1,5 @@
export * from "./ActionCard";
+export * from "./BackToButton";
export * from "./CenteredBoxBottomButtons";
export * from "./CenteredBoxPageWrapper";
export * from "./DashboardActionCard";
diff --git a/govtool/frontend/src/components/molecules/types.ts b/govtool/frontend/src/components/molecules/types.ts
new file mode 100644
index 000000000..6cafc8c4a
--- /dev/null
+++ b/govtool/frontend/src/components/molecules/types.ts
@@ -0,0 +1,7 @@
+import { SxProps } from "@mui/material";
+
+export type BackToLinkProps = {
+ label: string;
+ onClick: () => void;
+ sx?: SxProps;
+};
diff --git a/govtool/frontend/src/components/organisms/BgCard.tsx b/govtool/frontend/src/components/organisms/BgCard.tsx
index b430eb205..1995f06a3 100644
--- a/govtool/frontend/src/components/organisms/BgCard.tsx
+++ b/govtool/frontend/src/components/organisms/BgCard.tsx
@@ -89,7 +89,7 @@ export const BgCard = ({
flexDirection: "column",
height: "auto",
maxWidth: screenWidth > 768 ? 600 : undefined,
- my: isMobile ? undefined : 3,
+ mb: isMobile ? undefined : 3,
pb: isMobile ? undefined : 10,
pt: isMobile ? 6 : 10,
px: isMobile ? 2 : 18.75,
diff --git a/govtool/frontend/src/components/organisms/ChooseGovernanceActionType.tsx b/govtool/frontend/src/components/organisms/ChooseGovernanceActionType.tsx
new file mode 100644
index 000000000..91eec706e
--- /dev/null
+++ b/govtool/frontend/src/components/organisms/ChooseGovernanceActionType.tsx
@@ -0,0 +1,70 @@
+import { Dispatch, SetStateAction } from "react";
+
+import { ActionRadio, Spacer, Typography } from "@atoms";
+import { GOVERNANCE_ACTION_TYPES } from "@consts";
+import {
+ useCreateGovernanceActionForm,
+ useScreenDimension,
+ useTranslation,
+} from "@hooks";
+
+import { BgCard } from "./BgCard";
+
+type ChooseGovernanceActionTypeProps = {
+ onClickCancel: () => void;
+ setStep: Dispatch>;
+};
+
+export const ChooseGovernanceActionType = ({
+ onClickCancel,
+ setStep,
+}: ChooseGovernanceActionTypeProps) => {
+ const { t } = useTranslation();
+ const { isMobile } = useScreenDimension();
+ const { getValues, setValue, watch } = useCreateGovernanceActionForm();
+
+ const isContinueButtonDisabled = !watch("type");
+
+ const onClickContinue = () => {
+ setStep(2);
+ };
+
+ // TODO: Add tooltips when they will be available
+ const renderGovernanceActionTypes = () => {
+ return GOVERNANCE_ACTION_TYPES.map((type, index) => {
+ const isChecked = getValues("type") === type;
+ return (
+ <>
+
+ {index + 1 < GOVERNANCE_ACTION_TYPES.length ? : null}
+ >
+ );
+ });
+ };
+
+ const onChangeType = (value: string) => {
+ setValue("type", value);
+ };
+
+ return (
+
+
+ {t("createGovernanceAction.chooseGATypeTitle")}
+
+
+ {renderGovernanceActionTypes()}
+
+
+ );
+};
diff --git a/govtool/frontend/src/components/organisms/RegisterAsdRepStepOne.tsx b/govtool/frontend/src/components/organisms/RegisterAsdRepStepOne.tsx
index 3a68ce015..04598720a 100644
--- a/govtool/frontend/src/components/organisms/RegisterAsdRepStepOne.tsx
+++ b/govtool/frontend/src/components/organisms/RegisterAsdRepStepOne.tsx
@@ -14,8 +14,10 @@ import {
import { BgCard } from ".";
export const RegisterAsdRepStepOne = ({
+ onClickCancel,
setStep,
}: {
+ onClickCancel: () => void;
setStep: Dispatch>;
}) => {
const { t } = useTranslation();
@@ -35,6 +37,7 @@ export const RegisterAsdRepStepOne = ({
actionButtonLabel={t("continue")}
backButtonLabel={t("cancel")}
onClickActionButton={onClickContinue}
+ onClickBackButton={onClickCancel}
sx={{ paddingBottom: isMobile ? undefined : 3 }}
>
diff --git a/govtool/frontend/src/components/organisms/index.ts b/govtool/frontend/src/components/organisms/index.ts
index 9b7ee74ce..749a01357 100644
--- a/govtool/frontend/src/components/organisms/index.ts
+++ b/govtool/frontend/src/components/organisms/index.ts
@@ -1,4 +1,5 @@
export * from "./BgCard";
+export * from "./ChooseGovernanceActionType";
export * from "./ChooseStakeKeyPanel";
export * from "./ChooseWalletModal";
export * from "./ControlledField";
diff --git a/govtool/frontend/src/consts/governanceActionTypes.ts b/govtool/frontend/src/consts/governanceActionTypes.ts
new file mode 100644
index 000000000..b3b6a8539
--- /dev/null
+++ b/govtool/frontend/src/consts/governanceActionTypes.ts
@@ -0,0 +1 @@
+export const GOVERNANCE_ACTION_TYPES = ["Info", "Treasury"];
diff --git a/govtool/frontend/src/consts/index.ts b/govtool/frontend/src/consts/index.ts
index 65168f9c6..12f9ae298 100644
--- a/govtool/frontend/src/consts/index.ts
+++ b/govtool/frontend/src/consts/index.ts
@@ -1,3 +1,4 @@
+export * from "./governanceActionTypes";
export * from "./governanceActionsFilters";
export * from "./governanceActionsSorting";
export * from "./icons";
diff --git a/govtool/frontend/src/consts/paths.ts b/govtool/frontend/src/consts/paths.ts
index 4ac0cbde2..f230747d5 100644
--- a/govtool/frontend/src/consts/paths.ts
+++ b/govtool/frontend/src/consts/paths.ts
@@ -1,4 +1,5 @@
export const PATHS = {
+ create_governance_action: "/create_governance_action",
dashboard_governance_actions_action:
"/connected/governance_actions/:proposalId",
dashboard_governance_actions_category:
diff --git a/govtool/frontend/src/hooks/forms/index.ts b/govtool/frontend/src/hooks/forms/index.ts
index 2457ac6de..fe994e70b 100644
--- a/govtool/frontend/src/hooks/forms/index.ts
+++ b/govtool/frontend/src/hooks/forms/index.ts
@@ -1,3 +1,4 @@
+export * from "./useCreateGovernanceActionForm";
export * from "./useDelegateTodRepForm";
export * from "./useRegisterAsdRepFormContext";
export * from "./useUpdatedRepMetadataForm";
diff --git a/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts b/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts
new file mode 100644
index 000000000..bb4335f71
--- /dev/null
+++ b/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts
@@ -0,0 +1,45 @@
+import { useCallback, useState } from "react";
+import { useFormContext } from "react-hook-form";
+
+type createGovernanceActionValues = {
+ type: string;
+};
+
+export const defaulCreateGovernanceActionValues: createGovernanceActionValues =
+ {
+ type: "",
+ };
+
+export const useCreateGovernanceActionForm = () => {
+ const [isLoading, setIsLoading] = useState(false);
+
+ const {
+ control,
+ formState: { errors, isValid },
+ getValues,
+ handleSubmit,
+ setValue,
+ watch,
+ } = useFormContext();
+
+ const onSubmit = useCallback(async (values: createGovernanceActionValues) => {
+ setIsLoading(true);
+ console.log(values);
+ try {
+ } catch (e: any) {
+ } finally {
+ setIsLoading(false);
+ }
+ }, []);
+
+ return {
+ control,
+ errors,
+ getValues,
+ isLoading,
+ isValid,
+ setValue,
+ submitForm: handleSubmit(onSubmit),
+ watch,
+ };
+};
diff --git a/govtool/frontend/src/i18n/locales/en.ts b/govtool/frontend/src/i18n/locales/en.ts
index 3c9d6e006..8483755e6 100644
--- a/govtool/frontend/src/i18n/locales/en.ts
+++ b/govtool/frontend/src/i18n/locales/en.ts
@@ -122,6 +122,10 @@ export const en = {
youAreSoleVoterTitle: "You are a Sole Voter",
},
},
+ createGovernanceAction: {
+ chooseGATypeTitle: "Choose a Governance Action type",
+ title: "Create a Governance Action",
+ },
delegation: {
description:
"You can delegate your voting power to a DRep or to a pre-defined voting option.",
@@ -277,6 +281,11 @@ export const en = {
goToDashboard: "Go to Dashboard",
oops: "Oops!",
},
+ createGovernanceAction: {
+ cancelModalDescription:
+ "If you return to the Dashboard, your information will not be saved.",
+ cancelModalTitle: "Do You Want to Cancel Registration ?",
+ },
delegation: {
message:
"The confirmation of your actual delegation might take a bit of time but you can track it using",
@@ -292,6 +301,9 @@ export const en = {
youAreAboutToOpen: "You are about to open an external link to:",
},
registration: {
+ cancelTitle: "Do You Want to Abandon Registration ?",
+ cancelDescription:
+ "If you return to the Dashboard, your information will not be saved.",
message:
"The confirmation of your registration might take a bit of time but you can track it using",
title: "Registration Transaction Submitted!",
diff --git a/govtool/frontend/src/pages/CreateGovernanceAction.tsx b/govtool/frontend/src/pages/CreateGovernanceAction.tsx
new file mode 100644
index 000000000..295dda462
--- /dev/null
+++ b/govtool/frontend/src/pages/CreateGovernanceAction.tsx
@@ -0,0 +1,85 @@
+import { useEffect, useState } from "react";
+import { useNavigate } from "react-router-dom";
+import { FormProvider, useForm } from "react-hook-form";
+import { Box } from "@mui/material";
+
+import { Background } from "@atoms";
+import { PATHS } from "@consts";
+import { useModal } from "@context";
+import {
+ defaulCreateGovernanceActionValues,
+ useScreenDimension,
+ useTranslation,
+} from "@hooks";
+import { BackToButton } from "@molecules";
+import {
+ ChooseGovernanceActionType,
+ DashboardTopNav,
+ Footer,
+} from "@organisms";
+import { checkIsWalletConnected } from "@utils";
+
+export const CreateGovernanceAction = () => {
+ const navigate = useNavigate();
+ const { t } = useTranslation();
+ const { isMobile } = useScreenDimension();
+ const { closeModal, openModal } = useModal();
+ const [step, setStep] = useState(1);
+
+ const methods = useForm({
+ mode: "onBlur",
+ defaultValues: defaulCreateGovernanceActionValues,
+ });
+
+ useEffect(() => {
+ if (checkIsWalletConnected()) {
+ navigate(PATHS.home);
+ }
+ }, []);
+
+ const onClickBackToDashboard = () =>
+ openModal({
+ type: "statusModal",
+ state: {
+ status: "warning",
+ message: t("modals.createGovernanceAction.cancelModalDescription"),
+ buttonText: t("modals.common.goToDashboard"),
+ title: t("modals.createGovernanceAction.cancelModalTitle"),
+ dataTestId: "cancel-governance-action-creation-modal",
+ onSubmit: backToDashboard,
+ },
+ });
+
+ const backToDashboard = () => {
+ navigate(PATHS.dashboard);
+ closeModal();
+ };
+
+ return (
+
+
+
+
+
+ {step === 1 && (
+
+ )}
+
+ {isMobile && }
+
+
+ );
+};
diff --git a/govtool/frontend/src/pages/RegisterAsdRep.tsx b/govtool/frontend/src/pages/RegisterAsdRep.tsx
index b1788f106..06fb7fc00 100644
--- a/govtool/frontend/src/pages/RegisterAsdRep.tsx
+++ b/govtool/frontend/src/pages/RegisterAsdRep.tsx
@@ -5,11 +5,13 @@ import { Box } from "@mui/material";
import { Background } from "@atoms";
import { PATHS } from "@consts";
+import { useModal } from "@context";
import {
useScreenDimension,
useUrlAndHashFormController as useRegisterAsdRepFormController,
useTranslation,
} from "@hooks";
+import { BackToButton } from "@molecules";
import {
DashboardTopNav,
Footer,
@@ -24,6 +26,7 @@ export const RegisterAsdRep = () => {
const { isMobile } = useScreenDimension();
const navigate = useNavigate();
const { t } = useTranslation();
+ const { closeModal, openModal } = useModal();
const registerAsdRepFormMethods = useRegisterAsdRepFormController();
@@ -33,14 +36,46 @@ export const RegisterAsdRep = () => {
}
}, []);
+ const onClickBackToDashboard = () =>
+ openModal({
+ type: "statusModal",
+ state: {
+ status: "warning",
+ message: t("modals.registration.cancelDescription"),
+ buttonText: t("modals.common.goToDashboard"),
+ title: t("modals.registration.cancelTitle"),
+ dataTestId: "cancel-registration-modal",
+ onSubmit: backToDashboard,
+ },
+ });
+
+ const backToDashboard = () => {
+ navigate(PATHS.dashboard);
+ closeModal();
+ };
+
return (
+
- {step === 1 && }
+ {step === 1 && (
+
+ )}
{step === 2 && }
{step === 3 && }