Skip to content

Commit 9cb8b86

Browse files
committed
refactor: improve extra sources input and unify verification request form types
1 parent c7f10e7 commit 9cb8b86

File tree

9 files changed

+191
-162
lines changed

9 files changed

+191
-162
lines changed

src/components/Form/DynamicInput.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,24 @@ import colors from "../../styles/colors";
1414
import ReportTypeSelect from "../VerificationRequest/verificationRequestForms/formInputs/ReportTypeSelect";
1515
import ImpactAreaSelect from "../VerificationRequest/verificationRequestForms/formInputs/ImpactAreaSelect";
1616
import InputExtraSourcesList from "../VerificationRequest/verificationRequestForms/formInputs/InputExtraSourcesList";
17+
import { Topic } from "../../types/Topic";
18+
import { SourceType } from "../../types/Source";
1719

1820
const VisualEditor = lazy(() => import("../Collaborative/VisualEditor"));
1921

22+
export type UnifiedDefaultValue = Topic | SourceType[] | string
23+
2024
interface DynamicInputProps {
2125
fieldName: string;
2226
type: string;
2327
placeholder: string;
24-
value: string | [];
28+
value: UnifiedDefaultValue;
2529
onChange: any;
2630
addInputLabel: string;
27-
defaultValue: string | [];
31+
defaultValue: UnifiedDefaultValue;
2832
"data-cy": string;
2933
extraProps: any;
30-
disabledDate?: any;
34+
disabledDate?: boolean;
3135
disabled?: boolean;
3236
}
3337

