addPost.ts:
import * as z from 'zod';
import { db } from '@/lib/db';
import { PostSchema } from '@/schemas';
import { auth } from '@/auth/auth';
export const addPost = async (values: z.infer<typeof PostSchema>) => {
const validatedFields = PostSchema.safeParse(values);
const session = await auth();
if (!session) {
return { error: 'Twoja sesja nie istnieje!' };
}
if (!validatedFields.success) {
return {
error:
'Nieprawidłowe dane (tytł musi mieć minimum 2 litery, a treść minimum 10 liter)',
};
}
const { title, content, category, image, userWhoAdded } =
validatedFields.data;
await db.post.create({
data: {
title: title,
image: image,
userWhoAdded: userWhoAdded,
content: content,
category: category,
},
});
return { success: 'Poprawnie dodano post!' };
};
addPostForm:
import MaxWidthWrapper from '@/components/MaxWidthWrapper';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import {
Form,
FormControl,
FormField,
FormMessage,
FormItem,
FormLabel,
} from '@/components/ui/form';
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import 'react-quill/dist/quill.snow.css';
import ReactQuill from 'react-quill';
import * as z from 'zod';
import { PostSchema } from '@/schemas';
import { Input } from '@/components/ui/input';
import { useTransition, useState } from 'react';
import { addPost } from '@/actions/addPost';
import { Button } from '@/components/ui/button';
import { auth } from '@/auth/auth';
import { useSession } from 'next-auth/react';
export default function AddPostForm() {
const [isPending, startTransition] = useTransition();
const { data } = useSession();
const form = useForm<z.infer<typeof PostSchema>>({
resolver: zodResolver(PostSchema),
defaultValues: {
title: '',
content: '',
userWhoAdded: `${data?.user.firstname} ${data?.user.lastname}`,
},
});
const onSubmit = async (values: z.infer<typeof PostSchema>) => {
startTransition(() => {
addPost(values).then((data) => {
console.log(data);
});
});
console.log(values);
};
return (
<div className="flex min-h-screen flex-col items-center bg-white relative overflow-hidden w-full">
<MaxWidthWrapper className="flex flex-col items-center justify-center mt-7">
<h1 className="text-3xl font-bold mb-5">Dodaj post</h1>
<div className="w-full">
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
<div className="flex flex-col gap-y-6">
<div className="flex flex-row gap-x-1 justify-center items-center">
<FormField
control={form.control}
name="title"
render={({ field }) => (
<FormItem className="w-2/3">
<FormLabel>Tytuł</FormLabel>
<FormControl>
<Input
placeholder="Tytuł"
{...field}
type="text"
disabled={isPending}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="category"
render={({ field }) => (
<FormItem className="w-1/3">
<FormLabel>Kategoria posta</FormLabel>
<Select
onValueChange={field.onChange}
value={field.value}
>
<FormControl>
<SelectTrigger>
<SelectValue placeholder="Wybierz kategorie posta" />
</SelectTrigger>
</FormControl>
<SelectContent>
<SelectItem value="notice">
Ogłoszenie parafialne
</SelectItem>
<SelectItem value="intension">
Intencja mszalna
</SelectItem>
<SelectItem value="devotion">
Nabożeństwo
</SelectItem>
<SelectItem value="transmission">
Transmisja
</SelectItem>
<SelectItem value="paschalTriduum">
Triduum Paschalne
</SelectItem>
</SelectContent>
</Select>
</FormItem>
)}
/>
</div>
<div className="flex flex-col gap-y-4">
<FormField
control={form.control}
name="image"
render={({ field }) => (
<FormItem className="w-full">
<FormLabel>Zdjęcie</FormLabel>
<FormControl>
<Input
placeholder="Link do zdjęcia"
{...field}
type="text"
disabled={isPending}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<p className="text-sm">
Jak podać link do zdjęcia? <br />
Wejdź na stronę taką jak np:{' '}
<a
href="https://postimages.org/"
className="text-indigo-500"
>
https://postimages.org/
</a>
{' albo '}
<br />
<a
href="https://postimages.org/"
className="text-indigo-500"
>
https://imgbb.com/
</a>{' '}
Następnie prześlij tam swoje zdjęcie <br />
Potem dostaniesz link do swojego zdjęcia. <br />
</p>
<p className="tex-sm font-semibold">
Wklej go nad tą wiadomością
</p>
</div>
<FormField
control={form.control}
name="content"
render={({ field }) => (
<FormItem className="mb-12">
<FormLabel>Treść</FormLabel>
<FormControl>
<ReactQuill
{...field}
theme="snow"
placeholder="Napisz coś ..."
className="h-72 max-w-[30rem]"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
<Button
type="submit"
className="w-full mt-12"
disabled={isPending}
>
Dodaj post
</Button>
</form>
</Form>
</div>
</MaxWidthWrapper>
</div>
);
}
Post schema in prisma:
id String @id @default(cuid())
userWhoAdded String
createdAt DateTime @default(now())
title String
content String
category String
image String?
user User @relation(fields: [userWhoAdded], references: [username])
}
Post schema:
title: z.string().min(2, { message: 'Tytuł musi mieć minimum 2 znaki' }),
content: z.string().min(10, {
message: 'Treść musi mieć minimum 10 znaków',
}),
userWhoAdded: z.string(),
category: z.enum([
'notice',
'intension',
'devotion',
'transmission',
'paschalTriduum',
]),
image: z.string().optional(),
});
Error while pushing post to database
Unhandled Runtime Error
Error:
Invalid prisma.post.create()
invocation:
Foreign key constraint failed on the field: Post_userWhoAdded_fkey (index)
Source
src/actions/addPost.ts (30:2) @ async $$ACTION_0
28 | console.log(userWhoAdded);
29 |
30 | await db.post.create({
| ^
31 | data: {
32 | title: title,
33 | image: image,
I don’t even know why i get this problem and what i need to change if someone can explain it to me and help with repairing this
I want fast help i tried setting userWhoAdded to static string “” and even then i get this error