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

feat/205-drep-roles-info-page #233

Merged
merged 6 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ As a minor extension, we also keep a semantic version for the `UNRELEASED`
changes.

## [Unreleased]
- Create DRep registration page about roles [Issue 205](https://github.com/IntersectMBO/govtool/issues/205)
- Create Checkbox component. Improve Field and ControlledField [Issue 177](https://github.com/IntersectMBO/govtool/pull/177)
- Vitest unit tests added for utils functions [Issue 81](https://github.com/IntersectMBO/govtool/issues/81)
- i18next library added to FE [Issue 80](https://github.com/IntersectMBO/govtool/issues/80)
Expand Down
137 changes: 137 additions & 0 deletions govtool/frontend/src/components/organisms/BgCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import { useCallback, useMemo } from "react";
MSzalowski marked this conversation as resolved.
Show resolved Hide resolved
import { useNavigate } from "react-router-dom";
import { Box, Link } from "@mui/material";
import ArrowBackIosIcon from "@mui/icons-material/ArrowBackIos";

import { Button, Typography } from "@atoms";
import { PATHS } from "@consts";
import { useScreenDimension, useTranslation } from "@hooks";
import { theme } from "@/theme";

import { BgCardProps } from "./types";

export const BgCard = ({
actionButtonLabel,
children,
onClickBackButton,
onClickActionButton,
sx,
title,
}: BgCardProps) => {
const {
palette: { boxShadow2 },
} = theme;
const { isMobile, screenWidth } = useScreenDimension();
const navigate = useNavigate();
const { t } = useTranslation();

const navigateToDashboard = useCallback(
() => navigate(PATHS.dashboard),
[navigate]
);

const renderBackButton = useMemo(() => {
return (
<Button
data-testid="back-button"
onClick={onClickBackButton ?? navigateToDashboard}
size="extraLarge"
sx={{
px: 6,
width: isMobile ? "100%" : "auto",
Sworzen1 marked this conversation as resolved.
Show resolved Hide resolved
}}
variant="outlined"
>
{t("cancel")}
</Button>
);
}, [isMobile]);

const renderContinueButton = useMemo(() => {
return (
<Button
data-testid="retire-button"
onClick={onClickActionButton}
size="extraLarge"
sx={{
px: 6,
width: isMobile ? "100%" : "auto",
}}
variant="contained"
>
{actionButtonLabel}
</Button>
);
}, [isMobile]);

return (
<Box
height={isMobile ? "100%" : "auto"}
sx={{
alignItems: screenWidth >= 768 ? "center" : "inherit",
marginTop: screenWidth < 1440 ? "97px" : "137px",
display: screenWidth < 1440 ? "flex" : "grid",
...(screenWidth < 1440 && {
flexDirection: "column",
}),
...(screenWidth >= 1440 && { gridTemplateColumns: "1fr auto 1fr" }),
}}
>
{isMobile && (
<Box borderBottom="1px solid white">
<Typography
variant="title1"
sx={{
ml: 2,
my: 3.25,
}}
>
Sworzen1 marked this conversation as resolved.
Show resolved Hide resolved
{title}
</Typography>
</Box>
)}
<Link
data-testid="back-to-list-link"
sx={{
alignItems: "center",
alignSelf: "flex-start",
cursor: "pointer",
display: "flex",
justifyContent: "flex-start",
ml: screenWidth < 1440 ? 2 : 5,
mt: screenWidth < 1440 ? 3 : "none",
textDecoration: "none",
}}
onClick={navigateToDashboard}
>
<ArrowBackIosIcon sx={{ fontSize: 14 }} />
<Typography color="primary" fontWeight={400} variant="body2">
{t("backToDashboard")}
</Typography>
</Link>
<Box
borderRadius="20px"
boxShadow={isMobile ? "" : `2px 2px 20px 0px ${boxShadow2}`}
height="auto"
maxWidth={screenWidth > 768 ? 600 : undefined}
px={isMobile ? 2 : 18.75}
pt={isMobile ? 6 : 10}
pb={3}
sx={sx}
>
<Box display="flex" flexDirection="column">
{children}
</Box>
<Box
display="flex"
flexDirection={isMobile ? "column" : "row"}
justifyContent="space-between"
>
{isMobile ? renderContinueButton : renderBackButton}
<Box px={2} py={isMobile ? 1.5 : 0} />
Sworzen1 marked this conversation as resolved.
Show resolved Hide resolved
{isMobile ? renderBackButton : renderContinueButton}
Sworzen1 marked this conversation as resolved.
Show resolved Hide resolved
</Box>
</Box>
</Box>
);
};
172 changes: 47 additions & 125 deletions govtool/frontend/src/components/organisms/RegisterAsdRepStepOne.tsx
Original file line number Diff line number Diff line change
@@ -1,139 +1,61 @@
import { Dispatch, SetStateAction, useMemo } from "react";
import { useNavigate } from "react-router-dom";
import { Box, Link } from "@mui/material";
import { Dispatch, SetStateAction, useCallback } from "react";
import { Trans } from "react-i18next";
import { Link } from "@mui/material";

import { Button, Spacer, Typography } from "@atoms";
import { PATHS } from "@consts";
import { Typography } from "@atoms";
import { useScreenDimension, useTranslation } from "@hooks";
import {
useScreenDimension,
useRegisterAsdRepFormContext,
useTranslation,
} from "@hooks";
import { theme } from "@/theme";
import { openInNewTab } from "@utils";
correctAdaFormat,
getItemFromLocalStorage,
openInNewTab,
PROTOCOL_PARAMS_KEY,
} from "@utils";

import { ControlledField } from ".";
import { BgCard } from ".";

interface Props {
export const RegisterAsdRepStepOne = ({
setStep,
}: {
setStep: Dispatch<SetStateAction<number>>;
}

export const RegisterAsdRepStepOne = ({ setStep }: Props) => {
const navigate = useNavigate();
}) => {
const { t } = useTranslation();
const {
palette: { boxShadow2 },
} = theme;
const { isMobile, pagePadding, screenWidth } = useScreenDimension();
const { control, errors, isValid, showSubmitButton } =
useRegisterAsdRepFormContext();
const { isMobile } = useScreenDimension();

const renderCancelButton = useMemo(() => {
return (
<Button
data-testid={"cancel-button"}
onClick={() => navigate(PATHS.dashboard)}
size="extraLarge"
sx={{
px: 6,
width: isMobile ? "100%" : "auto",
}}
variant="outlined"
>
{t("cancel")}
</Button>
);
}, [isMobile]);
const deposit = getItemFromLocalStorage(PROTOCOL_PARAMS_KEY);

const renderConfirmButton = useMemo(() => {
return (
<Button
data-testid={
showSubmitButton && isValid ? "confirm-button" : "skip-button"
}
disabled={!isValid}
onClick={() => setStep(2)}
size="extraLarge"
sx={{
px: 6,
width: isMobile ? "100%" : "154px",
}}
variant="contained"
>
{showSubmitButton ? t("confirm") : t("skip")}
</Button>
);
}, [isMobile, isValid, showSubmitButton]);
const onClickContinue = useCallback(() => setStep(2), [setStep]);

return (
<Box
width={screenWidth < 768 ? "auto" : screenWidth < 1024 ? "60vw" : "45vw"}
boxShadow={isMobile ? "" : `2px 2px 20px 0px ${boxShadow2}`}
px={pagePadding}
py={isMobile ? 4 : 8}
borderRadius={"20px"}
mb={isMobile ? 0 : 6}
height={"100%"}
<BgCard
actionButtonLabel={t("continue")}
onClickActionButton={onClickContinue}
title={t("registration.becomeADRep")}
>
<Box display="flex" flexDirection="column" alignItems="center">
<Typography
color="accentOrange"
sx={{ letterSpacing: 1.5, textAlign: "center" }}
variant="body1"
>
{t("registration.optional")}
</Typography>
<Typography sx={{ mt: 1, textAlign: "center" }} variant="headline4">
{t("registration.headingStepOne")}
</Typography>
<Typography
fontWeight={400}
sx={{ mb: 7, mt: 3, textAlign: "center" }}
variant="body1"
>
{t("registration.descriptionStepOne")}
</Typography>
<ControlledField.Input
{...{ control, errors }}
dataTestId="url-input"
layoutStyles={{ width: isMobile ? "100%" : "70%" }}
name="url"
placeholder={t("forms.urlWithInfoPlaceholder")}
/>
<Spacer y={6} />
<ControlledField.Input
{...{ control, errors }}
dataTestId="hash-input"
layoutStyles={{ width: isMobile ? "100%" : "70%" }}
name="hash"
placeholder={t("forms.hashPlaceholder")}
/>
<Link
data-testid={"how-to-create-link"}
onClick={() =>
openInNewTab(
"https://docs.sanchogov.tools/faqs/how-to-create-a-metadata-anchor"
)
}
alignSelf={"center"}
mt={5}
sx={{ cursor: "pointer" }}
>
<Typography fontWeight={500} color="primary" variant="body1">
{t("forms.howCreateUrlAndHash")}
</Typography>
</Link>
</Box>
<Box
display={"flex"}
flexDirection={isMobile ? "column" : "row"}
justifyContent={"space-between"}
mt={6}
<Typography sx={{ textAlign: "center" }} variant="headline4">
{t("registration.rolesAndResponsibilitiesTitle")}
</Typography>
<Typography
fontWeight={400}
sx={{
pb: isMobile ? 6 : 4,
pt: 4,
textAlign: "center",
whiteSpace: "pre-line",
}}
variant="body1"
>
{isMobile ? renderConfirmButton : renderCancelButton}
<Box px={2} py={isMobile ? 1.5 : 0} />
{isMobile ? renderCancelButton : renderConfirmButton}
</Box>
</Box>
<Trans
components={[
<Link
key="1"
onClick={() => openInNewTab("https://sancho.network/")}
sx={{ cursor: "pointer" }}
/>,
]}
i18nKey={"registration.rolesAndResponsibilitiesDescription"}
values={{ deposit: correctAdaFormat(deposit) }}
/>
</Typography>
</BgCard>
);
};
1 change: 1 addition & 0 deletions govtool/frontend/src/components/organisms/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./BgCard";
export * from "./ChooseStakeKeyPanel";
export * from "./ChooseWalletModal";
export * from "./DashboardCards";
Expand Down
10 changes: 10 additions & 0 deletions govtool/frontend/src/components/organisms/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { SxProps } from "@mui/material";

export type BgCardProps = {
actionButtonLabel: string;
children: React.ReactNode;
onClickBackButton?: () => void;
onClickActionButton: () => void;
sx?: SxProps;
title: string;
};
9 changes: 5 additions & 4 deletions govtool/frontend/src/i18n/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,15 +269,15 @@ export const en = {
},
},
registration: {
descriptionStepOne:
"You can include extra information about yourself by adding a URL and its hash.",
rolesAndResponsibilitiesTitle: "Roles & Responsibilities",
rolesAndResponsibilitiesDescription:
"DReps are fundamental users that govern the Cardano network. This is an important role which requires work and dedication to fulfil.\n\nA DRep is expected to actively participate in governance and act as a representative of other Cardano members in governance matters. Therefore, DReps will be expected to keep abreast of Governance Actions so they can make informed and wise decisions.\n<0>Learn More</0> about DRep.\n\nPlease register as a DRep if you have time to dedicate to making Cardano a better and more well-governed place.\n\nBecoming a DRep will require a refundable deposit of ₳<strong>{{deposit}}</strong>.\n\nYou will be refunded your deposit when you retire.",
descriptionStepTwo:
"By clicking register you create your DRep ID within your wallet and become a DRep.\n\nOnce the registration has completed your DRep ID will be shown on your dashboard. You will be able to share your DRep ID so that other ada holders can delegate their voting power to you.",
headingStepOne: "Add Information",
headingStepTwo: "Confirm DRep registration",
optional: "OPTIONAL",
register: "Register",
registerAsDRep: "Register as a DRep",
becomeADRep: "Become a DRep",
},
slider: {
showAll: "Show all",
Expand Down Expand Up @@ -355,6 +355,7 @@ export const en = {
},
abstain: "Abstain",
back: "Back",
backToDashboard: "Back to dashboard",
backToList: "Back to the list",
cancel: "Cancel",
clear: "Clear",
Expand Down
Loading