From 30ce03a26283dca1a268807a982eb4050f18242e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Fricks?= Date: Mon, 9 Dec 2024 21:53:28 -0300 Subject: [PATCH 1/3] improvement: Add server-side authentication check in user edit --- src/features/user/edit/index.tsx | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/features/user/edit/index.tsx b/src/features/user/edit/index.tsx index 2252737..17498d4 100644 --- a/src/features/user/edit/index.tsx +++ b/src/features/user/edit/index.tsx @@ -2,6 +2,7 @@ import { useRouter } from "next/router"; import { useContext, useEffect } from "react"; import { SubmitHandler, useForm } from "react-hook-form"; import { Box, Button, Flex, Heading, Divider, SimpleGrid, VStack, HStack } from "@chakra-ui/react"; +import { parseCookies } from "nookies"; import { Input } from "@/shared/components/Form/Input"; import { Toast } from "@/components/Toast"; @@ -135,3 +136,19 @@ export function UserEdit() { ); } + +export const getServerSideProps = async (ctx: any) => { + const { ["nextauth.token"]: token } = parseCookies(ctx); + + if (!token) { + return { + redirect: { + destination: "/", + permanent: false + } + }; + } + return { + props: {} + }; +}; From 90759f7710786f4e51e1b10a81eb2fade0fa11cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Fricks?= Date: Mon, 9 Dec 2024 21:55:33 -0300 Subject: [PATCH 2/3] improvement: Enhance user edit form validation and error handling --- src/contexts/AuthContext.tsx | 9 ++------- src/features/user/edit/index.tsx | 33 ++++++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx index ae3a75c..2bd65ee 100644 --- a/src/contexts/AuthContext.tsx +++ b/src/contexts/AuthContext.tsx @@ -95,13 +95,8 @@ export function AuthProvider({ children }: { children: React.ReactNode }) { throw new Error("No authenticated user."); } - try { - const updatedUser = await updateUserProfile(token, data); - setUser(prevUser => (prevUser ? { ...prevUser, ...updatedUser } : null)); - } catch (error) { - console.error("Failed to update user.", error); - throw error; - } + const updatedUser = await updateUserProfile(token, data); + setUser(prevUser => (prevUser ? { ...prevUser, ...updatedUser } : null)); } function signOut() { diff --git a/src/features/user/edit/index.tsx b/src/features/user/edit/index.tsx index 17498d4..7db3d9f 100644 --- a/src/features/user/edit/index.tsx +++ b/src/features/user/edit/index.tsx @@ -1,8 +1,10 @@ +import { z } from "zod"; import { useRouter } from "next/router"; -import { useContext, useEffect } from "react"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { parseCookies } from "nookies"; import { SubmitHandler, useForm } from "react-hook-form"; +import { useContext, useEffect, useState } from "react"; import { Box, Button, Flex, Heading, Divider, SimpleGrid, VStack, HStack } from "@chakra-ui/react"; -import { parseCookies } from "nookies"; import { Input } from "@/shared/components/Form/Input"; import { Toast } from "@/components/Toast"; @@ -19,10 +21,20 @@ type RegisterForm = { // password_confirmation: string; }; +const UserEditFormSchema = z.object({ + name: z.string().min(1, "Campo obrigatório."), + email: z.string().email("E-mail inválido.").min(1, "Campo obrigatório."), + about: z.string().max(255, "Máximo de 255 caracteres."), + website_url: z.string() + // .url("URL inválida.") +}); + +type UserEditFormSchema = z.infer; + export function UserEdit() { const router = useRouter(); const { addToast } = Toast(); - + const [isError, setIsError] = useState(false); const { user, updateUser } = useContext(AuthContext); const { @@ -30,7 +42,10 @@ export function UserEdit() { handleSubmit, formState: { errors, isSubmitting }, reset - } = useForm(); + } = useForm({ + resolver: zodResolver(UserEditFormSchema), + mode: "onChange" + }); useEffect(() => { if (user) { @@ -47,19 +62,20 @@ export function UserEdit() { about: values.about, website_url: values.website_url }); - addToast({ title: "Usuário editado com sucesso.", message: "Seu perfil foi atualizado.", type: "success" }); - } catch (error) { + setIsError(false); + } catch (error: any) { addToast({ title: "Erro ao editar usuário.", - message: `Ocorreu um erro ao editar seu perfil: ${error}`, + message: `Ocorreu um erro ao editar seu perfil: ${error.response.data.error.message}`, type: "error" }); - console.log("Erro ao editar usuário:", error); + console.error(error); + setIsError(true); } }; @@ -95,6 +111,7 @@ export function UserEdit() { placeholder="Ex. www.site.com.br" {...register("website_url")} error={errors.website_url} + isInvalid={isError} /> From 3232c0d9fdfdba151c7b5c2576f62b081ad0646a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Paulo=20Fricks?= Date: Tue, 10 Dec 2024 14:13:19 -0300 Subject: [PATCH 3/3] improvement: Add username field to user edit form and update validation schema --- src/contexts/AuthContext.tsx | 2 +- src/features/user/edit/index.tsx | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx index 2bd65ee..f982da5 100644 --- a/src/contexts/AuthContext.tsx +++ b/src/contexts/AuthContext.tsx @@ -20,7 +20,7 @@ type User = { website_url: string; }; -type UpdateUserData = Pick; +type UpdateUserData = Pick; type AuthContextType = { isAuthenticated: boolean; diff --git a/src/features/user/edit/index.tsx b/src/features/user/edit/index.tsx index 7db3d9f..3bff8af 100644 --- a/src/features/user/edit/index.tsx +++ b/src/features/user/edit/index.tsx @@ -23,6 +23,7 @@ type RegisterForm = { const UserEditFormSchema = z.object({ name: z.string().min(1, "Campo obrigatório."), + username: z.string().min(1, "Campo obrigatório."), email: z.string().email("E-mail inválido.").min(1, "Campo obrigatório."), about: z.string().max(255, "Máximo de 255 caracteres."), website_url: z.string() @@ -58,6 +59,7 @@ export function UserEdit() { await updateUser({ id: user ? user.id : "", name: values.name, + username: user ? user.username : "", email: values.email, about: values.about, website_url: values.website_url @@ -88,6 +90,9 @@ export function UserEdit() { + + +