Skip to content

Commit

Permalink
[#432] feat: lift up governance actions logic; add fields validation
Browse files Browse the repository at this point in the history
  • Loading branch information
MSzalowski committed Mar 11, 2024
1 parent 7f21727 commit d2d06d0
Show file tree
Hide file tree
Showing 18 changed files with 420 additions and 293 deletions.
12 changes: 10 additions & 2 deletions govtool/frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import { Route, Routes, useNavigate } from "react-router-dom";

import { Modal, ScrollToTop } from "@atoms";
import { PATHS } from "@consts";
import { useCardano, useModal } from "@context";
import {
GovernanceActionSubmissionProvider,
useCardano,
useModal,
} from "@context";
import {
DashboardCards,
DashboardGovernanceActions,
Expand Down Expand Up @@ -118,7 +122,11 @@ export default function App() {
</Route>
<Route
path={PATHS.createGovernanceAction}
element={<CreateGovernanceAction />}
element={
<GovernanceActionSubmissionProvider>
<CreateGovernanceAction />
</GovernanceActionSubmissionProvider>
}
/>
<Route path={PATHS.delegateTodRep} element={<DelegateTodRep />} />
<Route path={PATHS.registerAsdRep} element={<RegisterAsdRep />} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,14 @@
import { Dispatch, SetStateAction } from "react";

import { ActionRadio, Spacer, Typography } from "@atoms";
import { GOVERNANCE_ACTION_TYPES } from "@consts";
import {
useCreateGovernanceActionForm,
useScreenDimension,
useTranslation,
} from "@hooks";
import { useScreenDimension, useTranslation } from "@hooks";

import { BgCard } from "../BgCard";
import { GovernanceActionType } from "@/types/governanceAction";
import { useGovernanceActionSubmission } from "@/context";

type ChooseGovernanceActionTypeProps = {
setStep: Dispatch<SetStateAction<number>>;
};

export const ChooseGovernanceActionType = ({
setStep,
}: ChooseGovernanceActionTypeProps) => {
export const ChooseGovernanceActionType = () => {
const { type, setType, setStep } = useGovernanceActionSubmission();
const { t } = useTranslation();
const { isMobile } = useScreenDimension();
const { getValues, setValue, watch } = useCreateGovernanceActionForm();

const isContinueButtonDisabled = !watch("governance_action_type");

const onClickContinue = () => {
setStep(3);
Expand All @@ -33,30 +20,32 @@ export const ChooseGovernanceActionType = ({

// TODO: Add tooltips when they will be available
const renderGovernanceActionTypes = () => {
return GOVERNANCE_ACTION_TYPES.map((type, index) => {
const isChecked = getValues("governance_action_type") === type;
return (
<div key={type}>
<ActionRadio
isChecked={isChecked}
onChange={onChangeType}
title={type}
value={type}
/>
{index + 1 < GOVERNANCE_ACTION_TYPES.length ? <Spacer y={2} /> : null}
</div>
);
});
return Object.keys(GovernanceActionType).map(
(governanceActionType, index, governanceActionTypes) => {
const isChecked = governanceActionType === type;
return (
<div key={type}>
<ActionRadio
isChecked={isChecked}
onChange={onChangeType}
title={governanceActionType}
value={governanceActionType}
/>
{index + 1 < governanceActionTypes.length ? <Spacer y={2} /> : null}
</div>
);
}
);
};

const onChangeType = (value: string) => {
setValue("governance_action_type", value);
setType(value as GovernanceActionType);
};

return (
<BgCard
actionButtonLabel={t("continue")}
isActionButtonDisabled={isContinueButtonDisabled}
isActionButtonDisabled={!type}
onClickActionButton={onClickContinue}
onClickBackButton={onClickBack}
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
import { Dispatch, SetStateAction, useCallback } from "react";
import { useCallback } from "react";
import { useFieldArray } from "react-hook-form";
import DeleteOutlineIcon from "@mui/icons-material/DeleteOutline";

import { Button, InfoText, Spacer, Typography } from "@atoms";
import { GOVERNANCE_ACTIONS_FIELDS } from "@consts";
import { useCreateGovernanceActionForm, useTranslation } from "@hooks";
import { GOVERNANCE_ACTION_FIELDS } from "@consts";
import { useGovernanceActionSubmission } from "@context";
import { useTranslation } from "@hooks";
import { Field } from "@molecules";

import { BgCard } from "../BgCard";
import { ControlledField } from "../ControlledField";
import { GovernanceActionField } from "@/types/governanceAction";

const LINK_PLACEHOLDER = "https://website.com/";
const MAX_NUMBER_OF_LINKS = 8;

type ChooseGovernanceActionTypeProps = {
setStep: Dispatch<SetStateAction<number>>;
};

export const CreateGovernanceActionForm = ({
setStep,
}: ChooseGovernanceActionTypeProps) => {
export const CreateGovernanceActionForm = () => {
const { t } = useTranslation();
const { control, errors, getValues, register, reset, watch } =
useCreateGovernanceActionForm();
const { control, errors, register, reset, watch, type, setStep } =
useGovernanceActionSubmission();
const {
append,
fields: links,
Expand All @@ -32,16 +28,10 @@ export const CreateGovernanceActionForm = ({
name: "links",
});

const governanceActionType = getValues("governance_action_type");
const fields =
GOVERNANCE_ACTIONS_FIELDS.find(
(field) => field.name === governanceActionType
)?.fields ?? [];

// TODO: Replace any
const isContinueButtonDisabled = Object.keys(fields).some(
(field: any) => !watch(field)
);
const isContinueButtonDisabled = Object.keys(
GOVERNANCE_ACTION_FIELDS[type!]
).some((field: any) => !watch(field));

const onClickContinue = () => {
setStep(4);
Expand All @@ -53,37 +43,33 @@ export const CreateGovernanceActionForm = ({
};

const renderGovernanceActionField = () => {
return Object.entries(fields).map(([key, value]) => {
const label =
key.charAt(0).toUpperCase() + key.slice(1).replace("_", " ");

if (value.component === "input") {
return (
<ControlledField.Input
{...{ control, errors }}
helpfulText={value.tip}
key={key}
label={label}
layoutStyles={{ mb: 3 }}
name={key}
placeholder={value.placeholder}
/>
);
}
if (value.component === "textarea") {
return (
<ControlledField.TextArea
{...{ control, errors }}
helpfulText={value.tip}
key={key}
label={label}
layoutStyles={{ mb: 3 }}
name={key}
placeholder={value.placeholder}
/>
);
return Object.entries(GOVERNANCE_ACTION_FIELDS[type!]).map(
([key, field]) => {
const fieldProps = {
helpfulText: field.tipI18nKey ? t(field.tipI18nKey) : undefined,
key,
label: t(field.labelI18nKey),
layoutStyles: { mb: 3 },
name: key,
placeholder: field.placeholderI18nKey
? t(field.placeholderI18nKey)
: undefined,
};
if (field.component === GovernanceActionField.Input) {
return (
<ControlledField.Input {...{ control, errors }} {...fieldProps} />
);
}
if (field.component === GovernanceActionField.TextArea) {
return (
<ControlledField.TextArea
{...{ control, errors }}
{...fieldProps}
/>
);
}
}
});
);
};

const addLink = useCallback(() => {
Expand Down Expand Up @@ -136,7 +122,7 @@ export const CreateGovernanceActionForm = ({
disabled={true}
helpfulText={t("forms.createGovernanceAction.typeTip")}
label={t("forms.createGovernanceAction.typeLabel")}
value={governanceActionType}
value={type}
/>
<Spacer y={3} />
{renderGovernanceActionField()}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Dispatch, SetStateAction } from "react";
import { Box } from "@mui/material";
import DriveFileRenameOutlineOutlinedIcon from "@mui/icons-material/DriveFileRenameOutlineOutlined";

Expand All @@ -11,16 +10,12 @@ import {
} from "@hooks";
import { LinkWithIcon } from "@molecules";
import { openInNewTab } from "@utils";
import { useGovernanceActionSubmission } from "@/context";

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

type ReviewCreatedGovernanceActionProps = {
setStep: Dispatch<SetStateAction<number>>;
};

export const ReviewCreatedGovernanceAction = ({
setStep,
}: ReviewCreatedGovernanceActionProps) => {
export const ReviewCreatedGovernanceAction = () => {
const { setStep, type } = useGovernanceActionSubmission();
const { t } = useTranslation();
const { getValues } = useCreateGovernanceActionForm();
const values = getValues();
Expand All @@ -46,7 +41,7 @@ export const ReviewCreatedGovernanceAction = ({
.filter(
([key]) =>
!Object.keys(defaulCreateGovernanceActionValues).includes(key) ||
key === "governance_action_type"
key === type
)
.map(([key, value]) => {
const label =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import { Dispatch, SetStateAction, useCallback, useState } from "react";
import { useCallback, useState } from "react";
import { Box } from "@mui/material";
import OpenInNewIcon from "@mui/icons-material/OpenInNew";

import { Button, Spacer, Typography } from "@atoms";
import { useCreateGovernanceActionForm, useTranslation } from "@hooks";
import { useTranslation } from "@hooks";
import { Step } from "@molecules";
import { BgCard, ControlledField } from "@organisms";
import { downloadJson, openInNewTab } from "@utils";
import { useGovernanceActionSubmission } from "@/context";

export const StorageInformation = ({
setStep,
}: {
setStep: Dispatch<SetStateAction<number>>;
}) => {
export const StorageInformation = () => {
const { t } = useTranslation();
const {
control,
Expand All @@ -21,10 +18,11 @@ export const StorageInformation = ({
generateJsonBody,
getValues,
watch,
} = useCreateGovernanceActionForm();
setStep,
type,
} = useGovernanceActionSubmission();
const [isJsonDownloaded, setIsJsonDownloaded] = useState<boolean>(false);
// TODO: change on correct file name
const fileName = getValues("governance_action_type");

// TODO: Change link to correct
const openGuideAboutStoringInformation = useCallback(
Expand All @@ -36,10 +34,10 @@ export const StorageInformation = ({

const onClickBack = useCallback(() => setStep(5), []);

const onClickDowloadJson = () => {
const onClickDownloadJson = () => {
const data = getValues();
const jsonBody = generateJsonBody(data);
downloadJson(jsonBody, fileName);
downloadJson(jsonBody, type);
setIsJsonDownloaded(true);
};

Expand All @@ -66,11 +64,11 @@ export const StorageInformation = ({
// TODO: add onClick action when available
component={
<Button
onClick={onClickDowloadJson}
onClick={onClickDownloadJson}
size="extraLarge"
sx={{ width: "fit-content" }}
>
{`${fileName}.jsonld`}
{`${type!}.jsonld`}
</Button>
}
label={t("createGovernanceAction.storingInformationStep1Label")}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
import { Dispatch, SetStateAction } from "react";
import { Box, Link } from "@mui/material";

import { Spacer, Typography } from "@atoms";
import {
useCreateGovernanceActionForm,
useScreenDimension,
useTranslation,
} from "@hooks";
import { useScreenDimension, useTranslation } from "@hooks";
import { BgCard, ControlledField } from "@organisms";
import { openInNewTab } from "@utils";
import { useGovernanceActionSubmission } from "@/context";

export const StoreDataInfo = ({
setStep,
}: {
setStep: Dispatch<SetStateAction<number>>;
}) => {
export const StoreDataInfo = () => {
const { t } = useTranslation();
const { control, errors, watch } = useCreateGovernanceActionForm();
const { control, errors, watch, setStep } = useGovernanceActionSubmission();
const { isMobile } = useScreenDimension();

// TODO: change link when available
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Dispatch, SetStateAction, useCallback } from "react";
import { useCallback } from "react";
import { Trans } from "react-i18next";

import { Typography } from "@atoms";
Expand All @@ -10,16 +10,16 @@ import {
} from "@utils";

import { BgCard } from "..";
import { useGovernanceActionSubmission } from "@/context";

type WhatGovernanceActionIsAboutProps = {
onClickCancel: () => void;
setStep: Dispatch<SetStateAction<number>>;
};

export const WhatGovernanceActionIsAbout = ({
setStep,
onClickCancel,
}: WhatGovernanceActionIsAboutProps) => {
const { setStep } = useGovernanceActionSubmission();
const { t } = useTranslation();
const { isMobile } = useScreenDimension();

Expand Down
Loading

0 comments on commit d2d06d0

Please sign in to comment.