Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@ import {
BreadcrumbList,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbSeparator,
BreadcrumbEllipsis,
BreadcrumbPage,
} from '@/components/Breadcrump';
import { Home } from 'lucide-react';

export function DefaultScreen() {
const { nextStep, previousStep, resetPetNewsValues } =
Expand Down
101 changes: 50 additions & 51 deletions src/app/(app)/pet-register/components/NameAndGender.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,61 +3,60 @@ import { Button } from '@/components/Button';
import { ToggleGroup, ToggleGroupItem } from '@/components/ToggleGroup';
import { IconFemale } from '@/components/icons/IconFemale';
import { IconMale } from '@/components/icons/IconMale';
import { ChangeEvent, useContext } from 'react';
import { useContext } from 'react';
import { PetRegisterContext } from '../context/PetRegisterContext';
import { usePetRegisterSteps } from './usePetRegisterSteps';
import { species } from '@/utils/species';
import { InputControl } from '@/components/Fields/InputControl';
import { Label } from '@/components/Label';
import { Input } from '@/components/Fields/Input';
import {
Breadcrumb,
BreadcrumbList,
BreadcrumbItem,
BreadcrumbLink,
} from '@/components/Breadcrump';
import { Home } from 'lucide-react';
import Image from 'next/image';
import { useForm } from 'react-hook-form';
import { NameAndGenderProps, nameAndGenderSchema } from '@/schemas/PetRegister/NameAndGender';
import { zodResolver } from '@hookform/resolvers/zod';
import { Label } from '@/components/Label';
import { InputMessage } from '@/components/Fields/InputMessage';

export function NameAndGender() {
const { newPet } = useContext(PetRegisterContext);
const { error, clickNextStep, clickPreviousStep, setError, pet, setPet } =
usePetRegisterSteps();
const { clickNextStep, clickPreviousStep, pet, setPet } = usePetRegisterSteps();

const specieName = species[pet.specieName as keyof typeof species];

function handleClickNextStep() {
if (!pet.gender || !pet.petName) {
clickNextStep(null);
return;
}
clickNextStep({
...newPet,
gender: pet.gender,
petName: pet.petName,
});
}
const {
handleSubmit,
register,
formState: { errors },
setValue,
getValues,
clearErrors,
} = useForm<NameAndGenderProps>({
resolver: zodResolver(nameAndGenderSchema),
criteriaMode: 'firstError',
reValidateMode: 'onChange',
mode: 'onBlur',
});

function handleClickPreviousStep() {
clickPreviousStep();
}

function handleOnChangePetName(evt: ChangeEvent<HTMLInputElement>) {
setError(false);
const { value } = evt.target;

setPet((state) => ({
...state,
petName: value,
}));
function handleClickNextStep(data: NameAndGenderProps) {
clickNextStep({
...newPet,
gender: data.gender,
petName: data.petName,
});
}

function handleOnChangeGender(value: string) {
setError(false);
setPet((state) => ({
...state,
gender: value,
}));
function handleGenderChange(value: string) {
setValue('gender', value, { shouldValidate: true });
clearErrors('gender')
}

return (
Expand All @@ -81,63 +80,59 @@ export function NameAndGender() {
</Breadcrumb>
<h3 className="text-xl font-bold text-left text-studio-600 w-full">
<span className="block mb-4">Uau!</span>
Ficamos muito felizes em receber mais um {specieName} em nossa
comunidade!
Ficamos muito felizes em receber mais um {specieName} em nossa comunidade!
</h3>

<InputControl className="w-full">
<span className="text-base text-center ">
<span className="text-base text-center font-bold text-neutral-900">
Qual o nome do seu companheiro?
</span>
<label htmlFor="petName" className="text-xs">
<Label htmlFor="petName" className="text-xs">
Nome:
</label>
</Label>
<Input
type="text"
name="petName"
id="petName"
placeholder="Nome de seu Pet"
variant="secondary"
className="bg-white placeholder:text-sm"
defaultValue={pet.petName}
onChange={handleOnChangePetName}
defaultValue={pet?.petName}
{...register('petName')}
required
/>
<span className="text-gray-400 text-xs">*Campo obrigatório</span>
{errors?.petName && (
<InputMessage variant="error" message={errors.petName.message} />
)}
</InputControl>

<div className="flex flex-col gap-2 ">
<span className="text-center text-base">Qual o sexo de seu Pet?</span>
<ToggleGroup
type="single"
defaultValue={pet.gender}
onValueChange={handleOnChangeGender}
defaultValue={getValues('gender')}
onValueChange={handleGenderChange}
className="gap-8"
>
<ToggleGroupItem
value="M"
className="flex flex-col gap-1 w-[120px] h-[120px] p-5 border-2 border-dashed bg-white border-gray-400 rounded-2xl text-gray-700 hover:bg-white hover:border-studio-600 hover:text-gray-700 data-[state=on]:bg-white data-[state=on]:border-solid data-[state=on]:border-studio-600 data-[state=on]:text-gray-700"
className="flex flex-col gap-1 w-[120px] h-[120px] p-5 border-2 border-dashed bg-white border-gray-400 rounded-3xl text-gray-700 hover:bg-white hover:border-studio-600 hover:text-gray-700 data-[state=on]:bg-white data-[state=on]:border-solid data-[state=on]:border-studio-600 data-[state=on]:text-gray-700"
>
<IconMale size={60} />
<span className="text-sm">Macho</span>
</ToggleGroupItem>
<ToggleGroupItem
value="F"
className="flex flex-col gap-1 w-[120px] h-[120px] p-5 border-2 border-dashed bg-white border-gray-400 rounded-2xl text-gray-700 hover:bg-white hover:border-studio-600 hover:text-gray-700 data-[state=on]:bg-white data-[state=on]:border-solid data-[state=on]:border-studio-600 data-[state=on]:text-gray-700"
className="flex flex-col gap-1 w-[120px] h-[120px] p-5 border-2 border-dashed bg-white border-gray-400 rounded-3xl text-gray-700 hover:bg-white hover:border-studio-600 hover:text-gray-700 data-[state=on]:bg-white data-[state=on]:border-solid data-[state=on]:border-studio-600 data-[state=on]:text-gray-700"
>
<IconFemale size={60} />
<span className="text-sm">Fêmea</span>
</ToggleGroupItem>
</ToggleGroup>
<span className="text-gray-400 text-xs">*Campo obrigatório</span>
{errors?.gender && (
<InputMessage variant="error" message={errors.gender.message} />
)}
</div>

{error && (
<span className="text-red-400 text-sm text-center">
Preencha todas as informações...
</span>
)}

<div className="mt-auto w-full flex justify-around">
<Button
variant="outline"
Expand All @@ -146,7 +141,11 @@ export function NameAndGender() {
>
Voltar
</Button>
<Button className="font-bold" onClick={handleClickNextStep}>
<Button
className="font-bold"
onClick={handleSubmit(handleClickNextStep)}
disabled={!getValues('petName') || !getValues('gender')}
>
Continuar
</Button>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/app/(app)/pet-register/components/PetRegister.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';
import { useContext, useEffect, useState } from 'react';
import { DefaultScreen } from './DefaultScren';
import { DefaultScreen } from './DefaultScreen';
import { Specie } from './Specie';
import { NameAndGender } from './NameAndGender';
import { SizeAndBreed } from './SizeAndBreed';
Expand Down
33 changes: 13 additions & 20 deletions src/app/(app)/pet-register/components/SizeAndBreed.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';
import { Button } from '@/components/Button';
import { ChangeEvent, useContext, useEffect, useState } from 'react';
import { useContext } from 'react';
import { PetRegisterContext } from '../context/PetRegisterContext';
import { usePetRegisterSteps } from './usePetRegisterSteps';
import {
Expand All @@ -20,7 +20,7 @@ import {
BreadcrumbLink,
BreadcrumbSeparator,
} from '@/components/Breadcrump';
import { Home } from 'lucide-react';
import { SearchInput } from '@/components/Fields/SearchInput';

export function SizeAndBreed() {
const { newPet, breeds, sizes } = useContext(PetRegisterContext);
Expand Down Expand Up @@ -55,7 +55,6 @@ export function SizeAndBreed() {

function handleOnChangeBreed(value: string) {
setError(false);

setPet((state) => ({
...state,
breedName: value,
Expand Down Expand Up @@ -107,25 +106,19 @@ export function SizeAndBreed() {
</Select>
</label>

{/* TODO: Adicionar a opção de outros */}
<label className="flex flex-col gap-1">
<span>Raça</span>
<Select onValueChange={handleOnChangeBreed}>
<SelectTrigger>
<SelectValue placeholder="Porte do seu pet" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<ScrollArea className="h-[150px] mr-1">
{breeds.map((breed) => (
<SelectItem key={breed.id} value={breed.name}>
{breed.name}
</SelectItem>
))}
</ScrollArea>
</SelectGroup>
</SelectContent>
</Select>
<SearchInput
items={breeds.map((breed) => {
return {
label: breed.name,
value: breed.name,
};
})}
onChange={handleOnChangeBreed}
value={pet.breedName}
placeholder="Porte do seu pet"
/>
</label>
</div>
)}
Expand Down
17 changes: 10 additions & 7 deletions src/app/(app)/pet-register/components/Specie.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Button } from '@/components/Button';
import { ToggleGroup, ToggleGroupItem } from '@/components/ToggleGroup';
import { IconCat } from '@/components/icons/IconCat';
import { IconDog } from '@/components/icons/IconDog';
import { useContext, useState } from 'react';
import { useContext } from 'react';
import { PetRegisterContext } from '../context/PetRegisterContext';
import { usePetRegisterSteps } from './usePetRegisterSteps';

Expand All @@ -13,7 +13,6 @@ import {
BreadcrumbItem,
BreadcrumbLink,
} from '@/components/Breadcrump';
import { Home } from 'lucide-react';
import Image from 'next/image';

export function Specie() {
Expand Down Expand Up @@ -82,17 +81,17 @@ export function Specie() {
>
<ToggleGroupItem
value="dog"
className="flex flex-col gap-1 w-[100px] h-[100px] p-5 border-2 border-gray-400 text-gray-400 hover:bg-transparent hover:border-studio-600 hover:text-studio-600 data-[state=on]:bg-transparent data-[state=on]:border-studio-600 data-[state=on]:text-studio-600 focus:border-sky-400 focus-visible:border-sky-400 focus:text-gray-400"
className="flex flex-col gap-1 w-[100px] h-[100px] p-5 border-2 border-gray-400 text-gray-400 hover:bg-transparent data-[state=on]:bg-transparent data-[state=on]:border-studio-600 data-[state=on]:text-studio-600 data-[state=off]:border-gray-400 data-[state=off]:text-gray-400"
>
<IconDog size={60} />
<span>Cachorro</span>
<span className='font-semibold'>Cachorro</span>
</ToggleGroupItem>
<ToggleGroupItem
value="cat"
className="flex flex-col gap-1 w-[100px] h-[100px] p-5 border-2 border-gray-400 text-gray-400 hover:bg-transparent hover:border-studio-600 hover:text-studio-600 data-[state=on]:bg-transparent data-[state=on]:border-studio-600 data-[state=on]:text-studio-600 focus:border-sky-400 focus-visible:border-sky-400 focus:text-gray-400"
className="flex flex-col gap-1 w-[100px] h-[100px] p-5 border-2 border-gray-400 text-gray-400 hover:bg-transparent data-[state=on]:bg-transparent data-[state=on]:border-studio-600 data-[state=on]:text-studio-600 data-[state=off]:border-gray-400 data-[state=off]:text-gray-400"
>
<IconCat size={60} />
<span>Gato</span>
<span className='font-semibold'>Gato</span>
</ToggleGroupItem>
</ToggleGroup>

Expand All @@ -110,7 +109,11 @@ export function Specie() {
>
Voltar
</Button>
<Button className="font-bold" onClick={handleClickNextStep}>
<Button
className="font-bold"
onClick={handleClickNextStep}
disabled={error}
>
Continuar
</Button>
</div>
Expand Down
6 changes: 3 additions & 3 deletions src/app/(auth)/login/components/LoginForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ export function LoginForm() {
const { error } = await submitLogin(loginData);
if (error) throw new Error(error);

const { session } = await getSession();
if (!session) {
throw new Error('Usuário não autenticado...');
const { session, error: errorSession } = await getSession();
if (errorSession || !session) {
throw new Error(errorSession ?? 'Usuário não autenticado...');
}

const { user } = session;
Expand Down
6 changes: 3 additions & 3 deletions src/app/(auth)/register/components/RegisterForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ export function RegisterForm() {
});
if (errorLogin) throw errorLogin;

const { session } = await getSession();
if (!session) {
throw new Error('Usuário não autenticado...');
const { session, error: errorSession } = await getSession();
if (errorSession || !session) {
throw new Error(errorSession ?? 'Usuário não autenticado...');
}

const { user } = session;
Expand Down
2 changes: 1 addition & 1 deletion src/components/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { cn } from '@/utils/twmerge';
import { ButtonHTMLAttributes, Ref, forwardRef } from 'react';

const buttonStyleBase =
'flex self-center font-medium items-center justify-center rounded-[45px] px-11 py-3';
'flex self-center font-medium items-center justify-center px-11 py-3 rounded-2xl';

const buttonVariants = {
variant: {
Expand Down
4 changes: 2 additions & 2 deletions src/components/Fields/SearchInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ interface SearchInputItems {
}

const searchVariants = {
normal: `w-full h-10 p-2 border border-[#B2B2B2] border-dashed outline-none rounded-2xl bg-white text-[#2E2E2E] focus:outline-none focus:border-solid focus:border-[#B78AF7] focus:shadow-custom-select transition-all`,
normal: `w-full h-10 p-2 text-sm border border-[#B2B2B2] border-dashed outline-none rounded-2xl bg-white focus:outline-none focus:border-solid focus:border-[#B78AF7] focus:shadow-custom-select transition-all`,
error: `border-[#FF917A] border-solid`,
};

Expand Down Expand Up @@ -123,4 +123,4 @@ function SearchInput({
);
}

export { SearchInput };
export { SearchInput };
13 changes: 13 additions & 0 deletions src/schemas/PetRegister/NameAndGender.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { z } from 'zod';

export const nameAndGenderSchema = z.object({
petName: z.string()
.min(2, { message: "*O nome fornecido deve ter entre 2 e 30 caracteres, não são permitidos caracteres especiais, nem números. Por favor, insira um nome válido." })
.max(30, { message: "*O nome fornecido deve ter entre 2 e 30 caracteres, não são permitidos caracteres especiais, nem números. Por favor, insira um nome válido." })
.regex(/^[A-Za-zÀ-ÖØ-öø-ÿ\s]+$/, {
message: "*O nome fornecido deve ter entre 2 e 30 caracteres, não são permitidos caracteres especiais, nem números. Por favor, insira um nome válido.",
}),
gender: z.string({message: '* Campo obrigatório.'})
});

export type NameAndGenderProps = z.infer<typeof nameAndGenderSchema>;
2 changes: 1 addition & 1 deletion src/services/getSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export async function getSession() {
const accessToken = getToken();

if (!accessToken) {
throw 'Nenhum usuário autenticado...';
throw new Error('Nenhum usuário autenticado...');
}

const { error, user } = await getUser();
Expand Down
Loading