Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#358] [#359] [#151] feat/358-choose-a-governance-action-type #383

Merged
merged 3 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ As a minor extension, we also keep a semantic version for the `UNRELEASED`
changes.

## [Unreleased]
- Abandoning registration as DRep [Issue 151](https://github.com/IntersectMBO/govtool/issues/151)
- Abandoning GA creation [Issue 359](https://github.com/IntersectMBO/govtool/issues/359)
- Choose GA type - GA Submiter [Issue 358](https://github.com/IntersectMBO/govtool/issues/358)
- Change step 3 components [Issue 152](https://github.com/intersectMBO/govtool/issues/152)
- Add possibility to vote on behalf of myself - Sole Voter [Issue 119](https://github.com/IntersectMBO/govtool/issues/119)
- Create DRep registration page about roles [Issue 205](https://github.com/IntersectMBO/govtool/issues/205)
Expand Down
5 changes: 5 additions & 0 deletions govtool/frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -115,6 +116,10 @@ export default function App() {
element={<DashboardGovernanceActionsCategory />}
/>
</Route>
<Route
path={PATHS.create_governance_action}
element={<CreateGovernanceAction />}
/>
<Route path={PATHS.delegateTodRep} element={<DelegateTodRep />} />
<Route path={PATHS.registerAsdRep} element={<RegisterAsdRep />} />
<Route
Expand Down
22 changes: 12 additions & 10 deletions govtool/frontend/src/components/atoms/ActionRadio.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Dispatch, FC, SetStateAction } from "react";
import { FC } from "react";
import { Box, Typography } from "@mui/material";
import InfoOutlinedIcon from "@mui/icons-material/InfoOutlined";

Expand All @@ -9,8 +9,8 @@ import { theme } from "@/theme";
type ActionRadioProps = {
dataTestId?: string;
isChecked?: boolean;
onChange: Dispatch<SetStateAction<string>>;
subtitle: string;
onChange: (newValue: string) => void;
subtitle?: string;
title: string;
tooltipText?: string;
tooltipTitle?: string;
Expand Down Expand Up @@ -76,13 +76,15 @@ export const ActionRadio: FC<ActionRadioProps> = ({ ...props }) => {
</Tooltip>
)}
</Box>
<Typography
variant="body2"
mt={1}
color={isChecked ? "white" : "textBlack"}
>
{subtitle}
</Typography>
{subtitle ? (
<Typography
variant="body2"
mt={1}
color={isChecked ? "white" : "textBlack"}
>
{subtitle}
</Typography>
) : null}
</Box>
</Box>
);
Expand Down
26 changes: 26 additions & 0 deletions govtool/frontend/src/components/molecules/BackToButton.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Box
data-testid="back-to-dashboard-link"
sx={{
alignItems: "center",
cursor: "pointer",
display: "flex",
...sx,
}}
onClick={onClick}
>
<ArrowBackIosIcon color="primary" sx={{ fontSize: 14 }} />
<Typography color="primary" fontWeight={400} variant="body2">
{label}
</Typography>
</Box>
);
};
1 change: 1 addition & 0 deletions govtool/frontend/src/components/molecules/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./ActionCard";
export * from "./BackToButton";
export * from "./CenteredBoxBottomButtons";
export * from "./CenteredBoxPageWrapper";
export * from "./DashboardActionCard";
Expand Down
7 changes: 7 additions & 0 deletions govtool/frontend/src/components/molecules/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { SxProps } from "@mui/material";

export type BackToLinkProps = {
label: string;
onClick: () => void;
sx?: SxProps;
};
2 changes: 1 addition & 1 deletion govtool/frontend/src/components/organisms/BgCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
@@ -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<SetStateAction<number>>;
};

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 (
<>
<ActionRadio
isChecked={isChecked}
onChange={onChangeType}
title={type}
value={type}
/>
{index + 1 < GOVERNANCE_ACTION_TYPES.length ? <Spacer y={2} /> : null}
</>
);
});
};

