diff --git a/src/pages/auth/forgot-password/model/useResetPassword.ts b/src/pages/auth/forgot-password/model/useResetPassword.ts index 91c0388..b819e10 100644 --- a/src/pages/auth/forgot-password/model/useResetPassword.ts +++ b/src/pages/auth/forgot-password/model/useResetPassword.ts @@ -1,23 +1,18 @@ -import { type DefaultError, useMutation } from '@tanstack/react-query'; +import { type DefaultError, useMutation, UseMutationOptions } from '@tanstack/react-query'; import { AuthHttp, TAuth } from 'entities/auth'; -interface ResetPasswordProps { - onSuccess?: (body: TAuth.ResetPasswordBody, res: TAuth.ResetPasswordResponse) => void; - onError?: (err: Error) => void; -} +export type UseResetePasswordOptions = Omit< + UseMutationOptions, + 'mutationFn' +>; -export function useResetPassword({ onSuccess, onError }: ResetPasswordProps = {}) { +export function useResetPassword(options: UseResetePasswordOptions = {}) { return useMutation, DefaultError, TAuth.ResetPasswordBody>({ mutationKey: [], mutationFn: AuthHttp.resetPassword, meta: { skipGlobalValidationToast: true, }, - onError: (err) => { - onError?.(err); - }, - onSuccess: (res, body) => { - onSuccess?.(body, res); - }, + ...options, }); } diff --git a/src/pages/auth/forgot-password/model/useSendCode.ts b/src/pages/auth/forgot-password/model/useSendCode.ts index 39f5611..aa0d66b 100644 --- a/src/pages/auth/forgot-password/model/useSendCode.ts +++ b/src/pages/auth/forgot-password/model/useSendCode.ts @@ -1,7 +1,16 @@ -import { type DefaultError, useMutation } from '@tanstack/react-query'; +import { type DefaultError, useMutation, UseMutationOptions } from '@tanstack/react-query'; import { AuthHttp, TAuth } from 'entities/auth'; -export function useSendCode() { +export type UseSendCodeOptions = Omit< + UseMutationOptions< + TAuth.ResetPasswordVerifyResponse, + DefaultError, + TAuth.ResetPasswordVerifyBody + >, + 'mutationFn' +>; + +export function useSendCode(options: UseSendCodeOptions = {}) { return useMutation< Awaited, DefaultError, @@ -12,5 +21,6 @@ export function useSendCode() { meta: { skipGlobalValidationToast: true, }, + ...options, }); } diff --git a/src/pages/auth/forgot-password/model/useSendPassword.ts b/src/pages/auth/forgot-password/model/useSendPassword.ts index 07823b5..ee38928 100644 --- a/src/pages/auth/forgot-password/model/useSendPassword.ts +++ b/src/pages/auth/forgot-password/model/useSendPassword.ts @@ -1,15 +1,16 @@ -import { type DefaultError, useMutation } from '@tanstack/react-query'; +import { type DefaultError, useMutation, UseMutationOptions } from '@tanstack/react-query'; import { AuthHttp, TAuth } from 'entities/auth'; -interface SendPasswordProps { - onSuccess?: ( - body: TAuth.ResetPasswordConfirmBody, - res: TAuth.ResetPasswordConfirmResponse - ) => void; - onError?: (err: Error) => void; -} +export type UseSendPasswordOptions = Omit< + UseMutationOptions< + TAuth.ResetPasswordConfirmResponse, + DefaultError, + TAuth.ResetPasswordConfirmBody + >, + 'mutationFn' +>; -export function useSendPassword({ onSuccess, onError }: SendPasswordProps = {}) { +export function useSendPassword(options: UseSendPasswordOptions = {}) { return useMutation< Awaited, DefaultError, @@ -20,11 +21,6 @@ export function useSendPassword({ onSuccess, onError }: SendPasswordProps = {}) meta: { skipGlobalValidationToast: true, }, - onError: (err) => { - onError?.(err); - }, - onSuccess: (res, body) => { - onSuccess?.(body, res); - }, + ...options, }); } diff --git a/src/pages/auth/forgot-password/ui/EmailForm.tsx b/src/pages/auth/forgot-password/ui/EmailForm.tsx index 718c078..d266b10 100644 --- a/src/pages/auth/forgot-password/ui/EmailForm.tsx +++ b/src/pages/auth/forgot-password/ui/EmailForm.tsx @@ -18,16 +18,16 @@ import { Controller, useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import type { EmailFormValues } from '../model/types'; import { EmailForm as EmailFormSchema } from '../model/schemas'; -import { ComponentProps } from 'react'; -import { useResetPassword } from '../model/useResetPassword'; +import { UseResetePasswordOptions, useResetPassword } from '../model/useResetPassword'; import { setFormErrors } from 'shared/lib/utils'; import { extractValidationIssues } from 'shared/api'; +import { ComponentProps } from 'react'; -interface EmailFormProps extends Omit, 'children' | 'onSubmit'> { - onSuccess?: (body: TAuth.ResetPasswordBody, res: TAuth.ResetPasswordResponse) => void; -} +type EmailFormProps = Omit, 'children' | 'onSubmit'> & { + mutateOptions?: UseResetePasswordOptions; +}; -function EmailForm({ onSuccess, ...props }: EmailFormProps) { +function EmailForm({ mutateOptions = {}, ...props }: EmailFormProps) { const form = useForm({ resolver: zodResolver(EmailFormSchema), defaultValues: { @@ -36,8 +36,11 @@ function EmailForm({ onSuccess, ...props }: EmailFormProps) { }); const resetPassword = useResetPassword({ - onSuccess, - onError: (err) => setFormErrors(extractValidationIssues(err), form), + ...mutateOptions, + onError: (err, ...args) => { + mutateOptions.onError?.(err, ...args); + setFormErrors(extractValidationIssues(err), form); + }, }); const onSubmit = (data: EmailFormValues) => { diff --git a/src/pages/auth/forgot-password/ui/ForgotPasswordPage.tsx b/src/pages/auth/forgot-password/ui/ForgotPasswordPage.tsx index 69205f4..5aae267 100644 --- a/src/pages/auth/forgot-password/ui/ForgotPasswordPage.tsx +++ b/src/pages/auth/forgot-password/ui/ForgotPasswordPage.tsx @@ -47,7 +47,11 @@ function ForgotPasswordPage() { {step === 'email' ? ( - setDraft({ email, step: 'otp' }, DRAFT_TTL_MS)} /> + setDraft({ email, step: 'otp' }, DRAFT_TTL_MS), + }} + /> ) : null} {step === 'otp' && ( { - clearDraft(); - router.replace(routes.auth.signin()); - toast.success(res.message); + mutateOptions={{ + onSuccess: (res) => { + clearDraft(); + router.replace(routes.auth.signin()); + toast.success(res.message); + }, }} /> )} diff --git a/src/pages/auth/forgot-password/ui/PasswordForm.tsx b/src/pages/auth/forgot-password/ui/PasswordForm.tsx index 9767347..d248826 100644 --- a/src/pages/auth/forgot-password/ui/PasswordForm.tsx +++ b/src/pages/auth/forgot-password/ui/PasswordForm.tsx @@ -21,22 +21,22 @@ import { setFormErrors } from 'shared/lib/utils'; import { extractValidationIssues } from 'shared/api'; import { PasswordForm as PasswordFormSchema } from '../model/schemas'; import type { PasswordFormValues } from '../model/types'; -import { useSendPassword } from '../model/useSendPassword'; +import { useSendPassword, UseSendPasswordOptions } from '../model/useSendPassword'; interface PasswordFormProps extends Omit, 'children' | 'onSubmit'> { - onSuccess?: ( - body: TAuth.ResetPasswordConfirmBody, - res: TAuth.ResetPasswordConfirmResponse - ) => void; + mutateOptions?: UseSendPasswordOptions; email: string; } -function PasswordForm({ onSuccess, email, ...props }: PasswordFormProps) { +function PasswordForm({ mutateOptions = {}, email, ...props }: PasswordFormProps) { const [showPassword, setShowPassword] = useState(false); const sendPassword = useSendPassword({ - onSuccess, - onError: (err) => setFormErrors(extractValidationIssues(err), form), + ...mutateOptions, + onError: (err, ...args) => { + mutateOptions.onError?.(err, ...args); + setFormErrors(extractValidationIssues(err), form); + }, }); const form = useForm({ diff --git a/src/pages/auth/signin/model/useSignin.ts b/src/pages/auth/signin/model/useSignin.ts index 3d1046d..69ad33d 100644 --- a/src/pages/auth/signin/model/useSignin.ts +++ b/src/pages/auth/signin/model/useSignin.ts @@ -1,22 +1,17 @@ -import { type DefaultError, useMutation } from '@tanstack/react-query'; +import { type DefaultError, useMutation, UseMutationOptions } from '@tanstack/react-query'; import { AuthHttp, TAuth } from 'entities/auth'; -interface UseSigninProps { - onSuccess?: (body: TAuth.SigninBody, res: TAuth.SigninResponse) => void; - onError?: (err: Error) => void; -} +export type UseSigninOptions = Omit< + UseMutationOptions, + 'mutationFn' +>; -export function useSignin({ onSuccess, onError }: UseSigninProps = {}) { +export function useSignin(options: UseSigninOptions = {}) { return useMutation, DefaultError, TAuth.SigninBody>({ mutationFn: AuthHttp.signin, meta: { skipGlobalValidationToast: true, }, - onError: (err) => { - onError?.(err); - }, - onSuccess: (res, body) => { - onSuccess?.(body, res); - }, + ...options, }); } diff --git a/src/pages/auth/signin/ui/SigninForm.tsx b/src/pages/auth/signin/ui/SigninForm.tsx index c55e811..a004d37 100644 --- a/src/pages/auth/signin/ui/SigninForm.tsx +++ b/src/pages/auth/signin/ui/SigninForm.tsx @@ -25,13 +25,13 @@ import { routes } from 'shared/config'; import { extractValidationIssues } from 'shared/api'; import { TAuth } from 'entities/auth'; import { ComponentProps } from 'react'; -import { useSignin } from '../model/useSignin'; +import { useSignin, UseSigninOptions } from '../model/useSignin'; interface SigninFormProps extends Omit, 'children' | 'onSubmit'> { - onSuccess?: (body: TAuth.SigninBody, res: TAuth.SigninResponse) => void; + mutateOptions?: UseSigninOptions; } -export function SigninForm({ className, onSuccess, ...props }: SigninFormProps) { +export function SigninForm({ className, mutateOptions = {}, ...props }: SigninFormProps) { const form = useForm({ resolver: zodResolver(SigninFormSchema), defaultValues: { @@ -41,8 +41,9 @@ export function SigninForm({ className, onSuccess, ...props }: SigninFormProps) }); const sendUserData = useSignin({ - onSuccess, - onError: (err) => { + ...mutateOptions, + onError: (err, ...args) => { + mutateOptions.onError?.(err, ...args); setFormErrors(extractValidationIssues(err), form); }, }); diff --git a/src/pages/auth/signin/ui/SigninPage.tsx b/src/pages/auth/signin/ui/SigninPage.tsx index 81b8566..9490e3f 100644 --- a/src/pages/auth/signin/ui/SigninPage.tsx +++ b/src/pages/auth/signin/ui/SigninPage.tsx @@ -18,14 +18,16 @@ function SigninPage() { { - if (res.success) { - AccessToken.token = res.token; - router.replace(routes.profile.root()); - if (res.message) { - toast.success(res.message); + mutateOptions={{ + onSuccess: (res) => { + if (res.success) { + AccessToken.token = res.token; + router.replace(routes.profile.root()); + if (res.message) { + toast.success(res.message); + } } - } + }, }} /> diff --git a/src/pages/auth/signup/model/useSignup.ts b/src/pages/auth/signup/model/useSignup.ts index 37a68f5..6061d9d 100644 --- a/src/pages/auth/signup/model/useSignup.ts +++ b/src/pages/auth/signup/model/useSignup.ts @@ -1,22 +1,17 @@ -import { type DefaultError, useMutation } from '@tanstack/react-query'; +import { type DefaultError, useMutation, UseMutationOptions } from '@tanstack/react-query'; import { AuthHttp, TAuth } from 'entities/auth'; -interface UseSignupProps { - onSuccess?: (body: TAuth.SignupBody, res: TAuth.SignupResponse) => void; - onError?: (err: Error) => void; -} +export type UseSignupOptions = Omit< + UseMutationOptions, + 'mutationFn' +>; -export function useSignup({ onSuccess, onError }: UseSignupProps = {}) { +export function useSignup(options: UseSignupOptions = {}) { return useMutation, DefaultError, TAuth.SignupBody>({ mutationFn: AuthHttp.signup, meta: { skipGlobalValidationToast: true, }, - onError: (err) => { - onError?.(err); - }, - onSuccess: (res, body) => { - onSuccess?.(body, res); - }, + ...options, }); } diff --git a/src/pages/auth/signup/model/useSignupConfirm.ts b/src/pages/auth/signup/model/useSignupConfirm.ts index d2dc7b8..6ce7d74 100644 --- a/src/pages/auth/signup/model/useSignupConfirm.ts +++ b/src/pages/auth/signup/model/useSignupConfirm.ts @@ -1,11 +1,17 @@ -import { type DefaultError, useMutation } from '@tanstack/react-query'; +import { type DefaultError, useMutation, UseMutationOptions } from '@tanstack/react-query'; import { AuthHttp, TAuth } from 'entities/auth'; -export function useSignupConfirm() { +export type UseSignupConfirmOptions = Omit< + UseMutationOptions, + 'mutationFn' +>; + +export function useSignupConfirm(options: UseSignupConfirmOptions = {}) { return useMutation, DefaultError, TAuth.SignupConfirmBody>({ mutationFn: AuthHttp.signupConfirm, meta: { skipGlobalValidationToast: true, }, + ...options, }); } diff --git a/src/pages/auth/signup/ui/SignupForm.tsx b/src/pages/auth/signup/ui/SignupForm.tsx index 07542f2..01602db 100644 --- a/src/pages/auth/signup/ui/SignupForm.tsx +++ b/src/pages/auth/signup/ui/SignupForm.tsx @@ -29,13 +29,13 @@ import { fieldNameMapper } from '../model/utils/field-name-mapper'; import { prepareFullName } from '../model/utils/prepare-fullname'; import { extractValidationIssues } from 'shared/api'; import { TAuth } from 'entities/auth'; -import { useSignup } from '../model/useSignup'; +import { useSignup, UseSignupOptions } from '../model/useSignup'; interface SignupFormProps extends Omit, 'children' | 'onSubmit'> { - onSuccess?: (body: TAuth.SignupBody, res: TAuth.SignupResponse) => void; + mutateOptions?: UseSignupOptions; } -export function SignupForm({ className, onSuccess, ...props }: SignupFormProps) { +export function SignupForm({ className, mutateOptions = {}, ...props }: SignupFormProps) { const [showPassword, setShowPassword] = useState(false); const form = useForm({ @@ -49,8 +49,9 @@ export function SignupForm({ className, onSuccess, ...props }: SignupFormProps) }); const sendUserData = useSignup({ - onSuccess, - onError: (err) => { + ...mutateOptions, + onError: (err, ...args) => { + mutateOptions.onError?.(err, ...args); setFormErrors( extractValidationIssues(err), form, diff --git a/src/pages/auth/signup/ui/SignupPage.tsx b/src/pages/auth/signup/ui/SignupPage.tsx index 6bb9043..459a420 100644 --- a/src/pages/auth/signup/ui/SignupPage.tsx +++ b/src/pages/auth/signup/ui/SignupPage.tsx @@ -48,7 +48,11 @@ function SignupPage() { {step === 'signup' ? ( - setDraft({ email, step: 'otp' }, DRAFT_TTL_MS)} /> + setDraft({ email, step: 'otp' }, DRAFT_TTL_MS), + }} + /> ) : null} {step === 'otp' ? (