export function SimpleForm()

in apps/newsletters-ui/src/app/components/SimpleForm.tsx [37:161]


export function SimpleForm<T extends z.ZodRawShape>({
	title,
	submitButtonText = 'SUBMIT FORM',
	schema,
	initialData,
	submit,
	isDisabled,
	message,
	maxOptionsForRadioButtons,
	stringConfig = {},
	explanations = {},
}: Props<T>) {
	const [parseInitialDataResult, setParseInitialDataResult] = useState<
		z.SafeParseReturnType<typeof schema, SchemaObjectType<T>> | undefined
	>(undefined);
	const [data, setData] = useState<SchemaObjectType<T>>();
	const [warnings, setWarnings] = useState<Partial<Record<keyof T, string>>>(
		{},
	);

	// If data has not already been set and the initial data has not
	// already been found invalid, parse the initialData.
	// If initialData is valid, setData to initialData
	useEffect(() => {
		if (data || parseInitialDataResult?.success === false) {
			return;
		}
		setParseInitialDataResult(schema.safeParse(initialData));
		if (parseInitialDataResult?.success) {
			setData(initialData);
		}
	}, [initialData, parseInitialDataResult?.success, schema, data]);

	if (parseInitialDataResult && !parseInitialDataResult.success) {
		console.warn(parseInitialDataResult.error);
		return <>INITIAL DATA WAS INVALID</>;
	}

	if (!data) {
		return null;
	}

	const manageChange = (value: FieldValue, key: FieldDef) => {
		const mod = getModification(value, key);
		const revisedData: SchemaObjectType<T> = {
			...data,
			...mod,
		};

		updateDataAndWarnings(revisedData);
	};

	const updateDataAndWarnings = (revisedData: SchemaObjectType<T>) => {
		setWarnings({});
		const parseResult = schema.safeParse(revisedData);
		const issueMap: Partial<Record<keyof T, string>> = {};

		if (parseResult.success) {
			setData(parseResult.data as T);
		} else {
			parseResult.error.issues.forEach((issue) => {
				const { message, path, code } = issue;
				const key =
					typeof path[0] === 'string' ? (path[0] as keyof T) : undefined;

				if (key) {
					issueMap[key] = message || code;
				}
			});
		}
		setWarnings(issueMap);
	};

	const handleReset = () => {
		if (!parseInitialDataResult || isDisabled) {
			return;
		}
		updateDataAndWarnings(parseInitialDataResult.data);
	};

	const handleSubmit = () => {
		if (isDisabled) {
			return;
		}
		const result = schema.safeParse(data);
		if (result.success) {
			return submit(result.data);
		}
		console.warn(result.error);
	};

	return (
		<Box elevation={3} padding={2} component={Paper} marginBottom={1.5}>
			<Typography variant="h3" component={'legend'}>
				{title}
			</Typography>

			<Box marginBottom={2}>
				<Button variant="outlined" onClick={handleReset} disabled={isDisabled}>
					Reset
				</Button>
			</Box>

			<SchemaForm
				schema={schema}
				data={data}
				changeValue={manageChange}
				validationWarnings={warnings}
				readOnlyKeys={isDisabled ? Object.keys(schema.shape) : undefined}
				maxOptionsForRadioButtons={maxOptionsForRadioButtons}
				stringConfig={stringConfig}
				explanations={explanations}
			/>
			<Box marginBottom={2}>
				<Button
					variant="contained"
					onClick={() => void handleSubmit()}
					disabled={isDisabled}
				>
					{submitButtonText}
				</Button>
			</Box>
		</Box>
	);
}