this post, we will dive deep into the critical sections of the code that power the blog application. It uses Next.js, Prisma ORM for database management, and various utility functions to handle authentication, validation, and user interaction. Let’s break it down into key sections.
1. Validation Schema Using Zod
const addSchema = z.object({
email: z.string().email().max(20),
password: z.string().min(3),
remember: z
.union([z.string(), z.undefined()])
.transform((val) => val === "on"),
})
The Zod schema is used for validating the incoming form data. In this case, we’re validating the email, password, and remember fields from the login form.
- The email field is required to be a valid email address and has a maximum length of 20 characters.
- The password must have a minimum length of 3 characters.
- The remember field checks if the value is 'on', transforming it into a boolean true for remembering the session, or false if undefined.
2. Handling Form Submission and Login Logic
export default async function login(prevState: unknown, formData: FormData) {
const result = addSchema.safeParse(Object.fromEntries(formData.entries()));
if (result.success === false) {
return { error: result.error.formErrors.fieldErrors }
}
const data = result.data;
let { email, password, remember } = data;
try {
const user = await prisma.user.findUnique({
where: { email },
});
if (user && await isValidPassword(password, user.password)) {
return await loginUser(user, remember);
} else {
return { error: { message: "Incorrect user or password" } }
}
} catch (error) {
return { error: { message: error + "" } }
}
}
The login function handles the core login process.
First, it validates the form data using the previously defined Zod schema.
If validation fails, it returns error messages for the respective fields.
The function then queries the database using Prisma to check if a user with the provided email exists. If found, it compares the provided password with the hashed password stored in the database using the isValidPassword function.
If the password is correct, it triggers a login process via the loginUser function.
If no matching user is found or the password is incorrect, an error message is returned.
3. Prisma Database Schema
model User {
id Int @id @default(autoincrement())
email String @unique
name String
password String
posts Post[]
}
Here, we define the User model in the Prisma schema. It has the following fields:
- id: A unique identifier for each user.
- email: The user's email address (unique).
- name: The user's name.
- password: The hashed password of the user.
- posts: A one-to-many relationship where each user can have multiple posts.
4. Rendering Posts in the Blog Page
export default async function Blog() {
const posts = await prisma.post.findMany({
include: { user: true },
});
const user = await getSession();
return (
<div className="mb-10">
{posts.map((post) => (
<div key={post.id} className="post-container">
<div>{post.subject}</div>
<div>{post.user.name}</div>
<div>{post.detail}</div>
<span>{post.like} <LikeButton id={post.id} /></span>
</div>
))}
</div>
);
}
In the Blog component, the posts are fetched from the database using Prisma’s findMany method. The code renders each post’s subject, detail, and user name. If the user is logged in, they can also interact with the posts (like/unlike posts, edit, or delete).
- Post Rendering: Each post is displayed with its subject, - details, and the associated user.
- Like/Unlike: A LikeButton component is used to handle the interaction of liking or unliking a post.
- Edit/Delete Options: If the logged-in user is the author of the post, they can edit or delete their posts.
5. Handling Post Deletion and Like/Unlike Logic
import { likePost, unlikePost } from "./_actions/likePost";
import deletePost from "./_actions/deletePost";
These helper functions, imported from the _actions folder, provide the functionality to manage post likes and deletions. The likePost and unlikePost functions update the like count for each post, while deletePost removes a post from the database.
6. Logout and Authentication Handling
The Logout and getSession functions help manage user authentication. The getSession function checks whether a user is logged in, and the Logout component handles logging out the user.
Top comments (0)