fix: uncontrolled form and fix refresh loop

This commit is contained in:
2024-12-20 16:58:20 +01:00
parent 861311d6ac
commit f91ae2eb19
2 changed files with 22 additions and 13 deletions

View File

@@ -23,12 +23,14 @@ import {
import GithubRepoChooser from '../GithubRepoChooser/GithubRepoChooser';
import React from 'react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
export default function ProjectSettings(project: Project) {
const router = useRouter();
const [ghRepo, setGhRepo] = React.useState('');
const [hasSubmitted, setHasSubmitted] = React.useState(false);
const apiUrl = `https://${window.location.hostname}/api/feedback/${project.id}`;
React.useEffect(() => {
setHasSubmitted(project.github !== '');
}, [project.github]);
return (
<div className="w-full max-w-4xl mx-auto p-4">
@@ -133,7 +135,7 @@ export default function ProjectSettings(project: Project) {
onSelect={(repo) => {
setGhRepo(`https://github.com/${repo}`);
}}
selected={project.github!.replace('https://github.com/', '')}
selected={project.github ? project.github.replace('https://github.com/', '') : ''}
/>
<p className="text-muted-foreground text-xs mt-2">
Not the results you were expecting? You may have not allowed your user in the{' '}
@@ -164,7 +166,7 @@ export default function ProjectSettings(project: Project) {
key={ghRepo}
schemaName={'githubSettings'}
action={githubSettings}
onActionComplete={() => router.refresh()}
onActionComplete={() => setHasSubmitted(true)}
/>
</CardContent>
</Card>
@@ -174,7 +176,7 @@ export default function ProjectSettings(project: Project) {
<CardDescription>Make sure your setup works!</CardDescription>
</CardHeader>
<CardContent>
{project.github ? (
{hasSubmitted ? (
<UniversalForm
fields={[
{

View File

@@ -46,29 +46,36 @@ export function UniversalForm<T extends z.ZodType>({
submitText = 'Submit',
submitClassname,
}: UniversalFormProps<T>) {
const [state, formAction] = useActionState(action, null);
// @ts-ignore idk why this error is happening, first apprearing on the react 19 update.
const [state, formAction] = useActionState<{ success: boolean; error?: string }>(action, null);
const schema = schemaDb.find((s) => s.name === schemaName)?.zod;
if (!schema) {
throw new Error(`Schema "${schemaName}" not found`);
}
// Initialize default values for all fields
const initialValues = React.useMemo(() => {
const values: Record<string, any> = {};
fields.forEach((field) => {
values[field.name] = field.value ?? ''; // Use empty string as fallback
});
return { ...values, ...defaultValues };
}, [fields, defaultValues]);
const form = useForm<z.infer<T>>({
resolver: zodResolver(schema),
defaultValues: (defaultValues || {}) as z.infer<T>,
defaultValues: initialValues as z.infer<T>,
});
// pretend nothing is happening on here
React.useEffect(() => {
// @ts-ignore
if (state && !state.success) {
// @ts-ignore
toast.error(state.error);
}
if (state) {
onActionComplete?.(state);
}
}, [state]);
}, [state, onActionComplete]);
return (
<Form {...form}>
@@ -78,7 +85,6 @@ export function UniversalForm<T extends z.ZodType>({
key={field.name}
control={form.control}
name={field.name as Path<z.infer<T>>}
defaultValue={field.value as PathValue<z.infer<T>, Path<z.infer<T>>>}
render={({ field: formField }) => (
<FormItem>
{field.type !== 'hidden' && <FormLabel>{field.label}</FormLabel>}
@@ -87,6 +93,7 @@ export function UniversalForm<T extends z.ZodType>({
type={field.type || 'text'}
placeholder={field.placeholder}
{...formField}
value={formField.value ?? ''}
/>
</FormControl>
{field.description && <FormDescription>{field.description}</FormDescription>}
@@ -99,4 +106,4 @@ export function UniversalForm<T extends z.ZodType>({
</form>
</Form>
);
}
}