@@ -87,7 +91,7 @@ const DynamicInput = (props: DynamicInputProps) => {
8791
case "sourceList":
8892
return (
8993
<InputExtraSourcesList
90-
value={props.value}
94+
sources={props.value}
9195
onChange={props.onChange}
9296
disabled={props.disabled}
9397
placeholder={props.placeholder}

src/components/VerificationRequest/verificationRequestForms/DynamicVerificationRequestForm.tsx

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,16 @@ import moment from "moment";
55
import DynamicForm from "../../Form/DynamicForm";
66
import SharedFormFooter from "../../SharedFormFooter";
77
import editVerificationRequestForm from "./fieldLists/EditVerificationRequestForm";
8+
import { IDynamicVerificationRequestForm } from "../../../types/VerificationRequest";
89

9-
interface IDynamicVerificationRequestForm {
10-
data?: any,
11-
onSubmit: any,
12-
isLoading: any,
13-
setRecaptchaString: any,
14-
hasCaptcha: any,
15-
isEdit: any,
16-
extrafields?: any,
17-
}
18-
19-
const DynamicVerificationRequestForm = ({ data, onSubmit, isLoading, setRecaptchaString, hasCaptcha, isEdit }: IDynamicVerificationRequestForm) => {
10+
const DynamicVerificationRequestForm = ({
11+
data,
12+
onSubmit,
13+
isLoading,
14+
setRecaptchaString,
15+
hasCaptcha,
16+
isEdit,
17+
}: IDynamicVerificationRequestForm) => {
2018
const {
2119
handleSubmit,
2220
control,

src/components/VerificationRequest/verificationRequestForms/EditVerificationRequestView.tsx

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,17 @@
11
import React, { useState } from "react";
2-
import { VerificationRequest } from "../../../types/VerificationRequest";
2+
import { IEditVerificationRequestDrawer } from "../../../types/VerificationRequest";
33
import { useTranslation } from "react-i18next";
44
import { Divider, Grid } from "@mui/material";
55
import verificationRequestApi from "../../../api/verificationRequestApi";
66
import LargeDrawer from "../../LargeDrawer";
77
import DynamicVerificationRequestForm from "./DynamicVerificationRequestForm";
88

9-
interface EditVerificationRequestDrawerProps {
10-
open: boolean;
11-
onClose: () => void;
12-
verificationRequest: VerificationRequest;
13-
onSave: (updatedRequest: VerificationRequest) => void;
14-
}
15-
16-
const EditVerificationRequestDrawer: React.FC<EditVerificationRequestDrawerProps> = ({
9+
const EditVerificationRequestDrawer = ({
1710
open,
1811
onClose,
1912
verificationRequest,
2013
onSave,
21-
}) => {
14+
}: IEditVerificationRequestDrawer) => {
2215
const { t } = useTranslation();
2316
const [recaptchaString, setRecaptchaString] = useState("");
2417
const hasCaptcha = !!recaptchaString;
@@ -68,4 +61,4 @@ const EditVerificationRequestDrawer: React.FC<EditVerificationRequestDrawerProps
6861
)
6962
};
7063

71-
export default EditVerificationRequestDrawer;
64+
export default EditVerificationRequestDrawer;
Lines changed: 86 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,105 @@
1-
import React, { useState, useEffect } from "react";
2-
import { Box, Grid } from "@mui/material";
1+
import React, { useState } from "react";
2+
import { Grid } from "@mui/material";
33
import AddIcon from "@mui/icons-material/Add";
44
import DeleteIcon from "@mui/icons-material/Delete";
55
import { useTranslation } from "next-i18next";
66
import AletheiaButton, { ButtonType } from "../../../Button";
77
import AletheiaInput from "../../../AletheiaInput";
8+
import { IInputExtraSourcesList } from "../../../../types/VerificationRequest";
9+
import { SourceType } from "../../../../types/Source";
810

9-
interface IInputExtraSourcesList {
10-
value: any;
11-
onChange: (value: any[]) => void;
12-
disabled: boolean;
13-
placeholder: string;
14-
}
11+
const formatSources = (sources: SourceType[]) => {
12+
const sourceArray = Array.isArray(sources) ? sources : [];
13+
if (sourceArray.length === 0) return [createEmptySource()];
1514

16-
const InputExtraSourcesList = ({ value, onChange, disabled, placeholder }: IInputExtraSourcesList) => {
17-
const { t } = useTranslation();
15+
return sourceArray.map((source) => ({
16+
id: source._id,
17+
href: typeof source === "object" ? source.href : source || "",
18+
isNewSource: !!(typeof source === "object" ? source.href : source),
19+
}));
20+
};
1821

19-
const [items, setItems] = useState(() => {
20-
const initialArray = Array.isArray(value) ? value : [];
21-
if (initialArray.length === 0) return [{ id: Math.random(), text: "", isOriginal: false }];
22+
const createEmptySource = () => ({
23+
id: Math.random().toString(),
24+
href: "",
25+
isNewSource: false
26+
});
2227

23-
return initialArray.map((item) => {
24-
const isObject = typeof item === "object" && item !== null;
25-
const textValue = isObject ? item.href : item;
26-
return {
27-
id: item._id || Math.random(),
28-
text: textValue || "",
29-
isOriginal: !!textValue,
30-
};
31-
});
32-
});
28+
const InputExtraSourcesList = ({ sources, onChange, disabled, placeholder }: IInputExtraSourcesList) => {
29+
const { t } = useTranslation();
30+
const [sourcesList, setSourcesList] = useState(() => formatSources(sources as SourceType[]));
3331

34-
useEffect(() => {
35-
handleNotifyChange(items);
36-
}, []);
32+
const handleSubmit = (hrefsList: typeof sourcesList) => {
33+
const updatedHrefs = [...new Set(hrefsList.map(source => source.href.trim()).filter(Boolean))];
34+
onChange(updatedHrefs);
35+
};
3736

38-
const handleNotifyChange = (newItems: any[]) => {
39-
setItems(newItems);
40-
const uniqueTexts = Array.from(
41-
new Set(
42-
newItems
43-
.map(i => i.text.trim())
44-
.filter(text => text !== "")
45-
)
46-
);
37+
const updateSources = (id: string, newHref: string) => {
38+
const newHrefList = sourcesList.map(source => source.id === id ? { ...source, href: newHref } : source);
39+
setSourcesList(newHrefList);
40+
handleSubmit(newHrefList);
41+
};
4742

48-
onChange(uniqueTexts);
49-
};
43+
const addField = () => {
44+
if (disabled) return;
45+
const newHrefList = [...sourcesList, createEmptySource()];
46+
setSourcesList(newHrefList);
47+
handleSubmit(newHrefList);
48+
};
5049

51-
const addField = () => {
52-
if (disabled) return;
53-
handleNotifyChange([...items, { id: Math.random(), text: "", isOriginal: false }]);
54-
};
50+
const removeField = (id: string, index: number) => {
51+
if (disabled || index === 0) return;
52+
const newHrefList = sourcesList.filter((source) => source.id !== id);
5553

56-
const removeField = (id: any) => {
57-
const index = items.findIndex((item) => item.id === id);
58-
if (disabled || index === 0) return;
59-
handleNotifyChange(items.filter((item) => item.id !== id));
60-
};
54+
setSourcesList(newHrefList);
55+
handleSubmit(newHrefList);
56+
};
6157

62-
const updateField = (id: any, newText: string) => {
63-
const updatedItems = items.map((item) =>
64-
item.id === id ? { ...item, text: newText } : item
65-
);
66-
handleNotifyChange(updatedItems);
67-
};
58+
return (
59+
<Grid container justifyContent="center">
60+
{sourcesList.map((source, index) => (
61+
<Grid item
62+
key={source.id}
63+
style={{
64+
display: "flex",
65+
width: "100%",
66+
gap: 12,
67+
marginTop: 12
68+
}}
69+
>
70+
<AletheiaInput
71+
value={source.href}
72+
disabled={disabled || (index === 0 && source.isNewSource)}
73+
onChange={(newHref) => updateSources(source.id, newHref.target.value)}
74+
placeholder={t(placeholder)}
75+
white="true"
76+
/>
6877

69-
return (
70-
<Grid container>
71-
{items.map((item, index) => (
72-
<Box key={item.id} sx={{ display: "flex", width: "100%", gap: 1, mt: 1 }}>
73-
<AletheiaInput
74-
value={item.text}
75-
disabled={disabled || (index === 0 && item.isOriginal)}
76-
onChange={(e) => updateField(item.id, e.target.value)}
77-
placeholder={t(placeholder)}
78-
white="true"
79-
/>
78+
{!disabled && index !== 0 && (
79+
<AletheiaButton
80+
onClick={() => removeField(source.id, index)}
81+
style={{ minWidth: "40px" }}
82+
>
83+
<DeleteIcon fontSize="small" />
84+
</AletheiaButton>
85+
)}
86+
</Grid>
87+
))}
8088

81-
{!disabled && index !== 0 && (
82-
<AletheiaButton
83-
onClick={() => removeField(item.id)}
84-
style={{ minWidth: "40px" }}
85-
>
86-
<DeleteIcon fontSize="small" />
87-
</AletheiaButton>
88-
)}
89-
</Box>
90-
))}
91-
92-
{!disabled && (
93-
<AletheiaButton
94-
type={ButtonType.blue}
95-
onClick={addField}
96-
style={{ marginTop: "8px" }}
97-
>
98-
<AddIcon fontSize="small" />
99-
</AletheiaButton>
100-
)}
101-
</Grid>
102-
);
89+
{!disabled && (
90+
<Grid item>
91+
<AletheiaButton
92+
type={ButtonType.blue}
93+
onClick={addField}
94+
style={{ marginTop: 12 }}
95+
>
96+
<AddIcon fontSize="small" />
97+
{t("sourceForm:addNewSourceButton")}
98+
</AletheiaButton>
99+
</Grid>
100+
)}
101+
</Grid>
102+
);
103103
};
104104

105-
export default InputExtraSourcesList;
105+
export default InputExtraSourcesList;

src/components/VerificationRequest/verificationRequestForms/formInputs/ReportTypeSelect.tsx

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,45 +4,46 @@ import { ContentModelEnum } from "../../../../types/enums";
44
import { SelectInput } from "../../../Form/ClaimReviewSelect";
55
import { useEffect, useState } from "react";
66
import { useTranslation } from "react-i18next";
7+
import { IReportTypeSelect } from "../../../../types/VerificationRequest";
78

89
const ReportTypeSelect = ({
9-
onChange,
10-
defaultValue,
11-
placeholder,
12-
style = {},
13-
isDisabled,
14-
}) => {
15-
const [value, setValue] = useState(defaultValue || "");
16-
const { t } = useTranslation();
10+
onChange,
11+
defaultValue,
12+
placeholder,
13+
style = {},
14+
isDisabled,
15+
}: IReportTypeSelect) => {
16+
const [value, setValue] = useState(defaultValue || "");
17+
const { t } = useTranslation();
1718

18-
const onChangeSelect = (e) => {
19-
setValue(e.target.value);
20-
};
19+
const onChangeSelect = (e) => {
20+
setValue(e.target.value);
21+
};
2122

22-
useEffect(() => {
23-
onChange(value || undefined);
24-
}, [value, onChange]);
23+
useEffect(() => {
24+
onChange(value || undefined);
25+
}, [value, onChange]);
2526

26-
return (
27-
<FormControl fullWidth>
28-
<SelectInput
29-
displayEmpty
30-
onChange={onChangeSelect}
31-
value={value}
32-
style={style}
33-
disabled={isDisabled}
34-
>
35-
<MenuItem value="" disabled>
36-
{placeholder}
37-
</MenuItem>
38-
{Object.values(ContentModelEnum).map((option) => (
39-
<MenuItem key={option} value={option}>
40-
{t(`claimForm:${option}`)}
41-
</MenuItem>
42-
))}
43-
</SelectInput>
44-
</FormControl>
45-
);
27+
return (
28+
<FormControl fullWidth>
29+
<SelectInput
30+
displayEmpty
31+
onChange={onChangeSelect}
32+
value={value}
33+
style={style}
34+
disabled={isDisabled}
35+
>
36+
<MenuItem value="" disabled>
37+
{placeholder}
38+
</MenuItem>
39+
{Object.values(ContentModelEnum).map((option) => (
40+
<MenuItem key={option} value={option}>
41+
{t(`claimForm:${option}`)}
42+
</MenuItem>
43+
))}
44+
</SelectInput>
45+
</FormControl>
46+
);
4647
};
4748

4849
export default ReportTypeSelect;

0 commit comments

Comments
 (0)