const onChangeType = (value: string) => {
setValue("type", value);
};

return (
<BgCard
actionButtonLabel={t("continue")}
backButtonLabel={t("cancel")}
isActionButtonDisabled={isContinueButtonDisabled}
onClickActionButton={onClickContinue}
onClickBackButton={onClickCancel}
>
<Typography sx={{ textAlign: "center" }} variant="headline4">
{t("createGovernanceAction.chooseGATypeTitle")}
</Typography>
<Spacer y={isMobile ? 4.25 : 7.5} />
{renderGovernanceActionTypes()}
<Spacer y={isMobile ? 6 : 7.5} />
</BgCard>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ import {
import { BgCard } from ".";

export const RegisterAsdRepStepOne = ({
onClickCancel,
setStep,
}: {
onClickCancel: () => void;
setStep: Dispatch<SetStateAction<number>>;
}) => {
const { t } = useTranslation();
Expand All @@ -35,6 +37,7 @@ export const RegisterAsdRepStepOne = ({
actionButtonLabel={t("continue")}
backButtonLabel={t("cancel")}
onClickActionButton={onClickContinue}
onClickBackButton={onClickCancel}
sx={{ paddingBottom: isMobile ? undefined : 3 }}
>
<Typography sx={{ textAlign: "center" }} variant="headline4">
Expand Down
1 change: 1 addition & 0 deletions govtool/frontend/src/components/organisms/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./BgCard";
export * from "./ChooseGovernanceActionType";
export * from "./ChooseStakeKeyPanel";
export * from "./ChooseWalletModal";
export * from "./ControlledField";
Expand Down
1 change: 1 addition & 0 deletions govtool/frontend/src/consts/governanceActionTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const GOVERNANCE_ACTION_TYPES = ["Info", "Treasury"];
1 change: 1 addition & 0 deletions govtool/frontend/src/consts/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./governanceActionTypes";
export * from "./governanceActionsFilters";
export * from "./governanceActionsSorting";
export * from "./icons";
Expand Down
1 change: 1 addition & 0 deletions govtool/frontend/src/consts/paths.ts
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
1 change: 1 addition & 0 deletions govtool/frontend/src/hooks/forms/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./useCreateGovernanceActionForm";
export * from "./useDelegateTodRepForm";
export * from "./useRegisterAsdRepFormContext";
export * from "./useUpdatedRepMetadataForm";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
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<boolean>(false);

const {
control,
formState: { errors, isValid },
getValues,
handleSubmit,
setValue,
watch,
} = useFormContext<createGovernanceActionValues>();

const onSubmit = useCallback(async () => {
setIsLoading(true);
try {
} catch (e: any) {
} finally {
setIsLoading(false);
}
}, []);

return {
control,
errors,
getValues,
isLoading,
isValid,
setValue,
submitForm: handleSubmit(onSubmit),
watch,
};
};
12 changes: 12 additions & 0 deletions govtool/frontend/src/i18n/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.",
Expand Down Expand Up @@ -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",
Expand All @@ -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!",
Expand Down
85 changes: 85 additions & 0 deletions govtool/frontend/src/pages/CreateGovernanceAction.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Background isReverted>
<Box
sx={{ display: "flex", flexDirection: "column", minHeight: "100vh" }}
>
<DashboardTopNav title={t("createGovernanceAction.title")} />
<BackToButton
label={t("backToDashboard")}
onClick={onClickBackToDashboard}
sx={{
mb: isMobile ? 0 : 1.5,
ml: isMobile ? 2 : 5,
mt: isMobile ? 3 : 1.5,
}}
/>
<FormProvider {...methods}>
{step === 1 && (
<ChooseGovernanceActionType
onClickCancel={onClickBackToDashboard}
setStep={setStep}
/>
)}
</FormProvider>
{isMobile && <Footer />}
</Box>
</Background>
);
};
Loading