fix react hook form

This commit is contained in:
João Geonizeli
2022-07-22 12:28:00 -03:00
parent feb72ce6a4
commit 20781746e6
17 changed files with 71 additions and 97 deletions

View File

@@ -4,23 +4,24 @@ import { Provider } from "react-redux";
import { BrowserRouter } from "react-router-dom"; import { BrowserRouter } from "react-router-dom";
import { Appbar } from "./components"; import { Appbar } from "./components";
import { ApolloContext } from "./contexts"; import { ApolloContext, UserContext } from "./contexts";
import { PrivateRoutes } from "./routes"; import { PrivateRoutes } from "./routes";
import { store } from "./services/store"; import { store } from "./services/store";
export const App = () => { export const App = () => {
return ( return (
<ApolloContext> <ApolloContext>
<Provider store={store}> <UserContext>
<BrowserRouter> <Provider store={store}>
<Appbar /> <BrowserRouter>
<PrivateRoutes /> <Appbar />
</BrowserRouter> <PrivateRoutes />
</Provider> </BrowserRouter>
</ApolloContext> </Provider>
</UserContext>
</ApolloContext>
); );
} };
const container = document.getElementById("app"); const container = document.getElementById("app");

View File

@@ -43,6 +43,7 @@ export const ListItem: FC<ListItemProps> = ({ icon, text, children }) => {
type ListProps = { type ListProps = {
className?: string className?: string
children: React.ReactNode
} }
export const List: FC<ListProps> = ({ export const List: FC<ListProps> = ({

View File

@@ -7,6 +7,7 @@ type Props = {
buttons?: any, buttons?: any,
title: string, title: string,
className?: string, className?: string,
children: React.ReactNode
} }
export const Modal: FC<Props> = ({ export const Modal: FC<Props> = ({

View File

@@ -11,14 +11,12 @@ export type UserContext = {
user?: Query['currentUser'] user?: Query['currentUser']
refetch: () => void refetch: () => void
isOnlyTeacher: boolean isOnlyTeacher: boolean
authToken: string
} }
const Context = createContext<UserContext>({ const Context = createContext<UserContext>({
refetch: () => { refetch: () => {
}, },
isOnlyTeacher: false, isOnlyTeacher: false,
authToken: ''
}) })
export const useCurrentUser = (): UserContext => { export const useCurrentUser = (): UserContext => {
@@ -44,10 +42,9 @@ const CurrentUserQuery = gql`
type Props = { type Props = {
children: any children: any
authToken: string
} }
export const UserContext: FC<Props> = ({ children, authToken }) => { export const UserContext: FC<Props> = ({ children }) => {
const [user, setUser] = useState<Query['currentUser']>(); const [user, setUser] = useState<Query['currentUser']>();
const isOnlyTeacher = !!(user?.roles.includes(UserRole.Teacher) && user?.roles.length === 1) const isOnlyTeacher = !!(user?.roles.includes(UserRole.Teacher) && user?.roles.length === 1)
@@ -67,7 +64,7 @@ export const UserContext: FC<Props> = ({ children, authToken }) => {
if (!user) return <UnauthorizedAccess /> if (!user) return <UnauthorizedAccess />
return ( return (
<Context.Provider value={{ user, refetch, isOnlyTeacher, authToken }}> <Context.Provider value={{ user, refetch, isOnlyTeacher }}>
{children} {children}
</Context.Provider> </Context.Provider>
); );

View File

@@ -44,9 +44,7 @@ const FiltersForm: FC = () => {
const {user, isOnlyTeacher} = userContext const {user, isOnlyTeacher} = userContext
const onSubmit = (values: FilterBarForm) => { const onSubmit = (values: FilterBarForm) => {
reset(getValues(), { reset(getValues())
isDirty: false
})
setWhere(mapFilter(values, user?.id)) setWhere(mapFilter(values, user?.id))
} }
@@ -66,7 +64,7 @@ const FiltersForm: FC = () => {
<Input <Input
type="date" type="date"
placeholder="createDate.startAt" placeholder="createDate.startAt"
ref={register({ {...register('createDate.startAt',{
maxLength: 10, maxLength: 10,
minLength: 10, minLength: 10,
})} })}
@@ -76,11 +74,10 @@ const FiltersForm: FC = () => {
<Input <Input
type="date" type="date"
placeholder="createDate.endAt" placeholder="createDate.endAt"
ref={register({ {...register('createDate.endAt', {
maxLength: 10, maxLength: 10,
minLength: 10, minLength: 10,
})} })}
name={"createDate.endAt"}
label={"Até"} label={"Até"}
/> />
</div> </div>
@@ -96,8 +93,7 @@ const FiltersForm: FC = () => {
id={"fromOtherUsers"} id={"fromOtherUsers"}
type="checkbox" type="checkbox"
placeholder="fromOtherUsers" placeholder="fromOtherUsers"
ref={register} {...register('fromOtherUsers')}
name={"fromOtherUsers"}
/> />
</span> </span>
)} )}

View File

@@ -97,9 +97,7 @@ export const Form: FC<Props> = ({question, onSubmit, onDraftSubmit, alert}) => {
const handleDraftSave = () => { const handleDraftSave = () => {
if (onDraftSubmit) { if (onDraftSubmit) {
onDraftSubmit({...getFormattedInputValues(), status: QuestionStatus.Draft} as QuestionCreateInput) onDraftSubmit({...getFormattedInputValues(), status: QuestionStatus.Draft} as QuestionCreateInput)
reset(getValues(), { reset(getValues())
isDirty: false
})
dispatch(turnOff()) dispatch(turnOff())
} }
} }
@@ -117,9 +115,7 @@ export const Form: FC<Props> = ({question, onSubmit, onDraftSubmit, alert}) => {
setValidationErrors(errors) setValidationErrors(errors)
} }
reset(getValues(), { reset(getValues())
isDirty: false
})
} }
return ( return (

View File

@@ -1,7 +1,7 @@
import React, { FC } from "react"; import React, { FC } from "react";
import { Controller } from "react-hook-form"; import { Controller } from "react-hook-form";
import CKEditor from "@ckeditor/ckeditor5-react"; import CKEditor from "@ckeditor/ckeditor5-react";
import * as ClassicEditor from "ckeditor5-mathtype/build/ckeditor"; import ClassicEditor from "ckeditor5-mathtype/build/ckeditor";
import { useFormProvider } from '../FormContext' import { useFormProvider } from '../FormContext'
@@ -37,7 +37,9 @@ export const TextEditor: FC<Props> = ({ name, defaultValue }) => {
control={control} control={control}
name={name} name={name}
defaultValue={defaultValue} defaultValue={defaultValue}
render={({ onChange, value }) => ( render={({
field: { onChange, value }
}) => (
<CKEditor <CKEditor
editor={ClassicEditor} editor={ClassicEditor}
data={value} data={value}

View File

@@ -61,25 +61,23 @@ export const FeaturesFormStep: FC = () => {
</label> </label>
<div className="my-auto"> <div className="my-auto">
<input <input
{...register('__nonused')}
className="my-auto" className="my-auto"
type="radio" type="radio"
id="authorship-own" id="authorship-own"
checked={!!ownQuestion} checked={!!ownQuestion}
ref={register}
onChange={() => handleOwnCheck("UNIFESO")} onChange={() => handleOwnCheck("UNIFESO")}
name="__nonused"
/> />
<label htmlFor="authorship-own" className="ml-1">Própria</label> <label htmlFor="authorship-own" className="ml-1">Própria</label>
</div> </div>
<div className="my-auto ml-3"> <div className="my-auto ml-3">
<input <input
{...register('__nonused')}
className="my-auto" className="my-auto"
type="radio" type="radio"
id="authorship-third" id="authorship-third"
checked={!ownQuestion} checked={!ownQuestion}
ref={register}
onChange={() => handleOwnCheck("")} onChange={() => handleOwnCheck("")}
name="__nonused"
/> />
<label htmlFor="authorship-third" className="ml-1">Outro</label> <label htmlFor="authorship-third" className="ml-1">Outro</label>
</div> </div>
@@ -90,9 +88,8 @@ export const FeaturesFormStep: FC = () => {
<div className="w-full"> <div className="w-full">
<div style={{ maxWidth: "194px" }}> <div style={{ maxWidth: "194px" }}>
<input <input
{...register('authorship')}
className="block rounded p-1 w-full border-gray-400 border shadow-sm" className="block rounded p-1 w-full border-gray-400 border shadow-sm"
ref={register}
name="authorship"
defaultValue={authorship || (ownQuestion ? "UNIFESO" : "")} defaultValue={authorship || (ownQuestion ? "UNIFESO" : "")}
readOnly={!!ownQuestion} readOnly={!!ownQuestion}
/> />
@@ -103,13 +100,12 @@ export const FeaturesFormStep: FC = () => {
<h2 className="pr-2 pl-3 my-auto">Ano</h2> <h2 className="pr-2 pl-3 my-auto">Ano</h2>
<div style={{ maxWidth: "62px" }}> <div style={{ maxWidth: "62px" }}>
<input <input
{...register('authorshipYear')}
className="w-full rounded p-1 border-gray-400 border shadow-sm" className="w-full rounded p-1 border-gray-400 border shadow-sm"
ref={register}
type="number" type="number"
min="1999" min="1999"
max={currentYear} max={currentYear}
step="1" step="1"
name="authorshipYear"
defaultValue={authorshipYear ?? new Date().getFullYear().toString()} defaultValue={authorshipYear ?? new Date().getFullYear().toString()}
readOnly={!!ownQuestion} readOnly={!!ownQuestion}
/> />
@@ -123,9 +119,8 @@ export const FeaturesFormStep: FC = () => {
<div className="flex flex-col"> <div className="flex flex-col">
<h2>Grau de Dificuldade</h2> <h2>Grau de Dificuldade</h2>
<select <select
ref={register} {...register('difficulty')}
className="w-full rounded p-1 border-gray-400 border shadow-sm" className="w-full rounded p-1 border-gray-400 border shadow-sm"
name="difficulty"
defaultValue={difficulty ?? ""} defaultValue={difficulty ?? ""}
> >
<option /> <option />
@@ -139,9 +134,8 @@ export const FeaturesFormStep: FC = () => {
<div className="w-full"> <div className="w-full">
<h2>Tipo</h2> <h2>Tipo</h2>
<select <select
ref={register} {...register("checkType")}
className="w-full rounded p-1 border-gray-400 border shadow-sm" className="w-full rounded p-1 border-gray-400 border shadow-sm"
name="checkType"
defaultValue={checkType ?? ""} defaultValue={checkType ?? ""}
> >
<option /> <option />
@@ -155,9 +149,8 @@ export const FeaturesFormStep: FC = () => {
<div className="w-full"> <div className="w-full">
<h2>Habilidade Cognitiva</h2> <h2>Habilidade Cognitiva</h2>
<select <select
ref={register} {...register('bloomTaxonomy')}
className="w-full rounded p-1 border-gray-400 border shadow-sm" className="w-full rounded p-1 border-gray-400 border shadow-sm"
name="bloomTaxonomy"
defaultValue={bloomTaxonomy ?? ""} defaultValue={bloomTaxonomy ?? ""}
> >
<option /> <option />
@@ -176,9 +169,8 @@ export const FeaturesFormStep: FC = () => {
<div className="flex flex-col mt-4"> <div className="flex flex-col mt-4">
<h2>Intenção</h2> <h2>Intenção</h2>
<textarea <textarea
{...register("intention")}
className="block rounded p-1 w-full border-gray-400 border shadow-sm" className="block rounded p-1 w-full border-gray-400 border shadow-sm"
ref={register}
name="intention"
defaultValue={question?.intention ?? ""} defaultValue={question?.intention ?? ""}
/> />
</div> </div>

View File

@@ -38,9 +38,8 @@ export const ReviewerSelect: FC<Props> = () => {
return ( return (
<select <select
ref={register} {...register('reviewerUserId')}
className="w-full rounded p-1 border-gray-400 border shadow-sm" className="w-full rounded p-1 border-gray-400 border shadow-sm"
name="reviewerUserId"
defaultValue={question?.reviewer?.id} defaultValue={question?.reviewer?.id}
> >
{(question?.status === undefined || question?.status === QuestionStatus.Draft) && <option />} {(question?.status === undefined || question?.status === QuestionStatus.Draft) && <option />}

View File

@@ -50,9 +50,8 @@ export const SubjectSelect: FC<Props> = () => {
<div> <div>
<h2>Assunto</h2> <h2>Assunto</h2>
<select <select
ref={register} {...register('subjectId')}
className="w-full rounded p-1 border-gray-400 border shadow-sm" className="w-full rounded p-1 border-gray-400 border shadow-sm"
name="subjectId"
defaultValue={question?.subject?.id ?? ""} defaultValue={question?.subject?.id ?? ""}
onChange={(e) => setSelectedId(e.target.value)} onChange={(e) => setSelectedId(e.target.value)}
> >

View File

@@ -31,9 +31,8 @@ export const AuthorshipFilter: FC<Props> = ({ setChanged, register }) => {
{options.map(({ value, label }, index) => ( {options.map(({ value, label }, index) => (
<span className="mr-1 mb-2 sm:mb-0 sm:mr-0" key={label}> <span className="mr-1 mb-2 sm:mb-0 sm:mr-0" key={label}>
<input <input
ref={register} ref={register('authorship')}
type="radio" type="radio"
name="authorship"
value={value} value={value}
id={value} id={value}
defaultChecked={!index} defaultChecked={!index}

View File

@@ -18,9 +18,8 @@ export const QuestionsAuthorshipTypeFilter: FC<Props> = ({ register, setChanged
return ( return (
<div> <div>
<select <select
ref={register} {...register('authorshipYear')}
className="w-full rounded p-1 border-gray-400 border shadow-sm" className="w-full rounded p-1 border-gray-400 border shadow-sm"
name="authorshipYear"
defaultValue={where.authorshipYear ?? ""} defaultValue={where.authorshipYear ?? ""}
onClick={() => setChanged(true)} onClick={() => setChanged(true)}
> >

View File

@@ -44,7 +44,7 @@ const FilterGroup: FC<FilterGroupProps> = ({
<input <input
type="checkbox" type="checkbox"
name={value} name={value}
ref={register} {...register(value)}
id={value} id={value}
defaultChecked={selecteds.includes(value)} defaultChecked={selecteds.includes(value)}
onClick={() => setChanged(true)} onClick={() => setChanged(true)}

View File

@@ -31,9 +31,8 @@ export const QuestionsSubjectFilter: FC<Props> = ({ register, setChanged }) => {
return ( return (
<div> <div>
<select <select
ref={register} {...register('subjectId')}
className="w-full rounded p-1 border-gray-400 border shadow-sm" className="w-full rounded p-1 border-gray-400 border shadow-sm"
name="subjectId"
defaultValue={where.subjectId ?? ""} defaultValue={where.subjectId ?? ""}
onClick={() => setChanged(true)} onClick={() => setChanged(true)}
> >

View File

@@ -1,6 +1,6 @@
import { ApolloQueryResult, gql, OperationVariables, useMutation } from "@apollo/client"; import { ApolloQueryResult, gql, OperationVariables, useMutation } from "@apollo/client";
import React, { FC, useState } from "react"; import React, { FC, useState } from "react";
import { useForm } from "react-hook-form"; import { FieldValues, SubmitHandler, useForm } from "react-hook-form";
import { Prompt, useHistory } from "react-router"; import { Prompt, useHistory } from "react-router";
import { Button, Card } from "../../../../components"; import { Button, Card } from "../../../../components";
import { useCurrentUser } from "../../../../contexts"; import { useCurrentUser } from "../../../../contexts";
@@ -52,8 +52,9 @@ export const ReviewMessageForm: FC<{
question: Question question: Question
refetch: (variables?: Partial<OperationVariables> | undefined) => Promise<ApolloQueryResult<Query>> refetch: (variables?: Partial<OperationVariables> | undefined) => Promise<ApolloQueryResult<Query>>
}> = ({ question, refetch }) => { }> = ({ question, refetch }) => {
const [isChangesSaved, setIsChangesSaved] = useState(true) const { register, handleSubmit, formState: {
const { register, handleSubmit } = useForm() isDirty
} } = useForm()
const history = useHistory(); const history = useHistory();
const { user } = useCurrentUser() const { user } = useCurrentUser()
@@ -62,26 +63,14 @@ export const ReviewMessageForm: FC<{
const hasFeebacks = !!question.reviewMessages.nodes.length const hasFeebacks = !!question.reviewMessages.nodes.length
const questionIsFromCurrentUser = user?.id === question.user.id const questionIsFromCurrentUser = user?.id === question.user.id
const handleTextChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => { const formSubmit: SubmitHandler<FieldValues> = async ({
if (e.target.value !== '') { feedbackType,
setIsChangesSaved(false) text
} else {
setIsChangesSaved(true)
}
}
const handleSubmitClick = () => {
setIsChangesSaved(true)
}
const formSubmit = async (inputs: {
feedbackType: ReviewMessageFeedbackType
text: string
}) => { }) => {
await createReviewMessage({ await createReviewMessage({
variables: { variables: {
text: inputs.text, text: text,
feedbackType: questionIsFromCurrentUser ? ReviewMessageFeedbackType.Answer : inputs.feedbackType, feedbackType: questionIsFromCurrentUser ? ReviewMessageFeedbackType.Answer : feedbackType,
questionId: NodeId.decode(question.id).id, questionId: NodeId.decode(question.id).id,
}, },
}); });
@@ -96,15 +85,14 @@ export const ReviewMessageForm: FC<{
return ( return (
<> <>
<Prompt <Prompt
when={!isChangesSaved} when={!isDirty}
message='O parecer ainda não foi enviado, deseja continuar?' message='O parecer ainda não foi enviado, deseja continuar?'
/> />
<Card title="Parecer" className="max-w-screen-md mx-auto"> <Card title="Parecer" className="max-w-screen-md mx-auto">
<form onSubmit={handleSubmit(formSubmit)}> <form onSubmit={handleSubmit(formSubmit)}>
<textarea <textarea
onChange={(e) => handleTextChange(e)}
className="w-full h-32 p-2 border-solid border-2 border-gray-700 rounded-md" className="w-full h-32 p-2 border-solid border-2 border-gray-700 rounded-md"
ref={register} {...register('text')}
name="text" name="text"
/> />
{!questionIsFromCurrentUser && REVIEW_FEEDBACK.map((item, index) => ( {!questionIsFromCurrentUser && REVIEW_FEEDBACK.map((item, index) => (
@@ -112,8 +100,7 @@ export const ReviewMessageForm: FC<{
<input <input
type="radio" type="radio"
id={item.value} id={item.value}
name="feedbackType" {...register("feedbackType", { required: true })}
ref={register({ required: true })}
value={item.value} value={item.value}
className="my-auto" className="my-auto"
defaultChecked={index === 0} defaultChecked={index === 0}
@@ -128,7 +115,7 @@ export const ReviewMessageForm: FC<{
</div> </div>
))} ))}
<div className="justify-end flex"> <div className="justify-end flex">
<Button type="primary" htmlType="submit" className="mt-4" onClick={handleSubmitClick}> <Button type="primary" htmlType="submit" className="mt-4">
{questionIsFromCurrentUser ? 'Responder Parecer' : 'Enviar Parecer'} {questionIsFromCurrentUser ? 'Responder Parecer' : 'Enviar Parecer'}
</Button> </Button>
</div> </div>

View File

@@ -3,7 +3,8 @@
"private": "true", "private": "true",
"dependencies": { "dependencies": {
"@apollo/client": "^3.6.9", "@apollo/client": "^3.6.9",
"@ckeditor/ckeditor5-react": "^5.0.2", "@ckeditor/ckeditor5-build-classic": "^21.0.0",
"@ckeditor/ckeditor5-react": "^2.1.0",
"@headlessui/react": "^1.6.6", "@headlessui/react": "^1.6.6",
"@heroicons/react": "^1.0.6", "@heroicons/react": "^1.0.6",
"@nivo/core": "^0.79.0", "@nivo/core": "^0.79.0",
@@ -17,7 +18,7 @@
"react": "^18.2.0", "react": "^18.2.0",
"react-avatar-edit": "^1.2.0", "react-avatar-edit": "^1.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-hook-form": "^6.2.0", "react-hook-form": "^7.33.1",
"react-icons": "^4.4.0", "react-icons": "^4.4.0",
"react-redux": "^8.0.2", "react-redux": "^8.0.2",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",

View File

@@ -136,12 +136,17 @@
"@babel/helper-validator-identifier" "^7.18.6" "@babel/helper-validator-identifier" "^7.18.6"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
"@ckeditor/ckeditor5-react@^5.0.2": "@ckeditor/ckeditor5-build-classic@^21.0.0":
version "5.0.2" version "21.0.0"
resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-react/-/ckeditor5-react-5.0.2.tgz#446518e1d7ce842c63fc6ac24e818cc78a753903" resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-build-classic/-/ckeditor5-build-classic-21.0.0.tgz#f34624fa28edbc4de917eee326db7de1f09c9c63"
integrity sha512-pN4acvCAIsuXaZDMttqy4dNBKXiJ6AS6P8NM3ggMc/rQkMIPp3YPhDWWf+pyQLUiewj1Bfr5EFeBfcXPQTOn+Q== integrity sha512-IYPXmc5Np7SzJVJbGNZk3OZEHnZ/WylbN1aFyfYdKMch9Be8mrCB9QQOqfsAEKD4SjXujYvn1jL0mM/EPZ8ECw==
"@ckeditor/ckeditor5-react@^2.1.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-react/-/ckeditor5-react-2.1.0.tgz#f612546a5a328899a436d71b72ffd632600049e8"
integrity sha512-rlHjRKhwP9tNK0Yj2UJShL14mRfxLPgJ+Pv6zTv/Mvmd4wrwGnJf+5ybOAGK92S02hP1cXH+9km+PRO1b4V+ng==
dependencies: dependencies:
prop-types "^15.7.2" prop-types "^15.6.1"
"@emotion/is-prop-valid@^1.1.0": "@emotion/is-prop-valid@^1.1.0":
version "1.1.3" version "1.1.3"
@@ -1700,7 +1705,7 @@ pretty-hrtime@^1.0.3:
resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1"
integrity sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A== integrity sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==
prop-types@^15.6.2, prop-types@^15.7.2: prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
version "15.8.1" version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -1741,10 +1746,10 @@ react-dom@^18.2.0:
loose-envify "^1.1.0" loose-envify "^1.1.0"
scheduler "^0.23.0" scheduler "^0.23.0"
react-hook-form@^6.2.0: react-hook-form@^7.33.1:
version "6.15.8" version "7.33.1"
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-6.15.8.tgz#725c139d308c431c4611e4b9d85a49f01cfc0e7a" resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.33.1.tgz#8c4410e3420788d3b804d62cc4c142915c2e46d0"
integrity sha512-prq82ofMbnRyj5wqDe8hsTRcdR25jQ+B8KtCS7BLCzjFHAwNuCjRwzPuP4eYLsEBjEIeYd6try+pdLdw0kPkpg== integrity sha512-ydTfTxEJdvgjCZBj5DDXRc58oTEfnFupEwwTAQ9FSKzykEJkX+3CiAkGtAMiZG7IPWHuzgT6AOBfogiKhUvKgg==
react-icons@^4.4.0: react-icons@^4.4.0:
version "4.4.0" version "4.4.0"